Merge remote-tracking branch 'origin/master' into BETA_JAVA_12
diff --git a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
index 8a8c16a..138e475 100644
--- a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug.tests; singleton:=true
-Bundle-Version: 3.11.300.qualifier
+Bundle-Version: 3.11.400.qualifier
 Bundle-ClassPath: javadebugtests.jar
 Bundle-Activator: org.eclipse.jdt.debug.testplugin.JavaTestPlugin
 Bundle-Vendor: %providerName
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInAnonymousLocalClass.java b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInAnonymousLocalClass.java
new file mode 100644
index 0000000..08b6a64
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInAnonymousLocalClass.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+import java.util.function.Consumer;
+
+public class Bug404097BreakpointInAnonymousLocalClass {
+
+	public static void breakpointMethod(final String methodParameter) {
+		// StringBuilder to make sure the compiler doesn't optimize "methodVariable" out of the compiled code.
+		final StringBuilder methodVariable = new StringBuilder("methodVariable");
+		Consumer<String> r = new Consumer<String>() {
+			public void accept(String lambdaParameter) {
+				String lambdaVariable = "lambdaVariable";
+				System.out.println("method parameter: " + methodParameter);
+				System.out.println("method variable: " + methodVariable);
+				System.out.println("lambda parameter: " + lambdaParameter);
+				System.out.println("lambda variable: " + lambdaVariable);
+			}
+		};
+		r.accept("lambdaParameter");
+	}
+
+	public static void main(String[] args) {
+		breakpointMethod("methodParameter");
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLambda.java b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLambda.java
new file mode 100644
index 0000000..158f975
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLambda.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+import java.util.function.Consumer;
+
+public class Bug404097BreakpointInLambda {
+
+	public static void breakpointMethod(final String methodParameter) {
+		// StringBuilder to make sure the compiler doesn't optimize "methodVariable" out of the compiled code.
+		final StringBuilder methodVariable = new StringBuilder("methodVariable");
+		Consumer<String> r = lambdaParameter -> {
+			String lambdaVariable = "lambdaVariable";
+			System.out.println("method parameter: " + methodParameter);
+			System.out.println("method variable: " + methodVariable);
+			System.out.println("lambda parameter: " + lambdaParameter);
+			System.out.println("lambda variable: " + lambdaVariable);
+		};
+		r.accept("lambdaParameter");
+	}
+
+	public static void main(String[] args) {
+		breakpointMethod("methodParameter");
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLocalClass.java b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLocalClass.java
new file mode 100644
index 0000000..029692c
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointInLocalClass.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+import java.util.function.Consumer;
+
+public class Bug404097BreakpointInLocalClass {
+
+	public static void breakpointMethod(final String methodParameter) {
+		// StringBuilder to make sure the compiler doesn't optimize "methodVariable" out of the compiled code.
+		final StringBuilder methodVariable = new StringBuilder("methodVariable");
+		class SomeConsumer implements Consumer<String> {
+			public void accept(String lambdaParameter) {
+				String lambdaVariable = "lambdaVariable";
+				System.out.println("method parameter: " + methodParameter);
+				System.out.println("method variable: " + methodVariable);
+				System.out.println("lambda parameter: " + lambdaParameter);
+				System.out.println("lambda variable: " + lambdaVariable);
+			}
+		};
+		Consumer<String> r = new SomeConsumer();
+		r.accept("lambdaParameter");
+	}
+
+	public static void main(String[] args) {
+		breakpointMethod("methodParameter");
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingInnerClass.java b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingInnerClass.java
new file mode 100644
index 0000000..224a73c
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingInnerClass.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+public class Bug404097BreakpointUsingInnerClass {
+
+	static class InnerClass {
+		int i;
+	}
+
+	public static void breakpointMethod() {
+		InnerClass object = new InnerClass();
+		object.i = 0;
+		System.out.println(object.i);
+	}
+
+	public static void main(String[] args) {
+		breakpointMethod();
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingLocalClass.java b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingLocalClass.java
new file mode 100644
index 0000000..10b84b6
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug404097BreakpointUsingLocalClass.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+public class Bug404097BreakpointUsingLocalClass {
+
+	public static void breakpointMethod() {
+		class LocalClass {
+			int i;
+		}
+		LocalClass object = new LocalClass();
+		object.i = 0;
+		System.out.println(object.i);
+	}
+
+	public static void main(String[] args) {
+		breakpointMethod();
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/ClosureVariableTest_Bug542989.java b/org.eclipse.jdt.debug.tests/java8/ClosureVariableTest_Bug542989.java
new file mode 100644
index 0000000..5a24fae
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/ClosureVariableTest_Bug542989.java
@@ -0,0 +1,22 @@
+/*******************************************************************************

+ * Copyright (c) 2019 IBM Corporation and others.

+ *

+ * 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

+ * https://www.eclipse.org/legal/epl-2.0/

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ * Contributors:

+ *     Paul Pazderski - initial API and implementation

+ *******************************************************************************/

+public class ClosureVariableTest_Bug542989 {

+	public static void main(String[] args) {

+		java.io.PrintStream out = System.out;

+		java.util.function.Consumer<String> printer = (msg) -> {

+			out.println(msg); //set breakpoint here

+		};

+		printer.accept("Hallo World!");

+	}

+}

diff --git a/org.eclipse.jdt.debug.tests/pom.xml b/org.eclipse.jdt.debug.tests/pom.xml
index 47c0287..88b3780 100644
--- a/org.eclipse.jdt.debug.tests/pom.xml
+++ b/org.eclipse.jdt.debug.tests/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.debug.tests</artifactId>
-  <version>3.11.300-SNAPSHOT</version>
+  <version>3.11.400-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
   <properties>
     <code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
diff --git a/org.eclipse.jdt.debug.tests/testprograms/Bug540243.java b/org.eclipse.jdt.debug.tests/testprograms/Bug540243.java
new file mode 100644
index 0000000..ed31664
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testprograms/Bug540243.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+
+public class Bug540243 {
+
+	public static void main(String[] args) throws InterruptedException {
+		Thread t = new Thread(new Runnable() {
+			// method must be synchronized, so that the thread owns a monitor
+			public synchronized void run() {
+				breakpointMethod();
+			}
+		});
+		t.start();
+		t.join();
+	}
+
+	public static void breakpointMethod() {
+		System.out.println("set a breakpoint here");
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index 2eed4e0..874c9a3 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -193,7 +193,7 @@
 	public static final String CLONE_SUFFIX = "Clone";
 
 	final String[] LAUNCH_CONFIG_NAMES_1_4 = {"LargeSourceFile", "LotsOfFields", "Breakpoints", "InstanceVariablesTests", "LocalVariablesTests", "LocalVariableTests2", "StaticVariablesTests",
- "DropTests", "ThrowsNPE", "ThrowsException", "org.eclipse.debug.tests.targets.Watchpoint",
+			"DropTests", "ThrowsNPE", "ThrowsException", "org.eclipse.debug.tests.targets.Watchpoint",
 			"org.eclipse.debug.tests.targets.BreakpointsLocationBug344984", "org.eclipse.debug.tests.targets.CallLoop", "A",
 			"HitCountLooper", "CompileError", "MultiThreadedLoop", "HitCountException", "MultiThreadedException", "MultiThreadedList", "MethodLoop", "StepFilterOne",
 			"StepFilterFour", "EvalArrayTests", "EvalSimpleTests", "EvalTypeTests", "EvalNestedTypeTests", "EvalTypeHierarchyTests",
@@ -207,7 +207,7 @@
 			"org.eclipse.debug.tests.targets.HcrClass5", "org.eclipse.debug.tests.targets.HcrClass6", "org.eclipse.debug.tests.targets.HcrClass7", "org.eclipse.debug.tests.targets.HcrClass8",
 			"org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1",
 			"StepResult2", "StepResult3", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException",
-			"Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303" };
+			"Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243" };
 
 	/**
 	 * the default timeout
@@ -470,6 +470,12 @@
 				cfgs.add(createLaunchConfiguration(jp, "EvalIntfSuperDefault"));
 				cfgs.add(createLaunchConfiguration(jp, "DebugHoverTest18"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug541110"));
+				cfgs.add(createLaunchConfiguration(jp, "ClosureVariableTest_Bug542989"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLocalClass"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInAnonymousLocalClass"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointInLambda"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingInnerClass"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug404097BreakpointUsingLocalClass"));
 	    		loaded18 = true;
 	    		waitForBuild();
 	        }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
index 7ef5057..1828248 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java
@@ -23,6 +23,7 @@
 import org.eclipse.jdt.debug.tests.breakpoints.BreakpointListenerTests;
 import org.eclipse.jdt.debug.tests.breakpoints.BreakpointLocationVerificationTests;
 import org.eclipse.jdt.debug.tests.breakpoints.BreakpointWorkingSetTests;
+import org.eclipse.jdt.debug.tests.breakpoints.ConditionalBreakpointsInJava8Tests;
 import org.eclipse.jdt.debug.tests.breakpoints.ConditionalBreakpointsTests;
 import org.eclipse.jdt.debug.tests.breakpoints.ConditionalBreakpointsWithGenerics;
 import org.eclipse.jdt.debug.tests.breakpoints.DeferredBreakpointTests;
@@ -131,6 +132,7 @@
 import org.eclipse.jdt.debug.tests.ui.OpenFromClipboardTests;
 import org.eclipse.jdt.debug.tests.ui.ViewManagementTests;
 import org.eclipse.jdt.debug.tests.ui.presentation.ModelPresentationTests;
+import org.eclipse.jdt.debug.tests.ui.presentation.ModelPresentationTests18;
 import org.eclipse.jdt.debug.tests.variables.DetailFormatterTests;
 import org.eclipse.jdt.debug.tests.variables.TestAnonymousInspect;
 import org.eclipse.jdt.debug.tests.variables.TestInstanceRetrieval;
@@ -347,6 +349,8 @@
 
 		if (JavaProjectHelper.isJava8Compatible()) {
 			addTest(new TestSuite(TestToggleBreakpointsTarget8.class));
+			addTest(new TestSuite(ModelPresentationTests18.class));
+			addTest(new TestSuite(ConditionalBreakpointsInJava8Tests.class));
 		}
 		if (JavaProjectHelper.isJava5Compatible()) {
 			addTest(new TestSuite(MethodBreakpointTests15.class));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsInJava8Tests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsInJava8Tests.java
new file mode 100644
index 0000000..2f967cf
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsInJava8Tests.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * 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
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.breakpoints;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.debug.tests.TestUtil;
+
+/**
+ * Tests conditional breakpoints.
+ */
+public class ConditionalBreakpointsInJava8Tests extends AbstractDebugTest {
+
+	public ConditionalBreakpointsInJava8Tests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected IJavaProject getProjectContext() {
+		return get18Project();
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		assertNoErrorMarkersExist();
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		terminateAndRemoveJavaLaunches();
+		removeAllBreakpoints();
+		super.tearDown();
+	}
+
+	/**
+	 * Test for Bug 541110 - ClassCastException in Instruction.popValue and a zombie EventDispatcher$1 job afterwards
+	 *
+	 * We check that a specific conditional breakpoint on a line with a lambda expression does not cause a {@link ClassCastException}.
+	 */
+	public void testBug541110() throws Exception {
+		String typeName = "Bug541110";
+		String breakpointCondition = "map.get(key) != null";
+		int breakpointLineNumber = 22;
+
+		// The class cast exception causes a job which runs forever. So we will timeout when waiting for debug events, if the exception occurs.
+		assertNoBreakpointHit(typeName, breakpointLineNumber, breakpointCondition);
+	}
+
+	/**
+	 * Test for Bug 541110 - Cannot display or set conditional breakpoint using local class reference or field
+	 *
+	 * We check that a conditional breakpoint inside a locally defined anonymous class can access visbile variables.
+	 */
+	public void testBug404097BreakpointInAnonymousLocalClass() throws Exception {
+		String typeName = "Bug404097BreakpointInAnonymousLocalClass";
+		int breakpointLineNumber = 25;
+		doTestVariableVisibility(typeName, breakpointLineNumber);
+	}
+
+	/**
+	 * Test for Bug 541110 - Cannot display or set conditional breakpoint using local class reference or field
+	 *
+	 * We check that a conditional breakpoint inside a lambda can access visible variables.
+	 */
+	public void testBug404097BreakpointInLambda() throws Exception {
+		String typeName = "Bug404097BreakpointInLambda";
+		int breakpointLineNumber = 24;
+		doTestVariableVisibility(typeName, breakpointLineNumber);
+	}
+
+	/**
+	 * Test for Bug 541110 - Cannot display or set conditional breakpoint using local class reference or field
+	 *
+	 * We check that a conditional breakpoint inside a locally defined class can access visible variables.
+	 */
+	public void testBug404097BreakpointInLocalClass() throws Exception {
+		String typeName = "Bug404097BreakpointInLocalClass";
+		int breakpointLineNumber = 25;
+		doTestVariableVisibility(typeName, breakpointLineNumber);
+	}
+
+	/**
+	 * Test for Bug 541110 - Cannot display or set conditional breakpoint using local class reference or field
+	 *
+	 * We check that a conditional breakpoint can access members of a static inner class.
+	 */
+	public void testBug404097BreakpointUsingInnerClass() throws Exception {
+		String typeName = "Bug404097BreakpointUsingInnerClass";
+		int breakpointLineNumber = 24;
+		doTestClassMemberVisibility(typeName, breakpointLineNumber);
+	}
+
+	/**
+	 * Test for Bug 541110 - Cannot display or set conditional breakpoint using local class reference or field
+	 *
+	 * We check that a conditional breakpoint can access members of a class which is defined locally.
+	 *
+	 * TODO: disabled until a fix is available
+	 */
+	public void disabled_testBug404097BreakpointUsingLocalClass() throws Exception {
+		String typeName = "Bug404097BreakpointUsingLocalClass";
+		int breakpointLineNumber = 23;
+		doTestClassMemberVisibility(typeName, breakpointLineNumber);
+	}
+
+	private void doTestVariableVisibility(String typeName, int breakpointLineNumber) throws Exception {
+		/*
+		 * We create a condition which does not evaluate to true and expect to not hit the breakpoint.
+		 * If condition evaluation runs into a compile error, either the breakpoint becomes unconditional and is therefore always hit.
+		 */
+		String breakpointCondition = String.join(" || ", Arrays.asList(
+				"!\"methodParameter\".equals(methodParameter)",
+				"methodVariable == null", "!\"methodVariable\".equals(methodVariable.toString())",
+				"!\"lambdaParameter\".equals(lambdaParameter)",
+				"!\"lambdaVariable\".equals(lambdaVariable)"));
+		assertNoBreakpointHit(typeName, breakpointLineNumber, breakpointCondition);
+	}
+
+	private void doTestClassMemberVisibility(String typeName, int breakpointLineNumber) throws Exception {
+		/*
+		 * We create a condition which does not evaluate to true and expect to not hit the breakpoint. If condition evaluation runs into a compile
+		 * error, the breakpoint becomes unconditional and is therefore always hit.
+		 */
+		String breakpointCondition = "object.i != 0";
+		assertNoBreakpointHit(typeName, breakpointLineNumber, breakpointCondition);
+	}
+
+	private void assertNoBreakpointHit(String typeName, int breakpointLineNumber, String breakpointCondition) throws Exception {
+		boolean suspendOnTrue = true;
+		createConditionalLineBreakpoint(breakpointLineNumber, typeName, breakpointCondition, suspendOnTrue);
+		ILaunchConfiguration config = getLaunchConfiguration(typeName);
+		DebugEventWaiter waiter = new DebugTargetTerminateWaiter();
+		launchAndWait(config, waiter);
+		TestUtil.waitForJobs(getName(), 1_000, 30_000, ProcessConsole.class);
+
+	}
+
+	private void terminateAndRemoveJavaLaunches() {
+		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
+		List<ILaunch> launches = Arrays.asList(launchManager.getLaunches());
+		for (ILaunch launch : launches) {
+			IDebugTarget debugTarget = launch.getDebugTarget();
+			if (debugTarget instanceof IJavaDebugTarget) {
+				terminateAndRemove((IJavaDebugTarget) debugTarget);
+			}
+		}
+	}
+
+	private static class DebugTargetTerminateWaiter extends DebugEventWaiter {
+
+		public DebugTargetTerminateWaiter() {
+			super(DebugEvent.TERMINATE);
+		}
+
+		@Override
+		public boolean accept(DebugEvent event) {
+			if (super.accept(event)) {
+				Object source = event.getSource();
+				return source instanceof IDebugTarget;
+			}
+			return false;
+		}
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsTests.java
deleted file mode 100644
index 6d9f336..0000000
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsTests.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2018 Simeon Andreev and others.
- *
- * 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
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Simeon Andreev - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.debug.tests.breakpoints;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.debug.core.DebugEvent;
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.ILaunch;
-import org.eclipse.debug.core.ILaunchConfiguration;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.model.IDebugTarget;
-import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.debug.core.IJavaDebugTarget;
-import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
-import org.eclipse.jdt.debug.tests.AbstractDebugTest;
-import org.eclipse.jdt.debug.tests.TestUtil;
-
-/**
- * Tests conditional breakpoints.
- */
-public class LambdaBreakpointsTests extends AbstractDebugTest {
-
-	/**
-	 * Constructor
-	 * @param name
-	 */
-	public LambdaBreakpointsTests(String name) {
-		super(name);
-	}
-
-	@Override
-	protected IJavaProject getProjectContext() {
-		return get18Project();
-	}
-
-
-	/**
-	 * Test for Bug 541110 - ClassCastException in Instruction.popValue and a zombie EventDispatcher$1 job afterwards
-	 *
-	 * We check that a specific conditional breakpoint on a line with a lambda expression does not cause a {@link ClassCastException}.
-	 */
-	public void testBug541110() throws Exception {
-		assertNoErrorMarkersExist();
-
-		String typeName = "Bug541110";
-		createConditionalLineBreakpoint(22, typeName, "map.get(key) != null", true);
-
-		try {
-			// The class cast exception causes a job which runs forever. So we will timeout when waiting for debug events, if the exception occurs.
-			ILaunchConfiguration config = getLaunchConfiguration(typeName);
-			DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.TERMINATE);
-			launchAndWait(config, waiter);
-			// Join running jobs in case the launch did go through, but we have the endless job.
-			TestUtil.waitForJobs(getName(), 1_000, 30_000, ProcessConsole.class);
-		} finally {
-			terminateAndRemoveJavaLaunches();
-			removeAllBreakpoints();
-		}
-	}
-
-	private void terminateAndRemoveJavaLaunches() {
-		ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
-		List<ILaunch> launches = Arrays.asList(launchManager.getLaunches());
-		for (ILaunch launch : launches) {
-			IDebugTarget debugTarget = launch.getDebugTarget();
-			if (debugTarget instanceof IJavaDebugTarget) {
-				terminateAndRemove((IJavaDebugTarget) debugTarget);
-			}
-		}
-	}
-}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugViewTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugViewTests.java
index ac6f7ea..843f239 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugViewTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugViewTests.java
@@ -55,13 +55,15 @@
 	}
 
 	private LaunchView debugView;
-	private boolean showMonitorsOriginal;
+	private Boolean showMonitorsOriginal;
+	private Boolean showSystemThreadsOriginal;
 
 	@Override
 	protected void setUp() throws Exception {
 		super.setUp();
 		IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
 		showMonitorsOriginal = jdiUIPreferences.getBoolean(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO);
+		showSystemThreadsOriginal = jdiUIPreferences.getBoolean(IJavaDebugUIConstants.PREF_SHOW_SYSTEM_THREADS);
 		jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO, true);
 		resetPerspective(DebugViewPerspectiveFactory.ID);
 		debugView = sync(() -> (LaunchView) getActivePage().showView(IDebugUIConstants.ID_DEBUG_VIEW));
@@ -72,6 +74,7 @@
 	protected void tearDown() throws Exception {
 		IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
 		jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO, showMonitorsOriginal);
+		jdiUIPreferences.setValue(IJavaDebugUIConstants.PREF_SHOW_SYSTEM_THREADS, showSystemThreadsOriginal);
 		sync(() -> getActivePage().closeAllEditors(false));
 		processUiEvents(100);
 		super.tearDown();
@@ -118,6 +121,7 @@
 			try {
 				thread = launchToBreakpoint(typeName, breakpointMethodName, expectedBreakpointHitsCount);
 
+				assertDebugViewIsOpen();
 				assertStackFrameIsSelected(breakpointMethodName);
 			} catch (AssertionError assertionError) {
 				failedAssertions.add(assertionError);
@@ -272,8 +276,13 @@
 		sync(() -> getActivePage().activate(debugView));
 	}
 
+	protected void assertDebugViewIsOpen() throws Exception {
+		debugView = sync(() -> (LaunchView) getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW));
+		assertNotNull("expected Debug View to be open", debugView);
+	}
+
 	protected void assertDebugViewIsActive() throws Exception {
-		assertEquals("expected Debug View to activate after resuming thread", debugView, sync(() -> getActivePage().getActivePart()));
+		assertEquals("expected Debug View to be activate", debugView, sync(() -> getActivePage().getActivePart()));
 	}
 
 	protected static class BreakpointWaiter extends DebugElementKindEventDetailWaiter {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugViewTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugViewTests.java
index 779348d..ed315d8 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugViewTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugViewTests.java
@@ -17,9 +17,13 @@
 
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.ui.IDebugUIConstants;
 import org.eclipse.jdt.debug.core.IJavaStackFrame;
 import org.eclipse.jdt.debug.core.IJavaThread;
 import org.eclipse.jdt.debug.tests.TestAgainException;
+import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.test.OrderedTestSuite;
 import org.eclipse.ui.IViewPart;
@@ -194,6 +198,36 @@
 	}
 
 	/**
+	 * Test for Bug 540243 - Wrong selection when first opening view due to breakpoint
+	 *
+	 * When hitting a breakpoint, if the Debug View is open at all, and we show Java thread owned monitors, its possible to see a wrong selection in
+	 * the Debug View. To ensure this doesn't occur, this test does the following:
+	 *
+	 * <ol>
+	 * <li>ensures the Debug View is showing owned monitors for threads</li>
+	 * <li>close the Debug View</li>
+	 * <li>create a Java snippet which starts a thread</li>
+	 * <li>set a break point in the code executed by the thread</li>
+	 * <li>debug the snippet until the break point is reached</li>
+	 * <li>validate that the selection in the Debug View contains is exactly the method with a break point</li>
+	 * </ol>
+	 */
+	public void testWrongSelectionBug540243() throws Exception {
+		IPreferenceStore jdiUIPreferences = JDIDebugUIPlugin.getDefault().getPreferenceStore();
+		Boolean isShowingMonitorThreadInfo = jdiUIPreferences.getBoolean(IJavaDebugUIConstants.PREF_SHOW_MONITOR_THREAD_INFO);
+		assertNotNull("Preference to show thread owned monitors must be set but is not", isShowingMonitorThreadInfo);
+		assertTrue("Preference to show thread owned monitors must be enabled but is not", isShowingMonitorThreadInfo);
+
+		sync(() -> getActivePage().hideView(getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW)));
+
+		int iterations = 1;
+		String typeName = "Bug540243";
+		String breakpointMethodName = "breakpointMethod";
+		int expectedBreakpointHitsCount = 1;
+		doTestWrongSelection(iterations, typeName, breakpointMethodName, expectedBreakpointHitsCount);
+	}
+
+	/**
 	 * Test for Bug 534319 - Debug View shows wrong information due to threads with short lifetime
 	 *
 	 * We observe that e.g. starting new threads from the debugged JVM can cause incorrect selections in the Debug View. To assure this doesn't occur,
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/presentation/ModelPresentationTests18.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/presentation/ModelPresentationTests18.java
new file mode 100644
index 0000000..8592def
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/presentation/ModelPresentationTests18.java
@@ -0,0 +1,78 @@
+/*******************************************************************************

+ * Copyright (c) 2019 IBM Corporation and others.

+ *

+ * 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

+ * https://www.eclipse.org/legal/epl-2.0/

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ * Contributors:

+ *     Paul Pazderski - initial API and implementation

+ *******************************************************************************/

+package org.eclipse.jdt.debug.tests.ui.presentation;

+

+import org.eclipse.debug.core.model.ILineBreakpoint;

+import org.eclipse.debug.core.model.IVariable;

+import org.eclipse.debug.ui.IDebugModelPresentation;

+import org.eclipse.jdt.core.IJavaProject;

+import org.eclipse.jdt.debug.core.IJavaStackFrame;

+import org.eclipse.jdt.debug.core.IJavaThread;

+import org.eclipse.jdt.debug.tests.AbstractDebugTest;

+import org.eclipse.jdt.internal.debug.core.logicalstructures.JDILambdaVariable;

+import org.eclipse.jdt.internal.debug.core.model.LambdaUtils;

+import org.eclipse.jdt.internal.debug.ui.JDIModelPresentation;

+

+/**

+ * Tests for some of the methods of the model presentation requiring/using Java 1.8 features.

+ *

+ * @see JDIModelPresentation

+ * @see ModelPresentationTests

+ */

+public class ModelPresentationTests18 extends AbstractDebugTest {

+

+	/**

+	 * Constructor

+	 */

+	public ModelPresentationTests18() {

+		super("Model Presentation tests using Java 1.8 features");

+	}

+

+	@Override

+	protected IJavaProject getProjectContext() {

+		return get18Project();

+	}

+

+	/**

+	 * Tests a closure/lambda variable text including variable type name.

+	 *

+	 * Test for Bug 542989.

+	 *

+	 * @throws Exception

+	 */

+	public void testClosureVariableText() throws Exception {

+		String typeName = "ClosureVariableTest_Bug542989";

+		ILineBreakpoint bp = createLineBreakpoint(18, typeName);

+

+		JDIModelPresentation pres = new JDIModelPresentation();

+		IJavaThread thread = null;

+		try {

+			thread = launchToLineBreakpoint(typeName, bp);

+

+			IJavaStackFrame frame = (IJavaStackFrame) thread.getTopStackFrame();

+			assertTrue("Did not stopped in lambda context.", LambdaUtils.isLambdaFrame(frame));

+			String closureVariableName = new JDILambdaVariable(null).getName();

+			IVariable closure = findVariable(frame, closureVariableName);

+			assertNotNull("Could not find variable '" + closureVariableName + "'", closure);

+

+			pres.setAttribute(IDebugModelPresentation.DISPLAY_VARIABLE_TYPE_NAMES, Boolean.TRUE);

+			String text = pres.getText(closure);

+			assertNotNull(text);

+		} finally {

+			terminateAndRemove(thread);

+			removeAllBreakpoints();

+			pres.dispose();

+		}

+	}

+}

diff --git a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
index 08163ba..d57c604 100644
--- a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug.ui; singleton:=true
-Bundle-Version: 3.10.100.qualifier
+Bundle-Version: 3.10.200.qualifier
 Bundle-Activator: org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index a680465..9f68823 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -1419,6 +1419,10 @@
                      name="PrimitiveVariableActionFilter"
                      value="isPrimitive">
                </objectState>
+               <objectState
+                     name="JavaVariableFilter"
+                     value="isObjectValue">
+               </objectState>
                <not>
                   <objectState
                         name="JavaVariableFilter"
diff --git a/org.eclipse.jdt.debug.ui/pom.xml b/org.eclipse.jdt.debug.ui/pom.xml
index af78e1d..ea497b6 100644
--- a/org.eclipse.jdt.debug.ui/pom.xml
+++ b/org.eclipse.jdt.debug.ui/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.debug.ui</artifactId>
-  <version>3.10.100-SNAPSHOT</version>
+  <version>3.10.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
   <properties>
     <code.ignoredWarnings>-warn:+resource,-deprecation,unavoidableGenericProblems</code.ignoredWarnings>
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
index 2545132..dac12ec 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -264,6 +264,8 @@
 	public static String DetailFormatterDialog_Select_type_6;
 	public static String DetailFormatterDialog_Could_not_open_type_selection_dialog_for_detail_formatters_7;
 	public static String DetailFormatterDialog_Select_type_8;
+	public static String DetailFormatterDialog_Select_type_9;
+	public static String DetailFormatterDialog_Select_type_10;
 	public static String DetailFormatterDialog_Select_a_type_to_format_when_displaying_its_detail_9;
 	public static String DetailFormatterDialog_Edit_Detail_Formatter_1;
 	public static String DetailFormatterDialog_Add_Detail_Formatter_2;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
index ec50283..c2e8452 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2018 IBM Corporation and others.
+# Copyright (c) 2000, 2019 IBM Corporation and others.
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -220,6 +220,8 @@
 DetailFormatterDialog_Select_type_6=Select Type
 DetailFormatterDialog_Could_not_open_type_selection_dialog_for_detail_formatters_7=Could not open type selection dialog for detail formatters
 DetailFormatterDialog_Select_type_8=Select Type
+DetailFormatterDialog_Select_type_9=Browse Type
+DetailFormatterDialog_Select_type_10=In order to  browse a type, a project needs to be present and accessible.
 DetailFormatterDialog_Select_a_type_to_format_when_displaying_its_detail_9=&Select a type to format when displaying its detail:
 DetailFormatterDialog_Edit_Detail_Formatter_1=Edit Detail Formatter
 DetailFormatterDialog_Add_Detail_Formatter_2=Add Detail Formatter
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java
index fc138f6..ac3aed6 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/EditLogicalStructureDialog.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2015 IBM Corporation and others.
+ * Copyright (c) 2004, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -21,6 +21,8 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
@@ -46,6 +48,7 @@
 import org.eclipse.jdt.ui.text.IJavaPartitions;
 import org.eclipse.jdt.ui.text.JavaTextTools;
 import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.dialogs.StatusDialog;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.DocumentEvent;
@@ -622,7 +625,24 @@
 	 * Open the 'select type' dialog, and set the user choice into the formatter.
 	 */
 	private void selectType() {
-		Shell shell= getShell();
+		Shell shell = getShell();
+		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+		if (projects.length == 0) {
+			MessageDialog.openInformation(shell, DebugUIMessages.DetailFormatterDialog_Select_type_9, DebugUIMessages.DetailFormatterDialog_Select_type_10);
+			return;
+		}
+		boolean allClosed = true;
+		for (IProject iProject : projects) {
+			if (iProject.isOpen()) {
+				allClosed = false;
+				break;
+			}
+		}
+
+		if (allClosed) {
+			MessageDialog.openInformation(shell, DebugUIMessages.DetailFormatterDialog_Select_type_9, DebugUIMessages.DetailFormatterDialog_Select_type_10);
+			return;
+		}
 		SelectionDialog dialog= null;
 		try {
 			dialog= JavaUI.createTypeDialog(shell, PlatformUI.getWorkbench().getProgressService(),
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
index 7cea28f..bbf67e4 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaVarActionFilter.java
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.debug.core.IJavaType;
 import org.eclipse.jdt.debug.core.IJavaVariable;
 import org.eclipse.jdt.internal.debug.core.model.JDINullValue;
+import org.eclipse.jdt.internal.debug.core.model.JDIObjectValue;
 import org.eclipse.jdt.internal.debug.core.model.JDIPlaceholderValue;
 import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListVariable;
 import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression;
@@ -191,6 +192,9 @@
 					if (value.equals("isPlaceholderValue")) { //$NON-NLS-1$
 						return varValue instanceof JDIPlaceholderValue;
 					}
+					if (value.equals("isObjectValue")) { //$NON-NLS-1$
+						return varValue != null && JDIObjectValue.class.isAssignableFrom(varValue.getClass());
+					}
 				}
 				else if (name.equals("ConcreteVariableActionFilter") && value.equals("isConcrete")) { //$NON-NLS-1$ //$NON-NLS-2$
 					return isDeclaredSameAsConcrete(var);
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
index 49742d2..ed71f21 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/contentassist/CurrentFrameContext.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -22,7 +22,7 @@
 import org.eclipse.jdt.debug.core.IJavaStackFrame;
 import org.eclipse.jdt.debug.core.IJavaVariable;
 import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
-import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;
+import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIPlaceholderVariable;
 import org.eclipse.jdt.internal.debug.core.model.JDIThisVariable;
 
 
@@ -65,7 +65,8 @@
         if (frame != null) {
             IVariable[] variables = frame.getVariables();
             int index = 0;
-			while (index < variables.length && (variables[index] instanceof JDIThisVariable || variables[index] instanceof JDIReturnValueVariable)) {
+			while (index < variables.length
+					&& (variables[index] instanceof JDIThisVariable || JDIPlaceholderVariable.class.isAssignableFrom(variables[index].getClass()))) {
 				index++;
 			}
             String[][] locals = new String[2][variables.length - index];
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java
index b013a0a..5fd7379 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/threadgroups/JavaDebugTargetProxy.java
@@ -21,7 +21,10 @@
 import org.eclipse.debug.core.DebugPlugin;
 import org.eclipse.debug.core.ILaunch;
 import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IDebugElement;
 import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
 import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
 import org.eclipse.debug.internal.ui.viewers.update.DebugEventHandler;
@@ -29,6 +32,7 @@
 import org.eclipse.debug.internal.ui.viewers.update.DebugTargetProxy;
 import org.eclipse.debug.internal.ui.viewers.update.StackFrameEventHandler;
 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
+import org.eclipse.jdt.debug.ui.JavaDebugUtils;
 import org.eclipse.jdt.internal.debug.ui.monitors.JavaElementContentProvider;
 import org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher;
 import org.eclipse.jface.viewers.Viewer;
@@ -141,4 +145,18 @@
 	    return 0;
 	}
 
+	@Override
+	protected int getStackFrameIndex(IStackFrame stackFrame) {
+		int stackFrameIndex = 0;
+		if (((IJavaDebugTarget) fDebugTarget).supportsMonitorInformation()) {
+			IThread thread = stackFrame.getThread();
+			IDebugElement[] ownedMonitors = JavaDebugUtils.getOwnedMonitors(thread);
+			stackFrameIndex += ownedMonitors.length;
+			IDebugElement contendedMonitor = JavaDebugUtils.getContendedMonitor(thread);
+			if (contendedMonitor != null) {
+				stackFrameIndex++;
+			}
+		}
+		return stackFrameIndex;
+	}
 }
diff --git a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
index eaa9d49..44df683 100644
--- a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true
-Bundle-Version: 3.12.100.qualifier
+Bundle-Version: 3.12.200.qualifier
 Bundle-ClassPath: jdi.jar,
  jdimodel.jar,
  tools.jar
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
index d3b92c5..4a5f6ae 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
@@ -15,8 +15,11 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.eval.ast.engine;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
@@ -57,9 +60,13 @@
 import org.eclipse.jdt.debug.eval.IEvaluationResult;
 import org.eclipse.jdt.internal.debug.core.JDIDebugOptions;
 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
+import org.eclipse.jdt.internal.debug.core.logicalstructures.JDILambdaVariable;
+import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;
 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
+import org.eclipse.jdt.internal.debug.core.model.JDIThisVariable;
 import org.eclipse.jdt.internal.debug.core.model.JDIThread;
 import org.eclipse.jdt.internal.debug.core.model.JDIValue;
+import org.eclipse.jdt.internal.debug.core.model.LambdaUtils;
 import org.eclipse.jdt.internal.debug.eval.EvaluationResult;
 import org.eclipse.jdt.internal.debug.eval.ast.instructions.InstructionSequence;
 
@@ -284,7 +291,8 @@
 		EvaluationSourceGenerator mapper = null;
 		CompilationUnit unit = null;
 		try {
-			IJavaVariable[] localsVar = context.getLocals();
+			List<IJavaVariable> localsVar = new ArrayList<>();
+			localsVar.addAll(Arrays.asList(context.getLocals()));
 			IJavaObject thisClass = context.getThis();
 			IVariable[] innerClassFields; // For anonymous classes, getting variables from outer class
 			if (null != thisClass) {
@@ -292,22 +300,41 @@
 			} else {
 				innerClassFields = new IVariable[0];
 			}
-			int numLocalsVar = localsVar.length;
+			List<IVariable> lambdaFrameVariables = LambdaUtils.getLambdaFrameVariables(frame);
+			int numLocalsVar = localsVar.size();
 			Set<String> names = new HashSet<>();
 			// ******
 			// to hide problems with local variable declare as instance of Local
 			// Types
 			// and to remove locals with duplicate names
 			// IJavaVariable[] locals = new IJavaVariable[numLocalsVar];
-			IJavaVariable[] locals = new IJavaVariable[numLocalsVar + innerClassFields.length];
-			String[] localVariablesWithNull = new String[numLocalsVar + innerClassFields.length];
+			IJavaVariable[] locals = new IJavaVariable[numLocalsVar + innerClassFields.length + lambdaFrameVariables.size()];
+			String[] localVariablesWithNull = new String[numLocalsVar + innerClassFields.length + lambdaFrameVariables.size()];
 			int numLocals = 0;
 			for (int i = 0; i < numLocalsVar; i++) {
-				if (!isLocalType(localsVar[i].getSignature())
-						&& !names.contains(localsVar[i].getName())) {
-					locals[numLocals] = localsVar[i];
-					names.add(localsVar[i].getName());
-					localVariablesWithNull[numLocals++] = localsVar[i].getName();
+				IJavaVariable variable = localsVar.get(i);
+				if (!isLocalType(variable.getSignature()) && !names.contains(variable.getName())) {
+					locals[numLocals] = variable;
+					names.add(variable.getName());
+					localVariablesWithNull[numLocals++] = variable.getName();
+				}
+			}
+			/*
+			 * If we are in a lambda frame, the variable context is not complete; names of outer-scope variables are mangled by the compiler. So we
+			 * check variables one stack frame above the lambda frames, in order to also include outer-scope variables. This is necessary to use local
+			 * variables defined in a method, within a breakpoint condition inside a lambda also defined in that method.
+			 */
+			for (IVariable variable : lambdaFrameVariables) {
+				if (variable instanceof IJavaVariable && !isLambdaOrImplicitVariable(variable)) {
+					IJavaVariable javaVariable = (IJavaVariable) variable;
+					String variableName = variable.getName();
+					if (variableName != null && !variableName.contains("$")) { //$NON-NLS-1$
+						if (!isLocalType(javaVariable.getSignature()) && !names.contains(variableName)) {
+							locals[numLocals] = javaVariable;
+							names.add(variable.getName());
+							localVariablesWithNull[numLocals++] = variable.getName();
+						}
+					}
 				}
 			}
 			// Adding outer class variables to inner class scope
@@ -839,4 +866,10 @@
 		}
 		return updatedSnippet.toString();
 	}
+
+	private static boolean isLambdaOrImplicitVariable(IVariable variable) {
+		boolean isLambdaOrImplicitVariable = variable instanceof JDILambdaVariable || variable instanceof JDIReturnValueVariable
+				|| variable instanceof JDIThisVariable;
+		return isLambdaOrImplicitVariable;
+	}
 }
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/PushLocalVariable.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/PushLocalVariable.java
index 69c1689..f7c3cee 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/PushLocalVariable.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/PushLocalVariable.java
@@ -22,6 +22,7 @@
 import org.eclipse.jdt.debug.core.IJavaObject;
 import org.eclipse.jdt.debug.core.IJavaVariable;
 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
+import org.eclipse.jdt.internal.debug.core.model.LambdaUtils;
 import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
 import org.eclipse.jdt.internal.debug.eval.ast.engine.IRuntimeContext;
 import org.eclipse.osgi.util.NLS;
@@ -64,6 +65,11 @@
 				return;
 			}
 		}
+		IVariable variable = LambdaUtils.findLambdaFrameVariable(context, getName());
+		if (variable != null) {
+			push(variable);
+			return;
+		}
 		throw new CoreException(
 				new Status(
 						IStatus.ERROR,
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java
index 034d018..055455d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDILambdaVariable.java
@@ -10,61 +10,23 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Paul Pazderski - Bug 542989 - inherit from {@link JDIPlaceholderVariable} to prevent NPEs
  *******************************************************************************/
 package org.eclipse.jdt.internal.debug.core.logicalstructures;
 
-import org.eclipse.debug.core.DebugException;
-import org.eclipse.debug.core.model.IVariable;
-import org.eclipse.jdt.debug.core.IJavaStackFrame;
-import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
-import org.eclipse.jdt.internal.debug.core.model.JDIVariable;
-
-import com.sun.jdi.ObjectReference;
-import com.sun.jdi.Type;
-import com.sun.jdi.Value;
+import org.eclipse.jdt.debug.core.IJavaValue;
 
 /**
- * Represents the return value after a "step-return".
+ * Represents the closure context inside a lambda expression.
  */
-public class JDILambdaVariable extends JDIVariable {
+public class JDILambdaVariable extends JDIPlaceholderVariable {
 
-	private ObjectReference fObject;
-
-	public JDILambdaVariable(JDIDebugTarget target, IJavaStackFrame frame, ObjectReference object) {
-		super(target);
-		this.fObject = object;
+	public JDILambdaVariable(IJavaValue value) {
+		super("Lambda", value); //$NON-NLS-1$
 	}
 
 	@Override
-	protected Value retrieveValue() {
-		return fObject;
-	}
-
-	/**
-	 * @see IVariable#getName()
-	 */
-	@Override
-	public String getName() {
-		return "Lambda"; //$NON-NLS-1$
-	}
-
-	@Override
-	public String getSignature() throws DebugException {
-		return null;
-	}
-
-	@Override
-	public String getGenericSignature() throws DebugException {
-		return null;
-	}
-
-	@Override
-	public String getReferenceTypeName() throws DebugException {
-		return null;
-	}
-
-	@Override
-	protected Type getUnderlyingType() throws DebugException {
-		return null;
+	public boolean isSynthetic() {
+		return true;
 	}
 }
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
index b5970c5..e292189 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java
@@ -362,13 +362,14 @@
 					}
 				}
 				if (LambdaUtils.isLambdaFrame(this)) {
-						List<IJavaStackFrame> frames = fThread.computeStackFrames();
-						int previousIndex = frames.indexOf(this) + 1;
-						if (previousIndex > 0 && previousIndex < frames.size()) {
-							IJavaStackFrame previousFrame = frames.get(previousIndex);
-							fVariables.add(new JDILambdaVariable((JDIDebugTarget) getDebugTarget(), previousFrame, ((JDIStackFrame) previousFrame).getUnderlyingThisObject()));
-						}
+					List<IJavaStackFrame> frames = fThread.computeStackFrames();
+					int previousIndex = frames.indexOf(this) + 1;
+					if (previousIndex > 0 && previousIndex < frames.size()) {
+						IJavaStackFrame previousFrame = frames.get(previousIndex);
+						IJavaValue closureValue = JDIValue.createValue((JDIDebugTarget) getDebugTarget(), ((JDIStackFrame) previousFrame).getUnderlyingThisObject());
+						fVariables.add(new JDILambdaVariable(closureValue));
 					}
+				}
 				addStepReturnValue(fVariables);
 				// add locals
 				Iterator<LocalVariable> variables = getUnderlyingVisibleVariables()
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
index ccce91c..e3cc969 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
@@ -22,7 +22,6 @@
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IValue;
 import org.eclipse.debug.core.model.IVariable;
-
 import org.eclipse.jdt.debug.core.IJavaType;
 import org.eclipse.jdt.debug.core.IJavaValue;
 import org.eclipse.jdt.debug.core.IJavaVariable;
@@ -39,6 +38,7 @@
 import com.sun.jdi.Type;
 import com.sun.jdi.VMDisconnectedException;
 import com.sun.jdi.Value;
+import com.sun.jdi.VoidValue;
 
 /**
  * Represents the value of a java variable
@@ -95,7 +95,7 @@
 
 	/**
 	 * Creates the appropriate kind of value - i.e. a primitive value, object,
-	 * class object, array, or <code>null</code>.
+	 * class object, array, <code>null</code> or void.
 	 */
 	public static JDIValue createValue(JDIDebugTarget target, Value value) {
 		if (value == null) {
@@ -113,6 +113,9 @@
 		if (value instanceof PrimitiveValue) {
 			return new JDIPrimitiveValue(target, value);
 		}
+		if (value instanceof VoidValue) {
+			return new JDIVoidValue(target);
+		}
 		return new JDIValue(target, value);
 	}
 
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java
index aeea804..851bc81 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java
@@ -14,8 +14,18 @@
 package org.eclipse.jdt.internal.debug.core.model;
 
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.jdt.debug.core.IJavaStackFrame;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.internal.debug.eval.ast.engine.IRuntimeContext;
 
 /**
  * Utility class for Lambda Expressions and Stack frames Place holder for all Lambda operation encapsulation.
@@ -23,6 +33,77 @@
 public class LambdaUtils {
 
 	/**
+	 * Inspects the top stack frame of the context; if that frame is a lambda frame, looks for a variable with the specified name in that frame and
+	 * two frames below that frame.
+	 *
+	 * Inside a lambda expression, variable names are mangled by the compiler. Its therefore necessary to check the outer frame when at a lambda
+	 * frame, in order to find a variable with its name. The lambda expression itself is called by a synthetic static method, which is the first frame
+	 * below the lambda frame. So in total we check 3 stack frames for the variable with the specified name.
+	 *
+	 * @param context
+	 *            The context in which to check.
+	 * @param variableName
+	 *            The name of the variable.
+	 * @return The variable with the specified name if found, {@code null} otherwise. Also returns {@code null} if no thread or top stack frame is
+	 *         available. If there are multiple variables with the same name in the lambda context, the most local one is returned.
+	 * @throws DebugException
+	 *             If accessing the top stack frame or the local variables on stack frames fails, due to failure to communicate with the debug target.
+	 */
+	public static IVariable findLambdaFrameVariable(IRuntimeContext context, String variableName) throws DebugException {
+		IJavaThread thread = context.getThread();
+		if (thread != null) {
+			IStackFrame topStackFrame = thread.getTopStackFrame();
+			List<IVariable> variables = getLambdaFrameVariables(topStackFrame);
+			for (IVariable variable : variables) {
+				if (variable.getName().equals(variableName)) {
+					return variable;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Collects variables visible from a lambda stack frame. I.e. inspects the specified stack frame; if that frame is a lambda frame, collects all
+	 * variables in that frame and two frames below that frame.
+	 *
+	 * Inside a lambda expression, variable names are mangled by the compiler. Its therefore necessary to check the outer frame when at a lambda
+	 * frame, in order to find a variable with its name. The lambda expression itself is called by a synthetic static method, which is the first frame
+	 * below the lambda frame. So in total we collect variables from 3 stack frames.
+	 *
+	 * @param frame
+	 *            The lambda frame at which to check.
+	 * @return The variables visible from the stack frame. An empty list if the specified stack frame is not a lambda frame. The variables are ordered
+	 *         top-down, i.e. if shadowing occurs, the more local variable will be first in the resulting list.
+	 * @throws DebugException
+	 *             If accessing the top stack frame or the local variables on stack frames fails, due to failure to communicate with the debug target.
+	 */
+	public static List<IVariable> getLambdaFrameVariables(IStackFrame frame) throws DebugException {
+		List<IVariable> variables = new ArrayList<>();
+		if (LambdaUtils.isLambdaFrame(frame)) {
+			IThread thread = frame.getThread();
+			IStackFrame[] stackFrames = thread.getStackFrames();
+			for (int i = 0; i < Math.min(3, stackFrames.length); ++i) {
+				IStackFrame stackFrame = stackFrames[i];
+				IVariable[] stackFrameVariables = stackFrame.getVariables();
+				variables.addAll(Arrays.asList(stackFrameVariables));
+			}
+		}
+		return Collections.unmodifiableList(variables);
+	}
+
+	/**
+	 * Evaluates if the input frame is a lambda frame.
+	 *
+	 * @param frame
+	 *            the frame which needs to be evaluated
+	 * @return <code>True</code> if the frame is a lambda frame else return <code>False</Code>
+	 */
+	public static boolean isLambdaFrame(IStackFrame frame) throws DebugException {
+		return frame instanceof IJavaStackFrame && isLambdaFrame((IJavaStackFrame) frame);
+	}
+
+	/**
 	 * Evaluates if the input frame is a lambda frame.
 	 *
 	 * @param frame
@@ -33,5 +114,4 @@
 	public static boolean isLambdaFrame(IJavaStackFrame frame) throws DebugException {
 		return frame.isSynthetic() && frame.getName().startsWith("lambda$"); //$NON-NLS-1$
 	}
-
-	}
+}
diff --git a/org.eclipse.jdt.debug/pom.xml b/org.eclipse.jdt.debug/pom.xml
index eccb2dd..68d6fea 100644
--- a/org.eclipse.jdt.debug/pom.xml
+++ b/org.eclipse.jdt.debug/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.debug</artifactId>
-  <version>3.12.100-SNAPSHOT</version>
+  <version>3.12.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
index 81987a5..6fcb96d 100644
--- a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.launching; singleton:=true
-Bundle-Version: 3.12.0.qualifier
+Bundle-Version: 3.12.100.qualifier
 Bundle-Activator: org.eclipse.jdt.internal.launching.LaunchingPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
@@ -16,7 +16,7 @@
  org.eclipse.jdt.launching.sourcelookup.containers
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.jdt.core;bundle-version="[3.15.0,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.13.0,4.0.0)",
+ org.eclipse.debug.core;bundle-version="[3.13.200,4.0.0)",
  org.eclipse.jdt.debug;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
index afe5b6e..94e64da 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
@@ -56,7 +56,9 @@
 import org.eclipse.debug.core.ILaunchManager;
 import org.eclipse.debug.core.Launch;
 import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IStreamMonitor;
 import org.eclipse.debug.core.model.IStreamsProxy;
+import org.eclipse.debug.internal.core.OutputStreamMonitor;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.launching.AbstractVMInstallType;
 import org.eclipse.jdt.launching.ILibraryLocationResolver;
@@ -700,9 +702,11 @@
 				p = DebugPlugin.exec(cmdLine, null, envp);
 				IProcess process = DebugPlugin.newProcess(new Launch(null, ILaunchManager.RUN_MODE, null), p, "Library Detection"); //$NON-NLS-1$
 				process.setAttribute(IProcess.ATTR_CMDLINE, String.join(" ", cmdLine)); //$NON-NLS-1$
+				IStreamMonitor outputStreamMonitor = process.getStreamsProxy().getOutputStreamMonitor();
 				for (int i= 0; i < 600; i++) {
-					// Wait no more than 30 seconds (600 * 50 milliseconds)
-					if (process.isTerminated()) {
+					// Wait no more than 30 seconds (600 * 50 milliseconds),
+					// also ensure we are done reading the process stream, if we have a OutputStreamMonitor
+					if (process.isTerminated() && isReadingDone(outputStreamMonitor)) {
 						break;
 					}
 					try {
@@ -728,6 +732,14 @@
 		return info;
 	}
 
+	@SuppressWarnings("restriction")
+	private boolean isReadingDone(IStreamMonitor monitor) {
+		if (monitor instanceof OutputStreamMonitor) {
+			return ((OutputStreamMonitor) monitor).isReadingDone();
+		}
+		return true;
+	}
+
 	/**
 	 * Parses the output from 'LibraryDetector'.
 	 *
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/advanced/AdvancedSourceLookup.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/advanced/AdvancedSourceLookup.java
index 77e721c..eefa06c 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/advanced/AdvancedSourceLookup.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/sourcelookup/advanced/AdvancedSourceLookup.java
@@ -60,13 +60,21 @@
 		final Map<File, IPackageFragmentRoot> classpath = new LinkedHashMap<>();
 		for (IPackageFragmentRoot fragment : project.getPackageFragmentRoots()) {
 			if (fragment.getKind() == IPackageFragmentRoot.K_BINARY) {
-				File classpathLocation;
+				File classpathLocation = null;
 				if (fragment.isExternal()) {
 					classpathLocation = fragment.getPath().toFile();
 				} else {
-					classpathLocation = fragment.getResource().getLocation().toFile();
+					IResource resource = fragment.getResource();
+					if (resource != null) {
+						IPath location = resource.getLocation();
+						if (location != null) {
+							classpathLocation = location.toFile();
+						}
+					}
 				}
-				classpath.put(classpathLocation, fragment);
+				if (classpathLocation != null) {
+					classpath.put(classpathLocation, fragment);
+				}
 			}
 		}
 		return classpath;
diff --git a/org.eclipse.jdt.launching/pom.xml b/org.eclipse.jdt.launching/pom.xml
index 50b420b..b98ef87 100644
--- a/org.eclipse.jdt.launching/pom.xml
+++ b/org.eclipse.jdt.launching/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.launching</artifactId>
-  <version>3.12.0-SNAPSHOT</version>
+  <version>3.12.100-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
   
   <build>