update to v_B39
one change caused significant fups: Bug 338118 - [compiler] CastExpression type should be changed to be a type reference and not an expression
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 430d8d8..96fd41a 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -24,8 +24,8 @@
  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.jdt.internal.compiler.codegen;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",
@@ -33,9 +33,9 @@
  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.compiler.tool,org.eclipse.jdt.apt.pluggable.core",
- org.eclipse.jdt.internal.core;x-friends:="org.eclipse.jdt.apt.pluggable.core",
- org.eclipse.jdt.internal.core.builder;x-friends:="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,
@@ -46,7 +46,7 @@
  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.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,
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 5afc77a..9eee7ac 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -305,10 +305,11 @@
 					}
 				}
 			}
-			int length = unitSource == null ? 0 : unitSource.length;
+			int length;
 			if ((startPosition > endPosition)
 				|| ((startPosition < 0) && (endPosition < 0))
-				|| length == 0)
+				|| (unitSource == null)
+				|| (length = unitSource.length) == 0)
 				return Messages.problem_noSourceInformation;
 
 			StringBuffer errorBuffer = new StringBuffer();
@@ -368,10 +369,11 @@
 					}
 				}
 			}
-			int length = unitSource== null ? 0 : unitSource.length;
+			int length;
 			if ((startPosition > endPosition)
 					|| ((startPosition < 0) && (endPosition < 0))
-					|| (length <= 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$
@@ -3030,8 +3032,10 @@
  * External API
  */
 protected ArrayList handleBootclasspath(ArrayList bootclasspaths, String customEncoding) {
- 	final int bootclasspathsSize = bootclasspaths == null ? 0 : bootclasspaths.size();
-	if (bootclasspathsSize != 0) {
+ 	final int bootclasspathsSize;
+	if ((bootclasspaths != null)
+		&& ((bootclasspathsSize = bootclasspaths.size()) != 0))
+	{
 		String[] paths = new String[bootclasspathsSize];
 		bootclasspaths.toArray(paths);
 		bootclasspaths.clear();
@@ -3056,8 +3060,10 @@
  * External API
  */
 protected ArrayList handleClasspath(ArrayList classpaths, String customEncoding) {
-	final int classpathsSize = classpaths == null ? 0 : classpaths.size();
-	if (classpathsSize != 0) {
+	final int classpathsSize;
+	if ((classpaths != null)
+		&& ((classpathsSize = classpaths.size()) != 0))
+	{
 		String[] paths = new String[classpathsSize];
 		classpaths.toArray(paths);
 		classpaths.clear();
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index c5b593a..81297f5 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -1,7 +1,7 @@
 #Format: compiler.name = word1 word2 word3
 compiler.name = Eclipse Compiler for Java(TM)
 #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.B38, 3.7.0 M6
+compiler.version = 0.B39, 3.7.0 M6
 compiler.copyright = Copyright IBM Corp 2000, 2010. All rights reserved.
 
 ###{ObjectTeams:
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index 57dbbfe..cf7c3ea 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -41,11 +41,41 @@
 	</td>
   </tr>
 </table>
+<a name="v_B39"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.7M6 - March 1, 2011 - 3.7.0 M6
+<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
+
 <a name="v_B38"></a>
 <hr><h1>
 Eclipse Platform Build Notes<br>
 Java development tools core</h1>
-Eclipse SDK 3.7M6 - February 22, 2011 - 3.7.0 M6
+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>
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 2660a01..72fb6cb 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -3574,7 +3574,7 @@
 				}
 			}
 		} else if(parent instanceof CastExpression) {
-			Expression e = ((CastExpression)parent).type;
+			TypeReference e = ((CastExpression)parent).type;
 			TypeBinding binding = e.resolvedType;
 			if(binding != null){
 				addExpectedType(binding, scope);
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index 522de9f..bd74371 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -13,12 +13,18 @@
  *******************************************************************************/
 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;
@@ -1272,7 +1278,7 @@
 			}
 			this.acceptedAnswer = true;
 		} else if (binding instanceof MethodBinding) {
-			MethodBinding methodBinding = (MethodBinding) binding;
+			MethodBinding methodBinding = getCorrectMethodBinding((MethodBinding) binding);
 			this.noProposal = false;
 
 			boolean isValuesOrValueOf = false;
@@ -1899,4 +1905,192 @@
 
 		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://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/javadoc.html#inheritingcomments">1.4.2</a>,
+	 * <a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments">1.5</a>, and
+	 * <a href="http://java.sun.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/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index 4a85801..4f44c45 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -841,7 +841,7 @@
 				Expression castType;
 				if(this.expressionPtr > 0
 					&& ((castType = this.expressionStack[this.expressionPtr-1]) instanceof TypeReference)) {
-					CastExpression cast = new CastExpression(expression, castType);
+					CastExpression cast = new CastExpression(expression, (TypeReference) castType);
 					cast.sourceStart = castType.sourceStart;
 					cast.sourceEnd= expression.sourceEnd;
 					this.assistNodeParent = cast;
@@ -2354,20 +2354,24 @@
 protected void consumeCastExpressionWithPrimitiveType() {
 	popElement(K_CAST_STATEMENT);
 
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	this.expressionPtr--;
 	this.expressionLengthPtr--;
-	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr+1], castType = this.expressionStack[this.expressionPtr]);
+	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, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	this.expressionPtr--;
 	this.expressionLengthPtr--;
-	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr + 1], castType = this.expressionStack[this.expressionPtr]);
+	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;
 }
@@ -2375,10 +2379,12 @@
 protected void consumeCastExpressionWithQualifiedGenericsArray() {
 	popElement(K_CAST_STATEMENT);
 
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	this.expressionPtr--;
 	this.expressionLengthPtr--;
-	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr + 1], castType = this.expressionStack[this.expressionPtr]);
+	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;
 }
@@ -2386,11 +2392,12 @@
 	// CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
 	popElement(K_CAST_STATEMENT);
 
-	Expression exp, cast, castType;
-
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	this.expressionPtr--;
 	this.expressionLengthPtr--;
-	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr+1], castType = this.expressionStack[this.expressionPtr]);
+	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;
 }
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
index 6847014..211bc1a 100644
--- 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -11,6 +11,7 @@
 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.*;
 
 /**
@@ -19,9 +20,13 @@
 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)
@@ -106,6 +111,13 @@
 				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);
+			}
 		}
 	}
 
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
index ed3f983..7c8fb62 100644
--- 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
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -25,12 +25,15 @@
 	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;
 	}
 
 	/*
@@ -186,6 +189,16 @@
 	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/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index 6d14848..9897c3b 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -158,7 +158,7 @@
 				Expression castType;
 				if(this.expressionPtr > 0
 					&& ((castType = this.expressionStack[this.expressionPtr-1]) instanceof TypeReference)) {
-					CastExpression cast = new CastExpression(expression, castType);
+					CastExpression cast = new CastExpression(expression, (TypeReference) castType);
 					cast.sourceStart = castType.sourceStart;
 					cast.sourceEnd= expression.sourceEnd;
 					parentNode = cast;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index 80eadf3..96ac685 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -532,6 +532,7 @@
 	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;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
index 94ca3f2..9dc7e97 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/Compiler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -408,6 +409,9 @@
 		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)
@@ -958,8 +962,18 @@
 				// build and record parsed units
 				this.parseThreshold = 0; // will request a full parse
 				beginToCompile(new ICompilationUnit[] { sourceUnit });
-				// process all units (some more could be injected in the loop by the lookup environment)
-				unit = this.unitsToProcess[0];
+				// 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*/);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
index 603cb2a..b2d1d20 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CastExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -69,7 +69,7 @@
 public class CastExpression extends Expression {
 
 	public Expression expression;
-	public Expression type;
+	public TypeReference type;
 	public TypeBinding expectedType; // when assignment conversion to a given expected type: String s = (String) t;
 
 //{ObjectTeams: the following flags are set depending on the kind parameter of the constructor
@@ -103,7 +103,7 @@
 	 * @param type
 	 * @param kind directs the kind of translation, see DO_WRAP, NEED_CLASS, RAW above.
 	 */
-	public CastExpression (Expression expression, Expression type, int kind)
+	public CastExpression (Expression expression, TypeReference type, int kind)
 	{
 		this(expression, type);
 		this.sourceStart = type.sourceStart;
@@ -133,7 +133,7 @@
 	}
 // SH}
 //expression.implicitConversion holds the cast for baseType casting
-public CastExpression(Expression expression, Expression type) {
+public CastExpression(Expression expression, TypeReference type) {
 	this.expression = expression;
 	this.type = type;
 	type.bits |= ASTNode.IgnoreRawTypeCheck; // no need to worry about raw type usage
@@ -576,112 +576,103 @@
 	this.constant = Constant.NotAConstant;
 	this.implicitConversion = TypeIds.T_undefined;
 
-	if ((this.type instanceof TypeReference) || (this.type instanceof NameReference)
-			&& ((this.type.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) == 0) { // no extra parenthesis around type: ((A))exp
-
-		boolean exprContainCast = false;
+	boolean exprContainCast = false;
 
 //{ObjectTeams: after resolving allow for a few conversions
 /* orig:
-		TypeBinding castType = this.resolvedType = this.type.resolveType(scope);
+	TypeBinding castType = this.resolvedType = this.type.resolveType(scope);
   :giro */
-		this.resolvedType = this.type.resolveType(scope);
+	this.resolvedType = this.type.resolveType(scope);
 
-		// wrap role types, if client required this:
-		if (this.wrapRoleType) {
-			// only try to wrap valid roles except for marker interfaces:
-			if (   this.resolvedType != null
-			    && this.resolvedType.leafComponentType().isRole()
-			    && !TSuperHelper.isMarkerInterface(this.resolvedType))
+	// wrap role types, if client required this:
+	if (this.wrapRoleType) {
+		// only try to wrap valid roles except for marker interfaces:
+		if (   this.resolvedType != null
+		    && this.resolvedType.leafComponentType().isRole()
+		    && !TSuperHelper.isMarkerInterface(this.resolvedType))
+		{
+			this.type.resolvedType =
+				this.resolvedType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(scope, this.resolvedType, this);
+			// check success:
+			if (   this.resolvedType == null
+				|| !RoleTypeBinding.isRoleType(this.resolvedType.leafComponentType()))
 			{
-				this.type.resolvedType =
-					this.resolvedType = RoleTypeCreator.maybeWrapUnqualifiedRoleType(scope, this.resolvedType, this);
-				// check success:
-				if (   this.resolvedType == null
-					|| !RoleTypeBinding.isRoleType(this.resolvedType.leafComponentType()))
-				{
-					// Although it is a role, wrapping failed. Error is already reported (hopefully).
-					assert scope.referenceCompilationUnit().compilationResult().hasErrors();
-					return null;
-				}
+				// Although it is a role, wrapping failed. Error is already reported (hopefully).
+				assert scope.referenceCompilationUnit().compilationResult().hasErrors();
+				return null;
 			}
 		}
-		else if (   this.requireRoleClass
-				 && this.resolvedType != null)
-		{
-			// for role field access we need the class part:
-			ReferenceBinding refType = (ReferenceBinding)this.resolvedType.leafComponentType();
-			assert(refType.isRole());
-			TypeBinding classPart = refType.roleModel.getClassPartBinding();
-			assert(classPart != null);
-			if (this.resolvedType.isArrayType())
-				classPart = new ArrayBinding(classPart, this.resolvedType.dimensions(), scope.environment());
-			this.resolvedType = classPart;
-			this.type.resolvedType = classPart;
-		}
+	}
+	else if (   this.requireRoleClass
+			 && this.resolvedType != null)
+	{
+		// for role field access we need the class part:
+		ReferenceBinding refType = (ReferenceBinding)this.resolvedType.leafComponentType();
+		assert(refType.isRole());
+		TypeBinding classPart = refType.roleModel.getClassPartBinding();
+		assert(classPart != null);
+		if (this.resolvedType.isArrayType())
+			classPart = new ArrayBinding(classPart, this.resolvedType.dimensions(), scope.environment());
+		this.resolvedType = classPart;
+		this.type.resolvedType = classPart;
+	}
 /*orig*/TypeBinding castType = this.resolvedType;
 // SH}
-		//expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation
-		if (this.expression instanceof CastExpression) {
-			this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
-			exprContainCast = true;
-		}
-		TypeBinding expressionType = this.expression.resolveType(scope);
-//{ObjectTeams: de-wrap tthis-expressiontType if this statement was generated:
-		if (expressionType instanceof WeakenedTypeBinding)
-			expressionType = ((WeakenedTypeBinding)expressionType).weakenedType; // pessimistic
-		else if (shouldUnwrapExpressionType(expressionType))
-			expressionType = ((ReferenceBinding)expressionType).getRealType();
-		if (this.isGenerated) {
-			// use stronger anchor if statement was generated:
-			if (   RoleTypeBinding.isRoleWithoutExplicitAnchor(castType)
-				&& RoleTypeBinding.isRoleWithExplicitAnchor(expressionType)
-				&& ((ReferenceBinding)castType).getRealType() == ((ReferenceBinding)expressionType).getRealType())
-			{
-				this.resolvedType = castType = expressionType;
-			}
-		}
-// SH}
-		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
-//{ObjectTeams: getAllRoles requires an unchecked cast (T[]), don't report:
-					  if (!scope.isGeneratedScope())
-// SH}
-						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;
-	} else { // expression as a cast
-		TypeBinding expressionType = this.expression.resolveType(scope);
-		if (expressionType == null) return null;
-		scope.problemReporter().invalidTypeReference(this.type);
-		return null;
+	//expression.setExpectedType(this.resolvedType); // needed in case of generic method invocation
+	if (this.expression instanceof CastExpression) {
+		this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
+		exprContainCast = true;
 	}
+	TypeBinding expressionType = this.expression.resolveType(scope);
+//{ObjectTeams: de-wrap tthis-expressiontType if this statement was generated:
+	if (expressionType instanceof WeakenedTypeBinding)
+		expressionType = ((WeakenedTypeBinding)expressionType).weakenedType; // pessimistic
+	else if (shouldUnwrapExpressionType(expressionType))
+		expressionType = ((ReferenceBinding)expressionType).getRealType();
+	if (this.isGenerated) {
+		// use stronger anchor if statement was generated:
+		if (   RoleTypeBinding.isRoleWithoutExplicitAnchor(castType)
+			&& RoleTypeBinding.isRoleWithExplicitAnchor(expressionType)
+			&& ((ReferenceBinding)castType).getRealType() == ((ReferenceBinding)expressionType).getRealType())
+		{
+			this.resolvedType = castType = expressionType;
+		}
+	}
+// SH}
+	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
+//{ObjectTeams: getAllRoles requires an unchecked cast (T[]), don't report:
+				  if (!scope.isGeneratedScope())
+// SH}
+					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;
 }
 //{ObjectTeams:	avoid comparing wrapped expression type with non-wrapped resolvedType when appropriate.
 private boolean shouldUnwrapExpressionType(TypeBinding expressionType) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index 636ce84..d01c4c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -425,21 +425,25 @@
   :giro */
 	syntheticArgs = nestedType.syntheticEnclosingInstances();
 //SH}
-	for (int i = 0, max = syntheticArgs == null ? 0 : 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 */);
+	if (syntheticArgs != null) {
+		for (int i = 0, max = syntheticArgs == null ? 0 : 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();
-	for (int i = 0, max = syntheticArgs == null ? 0 : 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 */);
+	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 */);
+			}
 		}
 	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index b9aced0..51d7a75 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -891,6 +891,35 @@
 						}
 					}
 				}
+				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
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index 8a8089e..cc83060 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -7,6 +7,7 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Stephan Herrmann - contribution for bug 337868 - [compiler][model] incomplete support for package-info.java when using SearchableEnvironment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -27,6 +28,7 @@
 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;
@@ -209,7 +211,13 @@
 		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
-		this.typeRequestor.accept(answer.getCompilationUnit(), answer.getAccessRestriction());
+		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());
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index 6de1514..7fd1f08 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -569,6 +569,10 @@
 							if (this.reportProblems) {
 								recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
 							}
+							if (this.inlineTagStarted) {
+								// parse a 'valid' inheritDoc tag
+								parseInheritDocTag();
+							}
 							break;
 						default:
 							valid = false;
@@ -709,6 +713,10 @@
 		return valid;
 	}
 
+	protected void parseInheritDocTag() {
+		// do nothing
+	}
+
 	/*
 	 * Parse @param tag declaration and flag missing description if corresponding option is enabled
 	 */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index ecb7fc7..fdbb165 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -2799,12 +2799,13 @@
 
 	//optimize push/pop
 
-	Expression cast,exp;
+	Expression cast;
+	Expression exp;
 	this.expressionPtr--;
 	this.expressionStack[this.expressionPtr] =
 		cast = new CastExpression(
 			exp=this.expressionStack[this.expressionPtr+1] ,
-			this.expressionStack[this.expressionPtr]);
+			(TypeReference) this.expressionStack[this.expressionPtr]);
 	this.expressionLengthPtr -- ;
 	updateSourcePosition(cast);
 	cast.sourceEnd=exp.sourceEnd;
@@ -2812,7 +2813,9 @@
 protected void consumeCastExpressionWithGenericsArray() {
 	// CastExpression ::= PushLPAREN Name TypeArguments Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
 
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	int end = this.intStack[this.intPtr--];
 
 	int dim = this.intStack[this.intPtr--];
@@ -2827,7 +2830,9 @@
 protected void consumeCastExpressionWithNameArray() {
 	// CastExpression ::= PushLPAREN Name Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
 
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	int end = this.intStack[this.intPtr--];
 
 	// handle type arguments
@@ -2846,7 +2851,9 @@
 
 	//optimize the push/pop
 
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	int end = this.intStack[this.intPtr--];
 	this.expressionStack[this.expressionPtr] = cast = new CastExpression(exp = this.expressionStack[this.expressionPtr], castType = getTypeReference(this.intStack[this.intPtr--]));
 	castType.sourceEnd = end - 1;
@@ -2855,7 +2862,9 @@
 }
 protected void consumeCastExpressionWithQualifiedGenericsArray() {
 	// CastExpression ::= PushLPAREN Name OnlyTypeArguments '.' ClassOrInterfaceType Dims PushRPAREN InsideCastExpression UnaryExpressionNotPlusMinus
-	Expression exp, cast, castType;
+	Expression exp;
+	Expression cast;
+	TypeReference castType;
 	int end = this.intStack[this.intPtr--];
 
 	int dim = this.intStack[this.intPtr--];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 720cf73..5d3b75f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -9,7 +9,9 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Benjamin Muskalla - Contribution for bug 239066
- *     Stephan Herrmann  - Contribution for bug 236385
+ *     Stephan Herrmann  - Contributions for 
+ *     						bug 236385 - [compiler] Warn for potential programming problem if an object is created but not used
+ *     						bug 338303 - Warning about Redundant assignment conflicts with definite assignment
  *     Fraunhofer FIRST - extended API and implementation
  *     Technical University Berlin - extended API and implementation
  *******************************************************************************/
@@ -4384,14 +4386,6 @@
 			expression.sourceStart,
 			expression.sourceEnd);
 }
-public void invalidTypeReference(Expression expression) {
-	this.handle(
-		IProblem.InvalidTypeExpression,
-		NoArgument,
-		NoArgument,
-		expression.sourceStart,
-		expression.sourceEnd);
-}
 public void invalidTypeToSynchronize(Expression expression, TypeBinding type) {
 	this.handle(
 		IProblem.InvalidTypeToSynchronized,
@@ -5574,6 +5568,8 @@
 }
 
 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)  };
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 02be83b..aecb4ef 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -184,7 +184,7 @@
 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
+#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 ++/--
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/CallinMappingDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/CallinMappingDeclaration.java
index d420404..389952e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/CallinMappingDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/CallinMappingDeclaration.java
@@ -733,15 +733,7 @@
 
 		// the reverse of a cast expression is implicit widening, thus allow these
 		if (currentExpression instanceof CastExpression) {
-			CastExpression castExpression = (CastExpression)currentExpression;
-			if (castExpression.type instanceof SingleNameReference) {
-				// special case: SingleNameReference does not support base-import scope,
-				// replace with SingleTypeReference:
-				SingleNameReference type = (SingleNameReference)castExpression.type;
-				AstGenerator gen = new AstGenerator(type.sourceStart, type.sourceEnd);
-				castExpression.type = gen.baseTypeReference(type.token);
-			}
-			currentExpression = (castExpression).expression;
+			currentExpression = ((CastExpression)currentExpression).expression;
 		}
 
 		if (currentExpression instanceof SingleNameReference) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
index 030fba5..d24aeb9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/lifting/Lifting.java
@@ -446,7 +446,7 @@
 			// here an (unnecessary) cast to j.l.Object prevents a warning re OTJLD 2.2(f):
 			roleExpression = gen.castExpression(
 								roleExpression, 
-								gen.qualifiedNameReference(TypeConstants.JAVA_LANG_OBJECT), 
+								gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT), 
 								CastExpression.RAW);
 		}
 		statements[1] =
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/BaseScopeMarker.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/BaseScopeMarker.java
index 9c6e88a..4ee7106 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/BaseScopeMarker.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/BaseScopeMarker.java
@@ -21,14 +21,12 @@
 package org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer;
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
-import org.eclipse.jdt.internal.compiler.ast.CastExpression;
 import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
 import org.eclipse.jdt.internal.compiler.ast.Expression.DecapsulationState;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
 
 /**
  * This visitor marks all relevant nodes as allowing baseclass decapsulation.
@@ -56,16 +54,4 @@
 	public void endVisit(QualifiedTypeReference typeReference, BlockScope scope) {
 		typeReference.setBaseclassDecapsulation(DecapsulationState.REPORTED);
 	}
-	@Override
-	public void endVisit(CastExpression castExpression, BlockScope scope) {
-		// cast may contain name reference? Should we mark the cast itself?
-		// (cf. MethodMappingImplementor.getMappedArgument())
-		if (castExpression.type instanceof SingleNameReference) {
-			// special case: SingleNameReference does not support base-import scope,
-			// replace with SingleTypeReference:
-			SingleNameReference type = (SingleNameReference)castExpression.type;
-			AstGenerator gen = new AstGenerator(type.sourceStart, type.sourceEnd);
-			castExpression.type = gen.baseTypeReference(type.token);
-		}
-	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
index 41d02d7..8c8cdfb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/statemachine/transformer/ReflectionGenerator.java
@@ -691,7 +691,7 @@
 		if (gen.sourceLevel >= ClassFileConstants.JDK1_5)
 			messageSendGet= gen.castExpression(
 								messageSendGet,
-								gen.singleNameReference(T),
+								gen.singleTypeReference(T),
 								CastExpression.RAW
 							);
 		return gen.ifStatement(
@@ -720,7 +720,7 @@
 					new EqualExpression(
 						gen.castExpression(
 							gen.singleNameReference(CLASS_ARG),
-							gen.qualifiedNameReference(TypeConstants.JAVA_LANG_OBJECT), CastExpression.RAW
+							gen.qualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT), CastExpression.RAW
 						),
 						gen.castExpression(
 							gen.classLiteralAccess(gen.singleTypeReference(roleType)),
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
index bd15084..8b0bd85 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/util/AstGenerator.java
@@ -184,7 +184,7 @@
 		return result;
 	}
 
-	public Expression baseTypeReference(ReferenceBinding type) {
+	public TypeReference baseTypeReference(ReferenceBinding type) {
 		TypeReference result = typeReference(type);
 		result.setBaseclassDecapsulation(DecapsulationState.REPORTED);
 		return result;
@@ -798,7 +798,7 @@
 		return call;
 	}
 
-	public CastExpression castExpression(Expression expression, Expression type, int kind)
+	public CastExpression castExpression(Expression expression, TypeReference type, int kind)
 	{
         CastExpression cast = new CastExpression(
                 expression,
@@ -823,13 +823,13 @@
 	{
 	    if (expr instanceof ThisReference)
 	        return null; // never useful to cast 'this'!
-	    Expression typeExpr = typeReference(type);
-	    typeExpr.sourceStart = this.sourceStart;
-	    typeExpr.sourceEnd   = this.sourceEnd;
-	    typeExpr.resolvedType = type;
+	    TypeReference typeRef = typeReference(type);
+	    typeRef.sourceStart = this.sourceStart;
+	    typeRef.sourceEnd   = this.sourceEnd;
+	    typeRef.resolvedType = type;
 
-	    CastExpression cast = new CastExpression(expr, typeExpr, kind);
-		typeExpr.resolvedType =
+	    CastExpression cast = new CastExpression(expr, typeRef, kind);
+		typeRef.resolvedType =
 		    cast.resolvedType = type;
 	    cast.constant = Constant.NotAConstant;
 	    cast.tagAsNeedCheckCast();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 86aea8d..612da9f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -1371,13 +1371,9 @@
 	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);
-		org.eclipse.jdt.internal.compiler.ast.Expression type = expression.type;
+		TypeReference type = expression.type;
 		trimWhiteSpacesAndComments(type);
-		if (type instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference ) {
-			castExpression.setType(convertType((org.eclipse.jdt.internal.compiler.ast.TypeReference)type));
-		} else if (type instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
-			castExpression.setType(convertToType((org.eclipse.jdt.internal.compiler.ast.NameReference)type));
-		}
+		castExpression.setType(convertType(type));
 		castExpression.setExpression(convert(expression.expression));
 		if (this.resolveBindings) {
 			recordNodes(castExpression, expression);
@@ -3300,17 +3296,6 @@
 		return parenthesizedExpression;
 	}
 
-	public Type convertToType(org.eclipse.jdt.internal.compiler.ast.NameReference reference) {
-		Name name = convert(reference);
-		final SimpleType type = new SimpleType(this.ast);
-		type.setName(name);
-		type.setSourceRange(name.getStartPosition(), name.getLength());
-		if (this.resolveBindings) {
-			this.recordNodes(type, reference);
-		}
-		return type;
-	}
-
 	protected VariableDeclarationExpression convertToVariableDeclarationExpression(org.eclipse.jdt.internal.compiler.ast.LocalDeclaration localDeclaration) {
 		final VariableDeclarationFragment variableDeclarationFragment = convertToVariableDeclarationFragment(localDeclaration);
 		final VariableDeclarationExpression variableDeclarationExpression = new VariableDeclarationExpression(this.ast);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index 336c3ed..83f8de3 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -1721,11 +1721,8 @@
 						return null;
 					}
 					ArrayType arrayType = (ArrayType) type;
-					if (typeBinding.isArrayType()) {
-						ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
-						return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
-					}
-					return getTypeBinding(this.scope.createArrayType(binding, arrayType.getDimensions()));
+					ArrayBinding arrayBinding = (ArrayBinding) typeBinding;
+					return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
 				}
 				if (typeBinding.isArrayType()) {
 					typeBinding = ((ArrayBinding) typeBinding).leafComponentType;
@@ -1765,11 +1762,8 @@
 					if (this.scope == null) {
 						return null;
 					}
-					if (binding.isArrayType()) {
-						ArrayBinding arrayBinding = (ArrayBinding) binding;
-						return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
-					}
-					return getTypeBinding(this.scope.createArrayType(binding, arrayType.getDimensions()));
+					ArrayBinding arrayBinding = (ArrayBinding) binding;
+					return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, arrayType.getDimensions()));
 				} else if (binding.isArrayType()) {
 					ArrayBinding arrayBinding = (ArrayBinding) binding;
 					return getTypeBinding(arrayBinding.leafComponentType);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
index 8bd5665..1ae3ff1 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IJavaProject.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -63,6 +63,22 @@
 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.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 7a78164..ae3da8c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -114,7 +114,7 @@
 	/**
 	 * Name of file containing project classpath
 	 */
-	public static final String CLASSPATH_FILENAME = ".classpath";  //$NON-NLS-1$
+	public static final String CLASSPATH_FILENAME = IJavaProject.CLASSPATH_FILE_NAME;
 
 	/**
 	 * Value of the project's raw classpath if the .classpath file contains invalid entries.
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index cb1e11c..59c69ce 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * 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;
 
@@ -31,6 +32,7 @@
 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;
@@ -1194,7 +1196,13 @@
 						return true; // don't continue with compilation unit
 					}
 				} else if (object instanceof IType[]) {
-					if (object == NO_TYPES) return true; // all types where deleted -> type is hidden
+					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())
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
index d98325e..913f3e7 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  *
  * 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;
 
@@ -22,6 +23,7 @@
 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;
@@ -134,8 +136,13 @@
 							sourceTypes[index++] = otherType;
 					}
 					return new NameEnvironmentAnswer(sourceTypes, answer.restriction);
-				} catch (JavaModelException npe) {
-					// fall back to using owner
+				} 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
 				}
 			}
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
index ebdbef0..191af72 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -37,6 +37,7 @@
 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;
@@ -912,6 +913,31 @@
 	}
 	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.
  */
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
index 64642a1..241cc0b 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java
@@ -3677,4 +3677,42 @@
 			}
 		}
 	}
+	/**
+	 * 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/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
index 13c1e97..3557dbb 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -263,45 +263,35 @@
 	super.consumeCastExpressionLL1();
 	if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
 		CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
-		if (castExpression.type instanceof TypeReference) {
-			this.patternLocator.match((TypeReference) castExpression.type, this.nodeSet);
-        }
+		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];
-		if (castExpression.type instanceof Reference) {
-			this.patternLocator.match((Reference) castExpression.type, this.nodeSet);
-        }
+		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];
-		if (castExpression.type instanceof Reference) {
-			this.patternLocator.match((Reference) castExpression.type, this.nodeSet);
-        }
+		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];
-		if (castExpression.type instanceof Reference) {
-			this.patternLocator.match((Reference) castExpression.type, this.nodeSet);
-        }
+		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];
-		if (castExpression.type instanceof Reference) {
-			this.patternLocator.match((Reference) castExpression.type, this.nodeSet);
-        }
+		this.patternLocator.match(castExpression.type, this.nodeSet);
 	}
 }