update jdt.core to 4.9 M3
diff --git a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
index 9faaa09..4ed2992 100644
--- a/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
+++ b/org.eclipse.jdt.core/antadapter/org/eclipse/jdt/core/JDTCompilerAdapter.java
@@ -522,7 +522,7 @@
 			niceSourceList.append("s"); //$NON-NLS-1$
 		}
 		niceSourceList.append(" to be compiled:"); //$NON-NLS-1$
-		niceSourceList.append(lSep);
+		niceSourceList.append(System.lineSeparator());
 
 		String[] encodedFiles = null, encodedDirs = null;
 		int encodedFilesLength = 0, encodedDirsLength = 0;
@@ -574,7 +574,7 @@
 				}
 			}
 			cmd.createArgument().setValue(arg);
-			niceSourceList.append("    " + arg + lSep); //$NON-NLS-1$
+			niceSourceList.append("    " + arg + System.lineSeparator()); //$NON-NLS-1$
 		}
 
 		this.attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
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 f865261..2ce5f7d 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
@@ -669,7 +669,7 @@
 					printErr(this.main.bind(
 								severity,
 								Integer.toString(globalErrorCount),
-								new String(fileName)));
+								fileName));
 					final String errorReportSource = errorReportSource(problem, null, 0);
 					this.printlnErr(errorReportSource);
 					this.printlnErr(problem.getMessage());
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 872b4d9..ef0ba27 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
@@ -2549,7 +2549,7 @@
 					// no need for field initialization
 					this.problemReporter,
 					compilationResult);
-				if (compilationUnit.types != null)
+				if (compilationUnit != null && compilationUnit.types != null)
 					typeDeclaration = compilationUnit.types[0];
 			} else {
 				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
index bb1c6b2..e5ae655 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -293,6 +293,8 @@
 	 */
 	private void initLevelTags() {
 		int level = ((int)(this.complianceLevel >>> 16)) - ClassFileConstants.MAJOR_VERSION_1_1 + 1;
+		if ( level >= BLOCK_TAGS_LENGTH)
+			return; // To support future JDKs
 		// Init block tags
 		this.levelTags[BLOCK_IDX] = new char[BLOCK_ALL_TAGS_LENGTH][];
 		this.levelTagsLength[BLOCK_IDX] = 0;
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 3e1ebbe..c323c8f 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
@@ -208,7 +208,8 @@
 	private boolean inReferenceExpression;
 	private IProgressMonitor monitor;
 	private int resumeOnSyntaxError = 0;
-
+	private boolean consumedEnhancedFor;
+	
 public CompletionParser(ProblemReporter problemReporter, boolean storeExtraSourceEnds) {
 	super(problemReporter);
 	this.reportSyntaxErrorIsRequired = false;
@@ -1923,6 +1924,7 @@
 	}
 	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.
@@ -2925,6 +2927,13 @@
 	}
 }
 @Override
+protected void consumeEnhancedForStatementHeader(){
+	this.consumedEnhancedFor = true;
+	super.consumeEnhancedForStatementHeader();
+
+}
+
+@Override
 protected void consumeEnhancedForStatementHeaderInit(boolean hasModifiers) {
 	super.consumeEnhancedForStatementHeaderInit(hasModifiers);
 	this.hasUnusedModifiers = false;
@@ -4176,6 +4185,8 @@
 	int previous = this.previousToken;
 	int prevIdentifierPtr = this.previousIdentifierPtr;
 
+	isInsideEnhancedForLoopWithoutBlock(token);
+	
 	if (isInsideMethod() || isInsideFieldInitialization() || isInsideAnnotation() || isInsideEnumConstantnitialization()) {
 		switch(token) {
 			case TokenNameLPAREN:
@@ -4761,6 +4772,13 @@
 		}
 	}
 }
+private void isInsideEnhancedForLoopWithoutBlock(int token) {
+	if( this.consumedEnhancedFor == true && token != TokenNameLBRACE) {
+		consumeOpenFakeBlock();
+	}
+	this.consumedEnhancedFor = false;
+	
+}
 @Override
 protected void consumeInvocationExpression() { // on error, a message send's error reductions will take the expression path rather than the statement path since that is a dead end.
 	super.consumeInvocationExpression();
@@ -6249,6 +6267,24 @@
 }
 // SH}
 
+@Override
+protected int actFromTokenOrSynthetic(int previousAct) {
+	int newAct = tAction(previousAct, this.currentToken);
+	if (this.hasError && !this.diet && newAct == ERROR_ACTION && this.currentToken == TerminalTokens.TokenNameEOF) {
+		if (requireExtendedRecovery()) {
+			// during extended recovery, if EOF would be wrong, try a few things to reduce our stacks:
+			for (int tok : RECOVERY_TOKENS) {
+				newAct = tAction(previousAct, tok);
+				if (newAct != ERROR_ACTION) {
+					this.currentToken = tok; // this worked, pretend we really got this from the Scanner
+					return newAct;
+				}
+			}
+		}
+	}
+	return newAct;
+}
+
 protected boolean isInImportStatement() {
 	return foundToken(K_INSIDE_IMPORT_STATEMENT);
 }
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
index 62b5668..f9d0212 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -911,12 +911,31 @@
 	/* might be completing at very end of file (e.g. behind a dot) */
 	if (this.completionIdentifier == null &&
 		this.startPosition == this.cursorLocation + 1){
+		this.endOfEmptyToken = this.currentPosition - 1;
 		this.currentPosition = this.startPosition; // for being detected as empty free identifier
 		return TokenNameIdentifier;
 	}
 	return TokenNameEOF;
 }
 @Override
+protected int getNextNotFakedToken() throws InvalidInputException {
+	int token;
+	boolean fromUnget = false;
+	if (this.nextToken != TokenNameNotAToken) {
+		token = this.nextToken;
+		this.nextToken = TokenNameNotAToken;
+		fromUnget = true;
+	} else {
+		token = getNextToken();
+	}
+	if (this.currentPosition == this.startPosition) {
+		if (!fromUnget)
+			this.currentPosition++; // on fake completion identifier
+		return -1;
+	}
+	return token;
+}
+@Override
 public final void getNextUnicodeChar() throws InvalidInputException {
 	int temp = this.currentPosition; // the \ is already read
 	super.getNextUnicodeChar();
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index e06f7c4..d5364e0 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -124,7 +124,7 @@
 	protected boolean isFirst = false;
 
 	public AssistParser snapShot;
-	private static final int[] RECOVERY_TOKENS = new int [] { TokenNameSEMICOLON, TokenNameRPAREN,};
+	protected static final int[] RECOVERY_TOKENS = { TokenNameSEMICOLON, TokenNameRPAREN, TokenNameRBRACE, TokenNameRBRACKET};
 
 
 public AssistParser(ProblemReporter problemReporter) {
@@ -2433,9 +2433,12 @@
 			
 	// If triggered fake EOF at completion site, see if the real next token would have passed muster.
 	if (this.currentToken == TokenNameEOF) {
-		if (this.scanner.eofPosition < this.scanner.source.length) {
+		int extendedEnd = this.scanner.source.length;
+		if (this.referenceContext instanceof AbstractMethodDeclaration)
+			extendedEnd = ((AbstractMethodDeclaration) this.referenceContext).bodyEnd; // no use parsing beyond the method's body end
+		if (this.scanner.eofPosition < extendedEnd) {
 			shouldStackAssistNode();
-			this.scanner.eofPosition = this.scanner.source.length;
+			this.scanner.eofPosition = extendedEnd;
 			nextToken = getNextToken();
 			if (automatonWillShift(nextToken, automatonState)) {
 				this.currentToken = nextToken;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 8058ab0..e7779ab 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
 import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 import org.eclipse.jdt.internal.compiler.parser.NLSTag;
@@ -647,6 +648,15 @@
 	}
 	this.stringLiterals[this.stringLiteralsPtr++] = literal;
 }
+private boolean isLambdaExpressionCopyContext(ReferenceContext context) {
+	if (context instanceof LambdaExpression && context != ((LambdaExpression) context).original())
+		return true; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
+	Scope cScope = context instanceof AbstractMethodDeclaration ? ((AbstractMethodDeclaration) context).scope :
+		context instanceof TypeDeclaration ? ((TypeDeclaration) context).scope : 
+		context instanceof LambdaExpression ? ((LambdaExpression) context).scope :
+			null;
+	return cScope != null ? isLambdaExpressionCopyContext(cScope.parent.referenceContext()) : false;
+}
 
 //{ObjectTeams: decapsulation warning needs to check before entering warning
 /**
@@ -679,7 +689,7 @@
 // SH}
 
 public void recordSuppressWarnings(IrritantSet irritants, Annotation annotation, int scopeStart, int scopeEnd, ReferenceContext context) {
-	if (context instanceof LambdaExpression && context != ((LambdaExpression) context).original())
+	if (isLambdaExpressionCopyContext(context))
 		return; // Do not record from copies. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=441929
 		
 	if (this.suppressWarningIrritants == null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
index f28efc6..ae97673 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LabeledStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -67,8 +67,8 @@
 			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());
+				((UnconditionalFlowInfo)mergedInfo).addNullInfoFrom(flowInfo.unconditionalFieldLessCopy()).
+					addNullInfoFrom(labelContext.initsOnBreak.unconditionalFieldLessCopy());
 			}
 			this.mergedInitStateIndex =
 				currentScope.methodScope().recordInitializationStates(mergedInfo);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithTypeAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithTypeAnnotation.java
index 80addcf..b10aad2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithTypeAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/FieldInfoWithTypeAnnotation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013 GoPivotal, Inc. All Rights Reserved.
+ * Copyright (c) 2013 GoPivotal, 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
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithTypeAnnotations.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithTypeAnnotations.java
index 0903ed5..84570ba 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithTypeAnnotations.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithTypeAnnotations.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 GoPivotal, Inc. All Rights Reserved.
+ * Copyright (c) 2016 GoPivotal, 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
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationInfo.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationInfo.java
index 2684e5a..eba4d5a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationInfo.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/TypeAnnotationInfo.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016 GoPivotal, Inc. All Rights Reserved.
+ * Copyright (c) 2016 GoPivotal, 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
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryTypeAnnotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryTypeAnnotation.java
index b5050a8..dd37c77 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryTypeAnnotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryTypeAnnotation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013 GoPivotal, Inc. All Rights Reserved.
+ * Copyright (c) 2013 GoPivotal, 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
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index e064675..0f3d420 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -2338,7 +2338,7 @@
 										if (TypeBinding.equalsEquals(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 (foundField == null || foundField.problemId() == ProblemReasons.NotVisible) {
 												if (depth > 0){
 													invocationSite.setDepth(depth);
 													invocationSite.setActualReceiverType(receiverType);
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 172ff41..4c1acd3 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
@@ -872,6 +872,10 @@
         return term_action[term_check[base_action[state]+sym] == (char)sym ? base_action[state] + sym : base_action[state]];
 // SH}
 	}
+	/** Overridable hook, to allow CompletionParser to synthesize a few trailing tokens at (faked) EOF. */
+	protected int actFromTokenOrSynthetic(int previousAct) {
+		return tAction(previousAct, this.currentToken);
+	}
 	protected int astLengthPtr;
 
 	protected int[] astLengthStack;
@@ -14192,12 +14196,7 @@
 	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;
-			}
-
+			this.nextIgnoredToken = this.scanner.getNextNotFakedToken();
 		} catch(InvalidInputException e){
 			pos = this.scanner.currentPosition;
 		} finally {
@@ -14436,7 +14435,7 @@
 				stackLength);
 		}
 		this.stack[this.stateStackTop] = act;
-		this.unstackedAct = act = tAction(act, this.currentToken);
+		this.unstackedAct = act = actFromTokenOrSynthetic(act);
 		if (act == ERROR_ACTION || this.restartRecovery) {
 			if (DEBUG_AUTOMATON) {
 				if (this.restartRecovery) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index d968584..bebc560 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -404,7 +404,7 @@
 		newEntry6 = 0;
 	public boolean insideRecovery = false;
 	int lookBack[] = new int[2]; // fall back to spring forward.
-	int nextToken = TokenNameNotAToken; // allows for one token push back, only the most recent token can be reliably ungotten.
+	protected int nextToken = TokenNameNotAToken; // allows for one token push back, only the most recent token can be reliably ungotten.
 	private VanguardScanner vanguardScanner;
 	private VanguardParser vanguardParser;
 	ConflictedParser activeParser = null;
@@ -5894,4 +5894,9 @@
 		}
 	}
 }
+
+/** Overridable hook, to allow CompletionScanner to hide a faked identifier token. */
+protected int getNextNotFakedToken() throws InvalidInputException {
+	return getNextToken();
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
index 5c0b861..d6007e3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/DefaultProblemFactory.java
@@ -199,8 +199,7 @@
 		}
 	}
 
-	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=120410
-	return new String(output.toString());
+	return output.toString();
 }
 /**
  * @param problem CategorizedProblem
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index a25e028..485c76e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -110,8 +110,7 @@
 	 * @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());
+		return this.result.toString();
 	}
 
 	/**
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
index fbc32ef..e9d2722 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java
@@ -554,7 +554,7 @@
 		if (superclassName == null) {
 			return null;
 		}
-		return new String(Signature.createTypeSignature(ClassFile.translatedName(superclassName), true));
+		return Signature.createTypeSignature(ClassFile.translatedName(superclassName), true);
 	}
 }
 
@@ -650,7 +650,7 @@
 		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));
+			strings[i]= Signature.createTypeSignature(names[i], true);
 		}
 		return strings;
 	}
@@ -1053,7 +1053,7 @@
 				typeName.insert(0, '.');
 			}
 		}
-		typeQualifiedName = new String(typeName.toString());
+		typeQualifiedName = typeName.toString();
 	} else {
 		typeQualifiedName = getElementName();
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
index 2194d57..dc02a21 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ImportContainer.java
@@ -63,9 +63,9 @@
 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));
+	if (isOnDemand) {
+		importName = importName.substring(0, index);
+	}
 	return getImport(importName, isOnDemand);
 }
 protected IImportDeclaration getImport(String importName, boolean isOnDemand) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 1fc724c..a425e6c 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -270,6 +270,7 @@
 	public static final int BATCH_INITIALIZATION_IN_PROGRESS = 2;
 	public static final int BATCH_INITIALIZATION_FINISHED = 3;
 	public int batchContainerInitializations = NO_BATCH_INITIALIZATION;
+	public Object batchContainerInitializationsLock = new Object();
 
 	public BatchInitializationMonitor batchContainerInitializationsProgress = new BatchInitializationMonitor();
 	public Hashtable<String, ClasspathContainerInitializer> containerInitializersCache = new Hashtable<>(5);
@@ -676,6 +677,15 @@
 		return container;
 	}
 
+	synchronized boolean containerIsSet(IJavaProject project, IPath containerPath) {
+		Map<IPath, IClasspathContainer> projectContainers = this.containers.get(project);
+		if (projectContainers == null){
+			return false;
+		}
+		IClasspathContainer container = projectContainers.get(containerPath);
+		return container != null;
+	}
+
 	public synchronized IClasspathContainer containerGetDefaultToPreviousSession(IJavaProject project, IPath containerPath) {
 		Map<IPath, IClasspathContainer> projectContainers = this.containers.get(project);
 		if (projectContainers == null)
@@ -934,7 +944,7 @@
 		);
 	}
 
-	private void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
+	void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
 		Map<IJavaProject, Set<IPath>> initializations = this.containerInitializationInProgress.get();
 		if (initializations == null)
 			return;
@@ -3082,10 +3092,24 @@
 								pathSet.toArray(paths); // clone as the following will have a side effect
 								for (int j = 0; j < length2; j++) {
 									IPath path = paths[j];
+									synchronized(JavaModelManager.this.batchContainerInitializationsLock) {
+										if (containerIsSet(javaProject, path)) {
+											// another thread has concurrently initialized the container.
+											continue;
+										}
+									}
 									initializeContainer(javaProject, path);
 									IClasspathContainer container = containerBeingInitializedGet(javaProject, path);
 									if (container != null) {
-										containerPut(javaProject, path, container);
+										synchronized(JavaModelManager.this.batchContainerInitializationsLock) {
+											if (containerIsSet(javaProject, path)) {
+												// another thread has concurrently initialized the container.
+												containerBeingInitializedRemove(javaProject, path);
+												containerRemoveInitializationInProgress(javaProject, path);
+											} else {
+												containerPut(javaProject, path, container);
+											}
+										}
 									}
 								}
 								if (monitor != null)
@@ -3374,8 +3398,7 @@
 	}
 
 	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));
+		return (String) this.stringSymbols.add(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
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
index 9e2e538..634f88d 100644
--- 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
@@ -447,7 +447,7 @@
 					buffer.insert(0, '.');
 				}
 			}
-			typeQualifiedName = new String(buffer.toString());
+			typeQualifiedName = buffer.toString();
 		} else {
 			typeQualifiedName = this.type.getElementName();
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
index d51dcc9..ba6b037 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java
@@ -600,7 +600,7 @@
 	if (superclassName == null) {
 		return null;
 	}
-	return new String(Signature.createTypeSignature(superclassName, false));
+	return Signature.createTypeSignature(superclassName, false);
 }
 
 /**
@@ -626,7 +626,7 @@
 	}
 	String[] strings= new String[names.length];
 	for (int i= 0; i < names.length; i++) {
-		strings[i]= new String(Signature.createTypeSignature(names[i], false));
+		strings[i]= Signature.createTypeSignature(names[i], false);
 	}
 	return strings;
 }
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index 39c1ee1..a0b66c4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -110,7 +110,19 @@
 	ZipFile file = null;
 	try {
 		file = new ZipFile(this.zipFilename);
-		ClassFileReader classfile = ClassFileReader.read(file, IModule.MODULE_INFO_CLASS); // FIXME: use jar cache
+		String releasePath = "META-INF/versions/" + this.compliance + '/' + IModule.MODULE_INFO_CLASS; //$NON-NLS-1$
+		System.out.println("Reading for module from: " + this.zipFilename); //$NON-NLS-1$
+		ClassFileReader classfile = null;
+		try {
+			classfile = ClassFileReader.read(file, releasePath);
+			System.out.println("Read classfile : " + classfile); //$NON-NLS-1$
+		} catch (Exception e) {
+			e.printStackTrace();
+			// move on to the default
+		}
+		if (classfile == null) {
+			classfile = ClassFileReader.read(file, IModule.MODULE_INFO_CLASS); // FIXME: use jar cache
+		}
 		if (classfile != null) {
 			mod = classfile.getModuleDeclaration();
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
index b3de9db..5bd9a58 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
@@ -924,7 +924,7 @@
 					// 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;
+					if (containsLocalType && parsedUnit != null) parsedUnit.bits |= ASTNode.HasAllMethodBodies;
 				} else {
 					// create parsed unit from file
 					IFile file = (IFile) cu.getResource();
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 f74ad50..065ff52 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
@@ -3400,7 +3400,7 @@
 		}
 		int length = args.length;
 		for(int i = startingIndex;	i< length ; i++){
-			args[i] = new String(paramTypeSignatures[i-startingIndex]);
+			args[i] = paramTypeSignatures[i-startingIndex];
 		}
 		method = type.getMethod(new String(selector), args);
 		
diff --git a/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd b/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd
index 11d9c55..a740d37 100644
--- a/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd
+++ b/org.eclipse.jdt.core/schema/annotationProcessorManager.exsd
@@ -113,10 +113,13 @@
       </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
+
+This program and the accompanying materials
+are made available under the terms of the Eclipse Public License 2.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;
+&lt;a href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/
+
+SPDX-License-Identifier: EPL-2.0
       </documentation>
    </annotation>
 
diff --git a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
index 5d282b5..7971e58 100644
--- a/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathContainerInitializer.exsd
@@ -114,10 +114,13 @@
       </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 program and the accompanying materials are made 
+available under the terms of the Eclipse Public License 2.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;
+href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/
+
+SPDX-License-Identifier: EPL-2.0
       </documentation>
    </annotation>
 
diff --git a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
index eb0b558..4982955 100644
--- a/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
+++ b/org.eclipse.jdt.core/schema/classpathVariableInitializer.exsd
@@ -131,10 +131,13 @@
       </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 program and the accompanying materials are made 
+available under the terms of the Eclipse Public License 2.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;
+href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/
+
+SPDX-License-Identifier: EPL-2.0
       </documentation>
    </annotation>
 
diff --git a/org.eclipse.jdt.core/schema/codeFormatter.exsd b/org.eclipse.jdt.core/schema/codeFormatter.exsd
index 09defb2..c718c46 100644
--- a/org.eclipse.jdt.core/schema/codeFormatter.exsd
+++ b/org.eclipse.jdt.core/schema/codeFormatter.exsd
@@ -90,10 +90,13 @@
       </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 program and the accompanying materials are made 

+available under the terms of the Eclipse Public License 2.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;

+href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/

+

+SPDX-License-Identifier: EPL-2.0

       </documentation>

    </annotation>

 

diff --git a/org.eclipse.jdt.core/schema/compilationParticipant.exsd b/org.eclipse.jdt.core/schema/compilationParticipant.exsd
index b786852..043b946 100644
--- a/org.eclipse.jdt.core/schema/compilationParticipant.exsd
+++ b/org.eclipse.jdt.core/schema/compilationParticipant.exsd
@@ -182,10 +182,13 @@
       </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
+
+This program and the accompanying materials
+are made available under the terms of the Eclipse Public License 2.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;
+&lt;a href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/
+
+SPDX-License-Identifier: EPL-2.0
       </documentation>
    </annotation>
 
diff --git a/org.eclipse.jdt.core/schema/javaFormatter.exsd b/org.eclipse.jdt.core/schema/javaFormatter.exsd
index a10d89b..6954708 100644
--- a/org.eclipse.jdt.core/schema/javaFormatter.exsd
+++ b/org.eclipse.jdt.core/schema/javaFormatter.exsd
@@ -115,10 +115,13 @@
       </appInfo>
       <documentation>
          Copyright (c) 2014 Google 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
+
+This program and the accompanying materials
+are made available under the terms of the Eclipse Public License 2.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;
+&lt;a href=&quot;https://www.eclipse.org/legal/epl-2.0&quot;&gt;https://www.eclipse.org/legal/epl-v20.html&lt;/a&gt;/
+
+SPDX-License-Identifier: EPL-2.0
       </documentation>
    </annotation>
 
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
index 96991ee..4f168d1 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/indexer/Indexer.java
@@ -564,7 +564,7 @@
 				NdType nextDeletion = toDelete.getType(numChildren - 1);
 				if (DEBUG_INSERTIONS) {
 					Package.logInfo("Deleting " + nextDeletion.getTypeId().getFieldDescriptor().getString() + " from "  //$NON-NLS-1$//$NON-NLS-2$
-							+ new String(toDelete.getLocation().getString()) + " " + toDelete.address); //$NON-NLS-1$
+							+ toDelete.getLocation().getString() + " " + toDelete.address); //$NON-NLS-1$
 				}
 				nextDeletion.delete();
 			} finally {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ManifestIndexer.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ManifestIndexer.java
index d9cf564..07a34e4 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ManifestIndexer.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/ManifestIndexer.java
@@ -15,7 +15,7 @@
 	public void indexDocument() {
 		byte[] entry = this.document.getByteContents();
 		String text = new String(entry, Charset.defaultCharset());
-		String[] kv = new String(text).split(":"); //$NON-NLS-1$
+		String[] kv = text.split(":"); //$NON-NLS-1$
 		if (kv != null && kv.length > 1 && kv[0] != null && kv[1] != null) {
 			if (kv[0].equals(AUTOMATIC_MODULE_NAME)) {
 				addModuleDeclaration(kv[1].toCharArray());
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 67deb1d..64f26ed 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -467,8 +467,10 @@
 				this.lookupEnvironment.problemReporter,
 				result);
 //{ObjectTeams: Unchanged, but note, that this is controlled by Dependencies:
-		this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
-		this.lookupEnvironment.completeTypeBindings(unit, true);
+		if(unit != null) {
+			this.lookupEnvironment.buildTypeBindings(unit, accessRestriction);
+			this.lookupEnvironment.completeTypeBindings(unit, true);
+		}
 // SH}
 	}
 }
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
index ca12631..413581a 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/PossibleMatch.java
@@ -86,7 +86,7 @@
 				}
 			}
 		} else if (this.autoModuleName != null) { // fab a module
-			contents = new String("module " + this.autoModuleName + "{}").toCharArray();  //$NON-NLS-1$//$NON-NLS-2$
+			contents = ("module " + this.autoModuleName + "{}").toCharArray();  //$NON-NLS-1$//$NON-NLS-2$
 			this.sourceFileName = "module-info.java"; //$NON-NLS-1$
 			this.compoundName = new char[][] { "module-info".toCharArray()}; //$NON-NLS-1$
 		} else {