Merge remote-tracking branch 'origin/master' into BETA_JAVA17

Change-Id: If12ca693de9a022531cb4f4aafce2b4e428b567f
diff --git a/org.eclipse.jdt.debug.tests/JDT Debug Evaluation Test Suite.launch b/org.eclipse.jdt.debug.tests/JDT Debug Evaluation Test Suite.launch
index 3fb6d26..ae8180e 100644
--- a/org.eclipse.jdt.debug.tests/JDT Debug Evaluation Test Suite.launch
+++ b/org.eclipse.jdt.debug.tests/JDT Debug Evaluation Test Suite.launch
@@ -24,7 +24,7 @@
 <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
 <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
 <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
-<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
 <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.jdt.debug.tests.EvalTestSuite"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jdt.debug.tests"/>
diff --git a/org.eclipse.jdt.debug.tests/JDT Debug Test Suite.launch b/org.eclipse.jdt.debug.tests/JDT Debug Test Suite.launch
index d435c12..86a90a2 100644
--- a/org.eclipse.jdt.debug.tests/JDT Debug Test Suite.launch
+++ b/org.eclipse.jdt.debug.tests/JDT Debug Test Suite.launch
@@ -1,44 +1,226 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.pde.ui.JunitLaunchConfig">
-<booleanAttribute key="append.args" value="true"/>
-<booleanAttribute key="askclear" value="false"/>
-<booleanAttribute key="automaticAdd" value="true"/>
-<booleanAttribute key="automaticValidate" value="false"/>
-<stringAttribute key="bootstrap" value=""/>
-<stringAttribute key="checked" value="[NONE]"/>
-<booleanAttribute key="clearConfig" value="true"/>
-<booleanAttribute key="clearws" value="true"/>
-<booleanAttribute key="clearwslog" value="false"/>
-<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
-<booleanAttribute key="default" value="true"/>
-<booleanAttribute key="includeOptional" value="true"/>
-<stringAttribute key="location" value="${workspace_loc}/../debug-junit-workspace"/>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
-<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
-<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.jdt.debug.tests.AutomatedSuite"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jdt.debug.tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx384m -XX:MaxPermSize=128M"/>
-<stringAttribute key="pde.version" value="3.3"/>
-<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
-<booleanAttribute key="run_in_ui_thread" value="true"/>
-<stringAttribute key="selected_target_plugins" value="org.eclipse.team.cvs.core@default:default,com.jcraft.jsch@default:default,org.eclipse.core.commands@default:default,org.eclipse.ltk.ui.refactoring@default:default,org.apache.jasper@default:default,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.core.databinding.beans@default:default,org.eclipse.jsch.core@default:default,org.eclipse.equinox.p2.updatechecker@default:default,org.eclipse.equinox.p2.ui.sdk@default:default,org.eclipse.help@default:default,org.eclipse.ui.net@default:default,org.eclipse.ui.intro.universal@default:default,org.eclipse.help.base@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.mortbay.jetty.util@default:default,org.eclipse.equinox.security.ui@default:default,org.eclipse.equinox.p2.metadata.generator@default:default,org.eclipse.core.filesystem.linux.x86@default:false,org.sat4j.pb@default:default,org.eclipse.platform@default:default,org.eclipse.equinox.jsp.jasper@default:default,org.eclipse.pde.ds.ui@default:default,org.apache.commons.logging@default:default,org.eclipse.equinox.common@default:default,org.eclipse.pde@default:default,org.eclipse.core.resources.compatibility@default:false,org.eclipse.core.net@default:default,org.eclipse.core.filebuffers@default:default,org.eclipse.equinox.p2.directorywatcher@default:default,org.eclipse.equinox.security@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.rcp@default:default,org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false,org.eclipse.equinox.p2.console@default:default,org.eclipse.sdk@default:default,org.eclipse.swt@default:default,org.eclipse.ui.views@default:default,org.apache.commons.codec@default:default,org.eclipse.core.databinding@default:default,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.equinox.jsp.jasper.registry@default:default,org.eclipse.compare.core@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.core.expressions@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.jdt.junit4.runtime@default:default,org.eclipse.jdt.junit.runtime@default:default,org.eclipse.ui.forms@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.ui.navigator.resources@default:default,org.eclipse.osgi.services@default:default,org.eclipse.help.appserver@default:default,org.mortbay.jetty.server@default:default,org.junit@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.ui.sdk.scheduler@default:default,org.eclipse.cvs@default:default,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.jface.text@default:default,org.eclipse.team.cvs.ssh2@default:default,org.eclipse.jdt.compiler.tool@default:false,org.eclipse.ui.ide.application@default:default,org.eclipse.team.core@default:default,org.eclipse.equinox.registry@default:default,org.junit4@default:default,org.eclipse.compare@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.frameworkadmin@default:default,com.api.tools.buildnotes.nl@default:false,org.eclipse.team.cvs.ssh@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.pde.ds.core@default:default,org.apache.ant@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.search@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ecf.provider.filetransfer.httpclient@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.apache.commons.httpclient@default:default,org.eclipse.jdt.compiler.apt@default:false,org.eclipse.ltk.core.refactoring@default:default,org.eclipse.ui.intro@default:default,org.eclipse.equinox.http.servlet@default:default,org.eclipse.core.resources@default:default,javax.servlet@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.exemplarysetup@default:default,org.eclipse.ui@default:default,org.eclipse.jsch.ui@default:default,org.eclipse.pde.ua.core@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.eclipse.equinox.preferences@default:default,org.eclipse.core.net.linux.x86@default:false,javax.servlet.jsp@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,com.ibm.icu@default:default,org.eclipse.core.boot@default:default,org.eclipse.jdt.apt.core@default:default,org.eclipse.osgi.util@default:default,org.eclipse.ui.editors@default:default,org.eclipse.ui.workbench.compatibility@default:false,org.eclipse.equinox.launcher@default:default,org.apache.lucene.analysis@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.equinox.http.jetty@default:default,org.apache.commons.el@default:default,org.eclipse.equinox.launcher.gtk.linux.x86@default:false,org.eclipse.ui.presentations.r21@default:default,org.eclipse.jdt.core.manipulation@default:default,org.eclipse.equinox.app@default:default,org.eclipse.ui.cheatsheets@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.swt.gtk.linux.x86@default:false,org.eclipse.osgi@default:default,org.eclipse.jdt.apt.pluggable.core@default:default,org.eclipse.jdt.apt.ui@default:default,org.eclipse.ui.navigator@default:default,org.eclipse.pde.ua.ui@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.team.cvs.ui@default:default,org.eclipse.help.webapp@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.equinox.p2.ui@default:default,org.objectweb.asm@default:default,org.sat4j.core@default:default,org.eclipse.equinox.p2.reconciler.dropins@default:default,org.eclipse.team.ui@default:default,org.eclipse.ui.browser@default:default,org.eclipse.ecf@default:default,org.eclipse.jdt@default:default,org.eclipse.jdt.junit@default:default,org.eclipse.equinox.p2.extensionlocation@default:default,org.eclipse.equinox.p2.metadata@default:default,org.apache.lucene@default:default,org.eclipse.ui.views.properties.tabbed@default:default,org.eclipse.core.runtime@default:true,org.eclipse.core.jobs@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.equinox.simpleconfigurator@default:default,org.eclipse.equinox.p2.core@default:default"/>
-<stringAttribute key="selected_workspace_plugins" value="org.eclipse.jdt.core.tests.compiler@default:default,org.eclipse.example.mixedmode@default:default,org.eclipse.debug.examples.ui@default:default,org.eclipse.ant.core@default:default,org.eclipse.platform.doc.isv@default:default,org.eclipse.ant.ui@default:default,org.eclipse.jdt.core.tests.builder@default:default,org.eclipse.debug.util@default:default,org.eclipse.platform.doc.user@default:default,com.api.tools.buildnotes.nl@default:false,org.eclipse.jdt.doc.isv@default:default,org.eclipse.ui.console@default:default,org.eclipse.debug.ui@default:default,org.eclipse.pde.api.tools@default:default,org.eclipse.ui.externaltools@default:default,org.eclipse.jdt.ui.examples.javafamily@default:default,org.eclipse.pde.doc.user@default:default,org.eclipse.jdt.debug.ui@default:default,org.eclipse.jdt.doc.user@default:default,org.eclipse.jdt.debug.tests@default:default,org.eclipse.debug.examples.core@default:default,org.eclipse.jdt.core@default:default,org.eclipse.jdt.launching@default:default,refproject@default:default,org.eclipse.ant.tests.ui@default:default,org.eclipse.debug.core@default:default,org.eclipse.ant.tests.core@default:default,org.eclipse.core.variables@default:default,Testing@default:default,com.api.tools.buildnotes@default:default,org.eclipse.test.performance@default:default,org.eclipse.jdt.debug@default:default,org.eclipse.pde.api.tools.ui@default:default,usagetests@default:default,org.eclipse.pde.api.tools.tests@default:default"/>
-<booleanAttribute key="show_selected_only" value="false"/>
-<booleanAttribute key="tracing" value="false"/>
-<booleanAttribute key="useCustomFeatures" value="false"/>
-<booleanAttribute key="useDefaultConfig" value="true"/>
-<booleanAttribute key="useDefaultConfigArea" value="false"/>
-<booleanAttribute key="useProduct" value="true"/>
+    <booleanAttribute key="append.args" value="true"/>
+    <booleanAttribute key="askclear" value="false"/>
+    <booleanAttribute key="automaticAdd" value="true"/>
+    <booleanAttribute key="automaticValidate" value="false"/>
+    <stringAttribute key="bootstrap" value=""/>
+    <stringAttribute key="checked" value="[NONE]"/>
+    <booleanAttribute key="clearConfig" value="true"/>
+    <booleanAttribute key="clearws" value="true"/>
+    <booleanAttribute key="clearwslog" value="false"/>
+    <stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>
+    <booleanAttribute key="default" value="true"/>
+    <booleanAttribute key="includeOptional" value="true"/>
+    <stringAttribute key="location" value="${workspace_loc}/../debug-junit-workspace"/>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+        <listEntry value="/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java"/>
+    </listAttribute>
+    <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+        <listEntry value="1"/>
+    </listAttribute>
+    <stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
+    <booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
+    <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
+    <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
+    <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
+    <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+    <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.jdt.debug.tests.AutomatedSuite"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
+    <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jdt.debug.tests"/>
+    <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+    <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms40m -Xmx384m -XX:MaxPermSize=128M"/>
+    <stringAttribute key="pde.version" value="3.3"/>
+    <stringAttribute key="product" value="org.eclipse.sdk.ide"/>
+    <booleanAttribute key="run_in_ui_thread" value="true"/>
+    <setAttribute key="selected_target_bundles">
+        <setEntry value="com.api.tools.buildnotes.nl@default:false"/>
+        <setEntry value="com.ibm.icu@default:default"/>
+        <setEntry value="com.jcraft.jsch@default:default"/>
+        <setEntry value="javax.servlet.jsp@default:default"/>
+        <setEntry value="javax.servlet@default:default"/>
+        <setEntry value="org.apache.ant@default:default"/>
+        <setEntry value="org.apache.commons.codec@default:default"/>
+        <setEntry value="org.apache.commons.el@default:default"/>
+        <setEntry value="org.apache.commons.httpclient@default:default"/>
+        <setEntry value="org.apache.commons.logging@default:default"/>
+        <setEntry value="org.apache.jasper@default:default"/>
+        <setEntry value="org.apache.lucene.analysis@default:default"/>
+        <setEntry value="org.apache.lucene@default:default"/>
+        <setEntry value="org.eclipse.compare.core@default:default"/>
+        <setEntry value="org.eclipse.compare@default:default"/>
+        <setEntry value="org.eclipse.core.boot@default:default"/>
+        <setEntry value="org.eclipse.core.commands@default:default"/>
+        <setEntry value="org.eclipse.core.contenttype@default:default"/>
+        <setEntry value="org.eclipse.core.databinding.beans@default:default"/>
+        <setEntry value="org.eclipse.core.databinding@default:default"/>
+        <setEntry value="org.eclipse.core.expressions@default:default"/>
+        <setEntry value="org.eclipse.core.filebuffers@default:default"/>
+        <setEntry value="org.eclipse.core.filesystem.linux.x86@default:false"/>
+        <setEntry value="org.eclipse.core.filesystem@default:default"/>
+        <setEntry value="org.eclipse.core.jobs@default:default"/>
+        <setEntry value="org.eclipse.core.net.linux.x86@default:false"/>
+        <setEntry value="org.eclipse.core.net@default:default"/>
+        <setEntry value="org.eclipse.core.resources.compatibility@default:false"/>
+        <setEntry value="org.eclipse.core.resources@default:default"/>
+        <setEntry value="org.eclipse.core.runtime@default:true"/>
+        <setEntry value="org.eclipse.cvs@default:default"/>
+        <setEntry value="org.eclipse.ecf.filetransfer@default:default"/>
+        <setEntry value="org.eclipse.ecf.identity@default:default"/>
+        <setEntry value="org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false"/>
+        <setEntry value="org.eclipse.ecf.provider.filetransfer.httpclient@default:default"/>
+        <setEntry value="org.eclipse.ecf.provider.filetransfer.ssl@default:false"/>
+        <setEntry value="org.eclipse.ecf.provider.filetransfer@default:default"/>
+        <setEntry value="org.eclipse.ecf.ssl@default:false"/>
+        <setEntry value="org.eclipse.ecf@default:default"/>
+        <setEntry value="org.eclipse.equinox.app@default:default"/>
+        <setEntry value="org.eclipse.equinox.common@default:default"/>
+        <setEntry value="org.eclipse.equinox.frameworkadmin.equinox@default:default"/>
+        <setEntry value="org.eclipse.equinox.frameworkadmin@default:default"/>
+        <setEntry value="org.eclipse.equinox.http.jetty@default:default"/>
+        <setEntry value="org.eclipse.equinox.http.registry@default:default"/>
+        <setEntry value="org.eclipse.equinox.http.servlet@default:default"/>
+        <setEntry value="org.eclipse.equinox.jsp.jasper.registry@default:default"/>
+        <setEntry value="org.eclipse.equinox.jsp.jasper@default:default"/>
+        <setEntry value="org.eclipse.equinox.launcher.gtk.linux.x86@default:false"/>
+        <setEntry value="org.eclipse.equinox.launcher@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.artifact.repository@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.console@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.core@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.director.app@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.director@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.directorywatcher@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.engine@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.exemplarysetup@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.extensionlocation@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.garbagecollector@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.jarprocessor@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.metadata.generator@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.metadata.repository@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.metadata@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.publisher@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.reconciler.dropins@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.touchpoint.eclipse@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.touchpoint.natives@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.ui.sdk.scheduler@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.ui.sdk@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.ui@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.updatechecker@default:default"/>
+        <setEntry value="org.eclipse.equinox.p2.updatesite@default:default"/>
+        <setEntry value="org.eclipse.equinox.preferences@default:default"/>
+        <setEntry value="org.eclipse.equinox.registry@default:default"/>
+        <setEntry value="org.eclipse.equinox.security.ui@default:default"/>
+        <setEntry value="org.eclipse.equinox.security@default:default"/>
+        <setEntry value="org.eclipse.equinox.simpleconfigurator.manipulator@default:default"/>
+        <setEntry value="org.eclipse.equinox.simpleconfigurator@default:default"/>
+        <setEntry value="org.eclipse.help.appserver@default:default"/>
+        <setEntry value="org.eclipse.help.base@default:default"/>
+        <setEntry value="org.eclipse.help.webapp@default:default"/>
+        <setEntry value="org.eclipse.help@default:default"/>
+        <setEntry value="org.eclipse.jdt.apt.core@default:default"/>
+        <setEntry value="org.eclipse.jdt.apt.pluggable.core@default:default"/>
+        <setEntry value="org.eclipse.jdt.apt.ui@default:default"/>
+        <setEntry value="org.eclipse.jdt.compiler.apt@default:false"/>
+        <setEntry value="org.eclipse.jdt.compiler.tool@default:false"/>
+        <setEntry value="org.eclipse.jdt.core.manipulation@default:default"/>
+        <setEntry value="org.eclipse.jdt.junit.runtime@default:default"/>
+        <setEntry value="org.eclipse.jdt.junit4.runtime@default:default"/>
+        <setEntry value="org.eclipse.jdt.junit@default:default"/>
+        <setEntry value="org.eclipse.jdt@default:default"/>
+        <setEntry value="org.eclipse.jface.databinding@default:default"/>
+        <setEntry value="org.eclipse.jface.text@default:default"/>
+        <setEntry value="org.eclipse.jsch.core@default:default"/>
+        <setEntry value="org.eclipse.jsch.ui@default:default"/>
+        <setEntry value="org.eclipse.ltk.core.refactoring@default:default"/>
+        <setEntry value="org.eclipse.ltk.ui.refactoring@default:default"/>
+        <setEntry value="org.eclipse.osgi.services@default:default"/>
+        <setEntry value="org.eclipse.osgi.util@default:default"/>
+        <setEntry value="org.eclipse.osgi@default:default"/>
+        <setEntry value="org.eclipse.pde.ds.core@default:default"/>
+        <setEntry value="org.eclipse.pde.ds.ui@default:default"/>
+        <setEntry value="org.eclipse.pde.ua.core@default:default"/>
+        <setEntry value="org.eclipse.pde.ua.ui@default:default"/>
+        <setEntry value="org.eclipse.pde@default:default"/>
+        <setEntry value="org.eclipse.platform@default:default"/>
+        <setEntry value="org.eclipse.rcp@default:default"/>
+        <setEntry value="org.eclipse.sdk@default:default"/>
+        <setEntry value="org.eclipse.search@default:default"/>
+        <setEntry value="org.eclipse.swt.gtk.linux.x86@default:false"/>
+        <setEntry value="org.eclipse.swt@default:default"/>
+        <setEntry value="org.eclipse.team.core@default:default"/>
+        <setEntry value="org.eclipse.team.cvs.core@default:default"/>
+        <setEntry value="org.eclipse.team.cvs.ssh2@default:default"/>
+        <setEntry value="org.eclipse.team.cvs.ssh@default:default"/>
+        <setEntry value="org.eclipse.team.cvs.ui@default:default"/>
+        <setEntry value="org.eclipse.team.ui@default:default"/>
+        <setEntry value="org.eclipse.ui.browser@default:default"/>
+        <setEntry value="org.eclipse.ui.cheatsheets@default:default"/>
+        <setEntry value="org.eclipse.ui.editors@default:default"/>
+        <setEntry value="org.eclipse.ui.forms@default:default"/>
+        <setEntry value="org.eclipse.ui.ide.application@default:default"/>
+        <setEntry value="org.eclipse.ui.ide@default:default"/>
+        <setEntry value="org.eclipse.ui.intro.universal@default:default"/>
+        <setEntry value="org.eclipse.ui.intro@default:default"/>
+        <setEntry value="org.eclipse.ui.navigator.resources@default:default"/>
+        <setEntry value="org.eclipse.ui.navigator@default:default"/>
+        <setEntry value="org.eclipse.ui.net@default:default"/>
+        <setEntry value="org.eclipse.ui.presentations.r21@default:default"/>
+        <setEntry value="org.eclipse.ui.views.properties.tabbed@default:default"/>
+        <setEntry value="org.eclipse.ui.views@default:default"/>
+        <setEntry value="org.eclipse.ui.workbench.compatibility@default:false"/>
+        <setEntry value="org.eclipse.ui.workbench.texteditor@default:default"/>
+        <setEntry value="org.eclipse.ui.workbench@default:default"/>
+        <setEntry value="org.eclipse.ui@default:default"/>
+        <setEntry value="org.junit4@default:default"/>
+        <setEntry value="org.junit@default:default"/>
+        <setEntry value="org.mortbay.jetty.server@default:default"/>
+        <setEntry value="org.mortbay.jetty.util@default:default"/>
+        <setEntry value="org.objectweb.asm@default:default"/>
+        <setEntry value="org.sat4j.core@default:default"/>
+        <setEntry value="org.sat4j.pb@default:default"/>
+    </setAttribute>
+    <setAttribute key="selected_workspace_bundles">
+        <setEntry value="Testing@default:default"/>
+        <setEntry value="com.api.tools.buildnotes.nl@default:false"/>
+        <setEntry value="com.api.tools.buildnotes@default:default"/>
+        <setEntry value="org.eclipse.ant.core@default:default"/>
+        <setEntry value="org.eclipse.ant.tests.core@default:default"/>
+        <setEntry value="org.eclipse.ant.tests.ui@default:default"/>
+        <setEntry value="org.eclipse.ant.ui@default:default"/>
+        <setEntry value="org.eclipse.core.variables@default:default"/>
+        <setEntry value="org.eclipse.debug.core@default:default"/>
+        <setEntry value="org.eclipse.debug.examples.core@default:default"/>
+        <setEntry value="org.eclipse.debug.examples.ui@default:default"/>
+        <setEntry value="org.eclipse.debug.ui@default:default"/>
+        <setEntry value="org.eclipse.debug.util@default:default"/>
+        <setEntry value="org.eclipse.example.mixedmode@default:default"/>
+        <setEntry value="org.eclipse.jdt.core.tests.builder@default:default"/>
+        <setEntry value="org.eclipse.jdt.core.tests.compiler@default:default"/>
+        <setEntry value="org.eclipse.jdt.core@default:default"/>
+        <setEntry value="org.eclipse.jdt.debug.tests@default:default"/>
+        <setEntry value="org.eclipse.jdt.debug.ui@default:default"/>
+        <setEntry value="org.eclipse.jdt.debug@default:default"/>
+        <setEntry value="org.eclipse.jdt.doc.isv@default:default"/>
+        <setEntry value="org.eclipse.jdt.doc.user@default:default"/>
+        <setEntry value="org.eclipse.jdt.launching@default:default"/>
+        <setEntry value="org.eclipse.jdt.ui.examples.javafamily@default:default"/>
+        <setEntry value="org.eclipse.pde.api.tools.tests@default:default"/>
+        <setEntry value="org.eclipse.pde.api.tools.ui@default:default"/>
+        <setEntry value="org.eclipse.pde.api.tools@default:default"/>
+        <setEntry value="org.eclipse.pde.doc.user@default:default"/>
+        <setEntry value="org.eclipse.platform.doc.isv@default:default"/>
+        <setEntry value="org.eclipse.platform.doc.user@default:default"/>
+        <setEntry value="org.eclipse.test.performance@default:default"/>
+        <setEntry value="org.eclipse.ui.console@default:default"/>
+        <setEntry value="org.eclipse.ui.externaltools@default:default"/>
+        <setEntry value="refproject@default:default"/>
+        <setEntry value="usagetests@default:default"/>
+    </setAttribute>
+    <booleanAttribute key="show_selected_only" value="false"/>
+    <booleanAttribute key="tracing" value="false"/>
+    <booleanAttribute key="useCustomFeatures" value="false"/>
+    <booleanAttribute key="useDefaultConfig" value="true"/>
+    <booleanAttribute key="useDefaultConfigArea" value="false"/>
+    <booleanAttribute key="useProduct" value="true"/>
 </launchConfiguration>
diff --git a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
index b436bcf..eb10689 100644
--- a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
@@ -36,11 +36,11 @@
  org.eclipse.core.resources,
  org.eclipse.core.variables,
  org.eclipse.ui,
- org.eclipse.jdt.core;bundle-version="[3.8.0,4.0.0)",
- org.eclipse.jdt.ui;bundle-version="[3.17.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.11.0,4.0.0)",
- org.eclipse.jdt.debug.ui;bundle-version="[3.9.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.22.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.19.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)",
+ org.eclipse.jdt.debug.ui;bundle-version="[3.12.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.14.0,4.0.0)",
  org.eclipse.debug.ui;bundle-version="[3.13.0,4.0.0)",
  org.eclipse.core.runtime,
diff --git a/org.eclipse.jdt.debug.tests/build.properties b/org.eclipse.jdt.debug.tests/build.properties
index 5a449ba..82a6ff3 100644
--- a/org.eclipse.jdt.debug.tests/build.properties
+++ b/org.eclipse.jdt.debug.tests/build.properties
@@ -24,7 +24,8 @@
                plugin.properties,\
                java7/,\
                java8/,\
-               java9/
+               java9/,\
+               java16_/
 source.javadebugtests.jar = test plugin/,\
                             tests/,\
                             console tests/
diff --git a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/ConsoleTerminateAllActionTests.java b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/ConsoleTerminateAllActionTests.java
index 33ace80..b8498d7 100644
--- a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/ConsoleTerminateAllActionTests.java
+++ b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/ConsoleTerminateAllActionTests.java
@@ -68,7 +68,7 @@
 						IWorkbenchPage page = window.getActivePage();
 						if (page != null) {
 							IViewPart part = page.findView(IConsoleConstants.ID_CONSOLE_VIEW);
-							if (part != null && part instanceof IConsoleView) {
+							if (part instanceof IConsoleView) {
 								view = (ConsoleView) part;
 								break;
 							}
diff --git a/org.eclipse.jdt.debug.tests/java7/Bug572782.java b/org.eclipse.jdt.debug.tests/java7/Bug572782.java
new file mode 100644
index 0000000..4841afb
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java7/Bug572782.java
@@ -0,0 +1,57 @@
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Bug572782 {
+	static class Generic<T> {
+		
+	}
+	
+	static class ExtendedGeneric<T extends Generic<ExtendedGeneric<T>>> {
+		public ExtendedGeneric() {
+			super();
+			System.out.println("created " + this);
+		}
+	}
+
+	static class SimpleGeneric<T extends Generic<T>> {
+		public SimpleGeneric() {
+			super();
+			System.out.println("created " + this);
+		}
+	}
+
+	static class NthGeneric<T extends Generic<ExtendedGeneric<T>>> {
+		public List<T> items;
+
+		public NthGeneric() {
+			super();
+			System.out.println("created " + this);
+			this.items = new ArrayList<>();
+		}
+		
+		public static void nthGeneric() {
+			System.out.println("at nthGeneric");
+		}
+	}
+	
+	static <T extends List<String>> void foo(T list) {
+		System.out.println("at " + list);
+	}
+
+	<T extends Set<String>> void boo(T set) {
+		System.out.println("at " + set);
+	}
+
+	public static void main(String[] args) {
+		new ExtendedGeneric();
+		new SimpleGeneric();
+		new NthGeneric();
+		foo(Arrays.asList("1"));
+		NthGeneric.nthGeneric();
+		(new Bug572782()).boo(new HashSet<String>());
+	}
+}
+
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug569413.java b/org.eclipse.jdt.debug.tests/java8/Bug569413.java
new file mode 100644
index 0000000..76ff99b
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug569413.java
@@ -0,0 +1,41 @@
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class Bug569413 {
+
+	public static void main(String[] args) {
+		new Bug569413().test();
+	}
+
+	List<TestClass> packageProcessors = Arrays.asList(new TestClass());
+	Map<String, TestClass> basePackages = new HashMap<>();
+
+	void test() {
+		packageProcessors.forEach(pp -> {
+			Set<String> pkgs = pp.getPackagesToMap();
+			pp.getPackagesToMap().forEach(p -> {
+				// just to make pkgs variable visible for evaluation
+				int a = pkgs.size();
+				basePackages.put(p, pp);
+			});
+		});
+
+		packageProcessors.forEach(pp -> {
+			pp.getPackagesToMap().forEach(p -> {
+				basePackages.put(p, null);
+			});
+		});
+	}
+
+	static class TestClass {
+
+		public Set<String> getPackagesToMap() {
+			return new LinkedHashSet<>(Arrays.asList("ab", "b", "c"));
+		}
+
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug572629.java b/org.eclipse.jdt.debug.tests/java8/Bug572629.java
new file mode 100644
index 0000000..84c5fb4
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/Bug572629.java
@@ -0,0 +1,75 @@
+import java.util.stream.Stream;
+
+/*******************************************************************************
+ * Copyright (c) 2021 Gayan Perera 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:
+ *     Gayan Perera - initial API and implementation
+ *******************************************************************************/
+public class Bug572629 {
+	private String payload;
+	
+	private String[] payloads;
+
+	private static String[] PAYLOADS = new String[] {"1"};
+	
+	private Parent parent = new Parent();
+
+	public Bug572629(String payload) {
+		this.payload = payload;
+		this.payloads = new String[]{payload};
+	}
+	
+	@Override
+	public boolean equals(Object o) {
+		if (o == null || o.getClass() != this.getClass()) {
+			return false;
+		}
+		Bug572629 other = (Bug572629) o;
+		System.out.print(PAYLOADS.length);
+		return this.payload == other.payload && this.payloads.length == other.payloads.length;
+	}
+	
+	public void hoverOverLocal(String[] names) {
+		char[] name = new char[] {'n', 'a', 'm', 'e'};
+		Bug572629 object = new Bug572629("p");
+
+		System.out.println(name.length);
+		System.out.println(object.payload);
+		System.out.println(names.length);
+		Stream.of(name).forEach(a -> {
+			 System.out.println(a.length);			 
+		});
+	}
+
+	private void hoverOnThis() {
+		System.out.println(this.parent.child.age);
+		System.out.println(this.parent.child.name);
+		System.out.println(parent.child.age);
+		System.out.println(parent.child.name);
+	}
+	
+	public static void main(String[] args) {
+		new Bug572629("p").equals(new Bug572629("r"));
+		new Bug572629("p").hoverOverLocal(new String[] {"name"});
+		new Bug572629("p").hoverOnThis();
+	}
+
+	public static class Parent {
+		public Child child = new Child();
+	}
+
+	public static class Child {
+		public int age = 5;
+		
+		public String name = "name";
+	}
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TableDetailPane.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TableDetailPane.java
index f9acfc3..c39b62b 100644
--- a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TableDetailPane.java
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TableDetailPane.java
@@ -162,7 +162,7 @@
 			while (iterator.hasNext()){
 
 				Object selection = iterator.next();
-				if (selection != null && selection instanceof IVariable){
+				if (selection instanceof IVariable){
 
 					IValue val = null;
 					try {
diff --git a/org.eclipse.jdt.debug.tests/testprograms/MultiThreadedList.java b/org.eclipse.jdt.debug.tests/testprograms/MultiThreadedList.java
index d347a3d..d21ec85 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/MultiThreadedList.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/MultiThreadedList.java
@@ -45,7 +45,7 @@
 	
 	private void listLoop() {
 		while (i < 20) {
-			list.add(new Integer(i++));
+			list.add(Integer.valueOf(i++));
 			System.out.println("Size = " + list.size());
 			try {
 				Thread.sleep(100);
diff --git a/org.eclipse.jdt.debug.tests/testprograms/PerfLoop.java b/org.eclipse.jdt.debug.tests/testprograms/PerfLoop.java
index 09babaf..89239df 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/PerfLoop.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/PerfLoop.java
@@ -22,7 +22,7 @@
 	public static void main(String[] args) {
 		Vector v = new Vector(200);
 		for (int i = 0; i < 100000; i++) {
-			v.add(new Integer(i));
+			v.add(Integer.valueOf(i));
 		}
 	}
 }
diff --git a/org.eclipse.jdt.debug.tests/testprograms/VariableDetails.java b/org.eclipse.jdt.debug.tests/testprograms/VariableDetails.java
index 4bd2c04..3f9a121 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/VariableDetails.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/VariableDetails.java
@@ -22,7 +22,7 @@
 	public static void main(String[] args) {
 		Vector v = new Vector(200);
 		for (int i = 0; i < 100; i++) {
-			v.add(new Integer(i));
+			v.add(Integer.valueOf(i));
 		}
 		System.out.println(v);
 	}
diff --git a/org.eclipse.jdt.debug.tests/testprograms/WatchItemTests.java b/org.eclipse.jdt.debug.tests/testprograms/WatchItemTests.java
index 306143d..12e7d41 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/WatchItemTests.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/WatchItemTests.java
@@ -37,7 +37,7 @@
 	public void fillVector() {
 		fVector = new Vector();
 		for (int i = 0; i < 100; i++) {
-			fVector.add(new Integer(i));
+			fVector.add(Integer.valueOf(i));
 		}
 	}
 	
diff --git a/org.eclipse.jdt.debug.tests/testprograms/org/eclipse/debug/tests/targets/Watchpoint.java b/org.eclipse.jdt.debug.tests/testprograms/org/eclipse/debug/tests/targets/Watchpoint.java
index 45301c4..4ddcf79 100644
--- a/org.eclipse.jdt.debug.tests/testprograms/org/eclipse/debug/tests/targets/Watchpoint.java
+++ b/org.eclipse.jdt.debug.tests/testprograms/org/eclipse/debug/tests/targets/Watchpoint.java
@@ -30,7 +30,7 @@
 		list = new ArrayList(10);
 		int value = 10;
 		while (value > 0) {
-			list.add(new Integer(value));
+			list.add(Integer.valueOf(value));
 			value--;
 		}
 		
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepIntoSelectionTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepIntoSelectionTests.java
index 3da76fa..2c3b9c3 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepIntoSelectionTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/test/stepping/StepIntoSelectionTests.java
@@ -185,7 +185,7 @@
 	}
 
 	/**
-	 * Step into 'new Integer(i)'
+	 * Step into 'Integer.valueOf(i)'
 	 *
 	 * @throws Exception
 	 */
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 dec4564..c9411c9 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
@@ -439,6 +439,7 @@
 	    		cfgs.add(createLaunchConfiguration(jp, LiteralTests17.LITERAL_TYPE_NAME));
 				cfgs.add(createLaunchConfiguration(jp, "ThreadNameChange"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug567801"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug572782"));
 	    		loaded17 = true;
 	    		waitForBuild();
 	        }
@@ -492,6 +493,8 @@
 				cfgs.add(createLaunchConfiguration(jp, "Bug564801"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug567801"));
 				cfgs.add(createLaunchConfiguration(jp, "Bug571230"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug572629"));
+				cfgs.add(createLaunchConfiguration(jp, "Bug569413"));
 	    		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 b1b583a..7f93c69 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
@@ -92,7 +92,9 @@
 import org.eclipse.jdt.debug.tests.core.WorkingDirectoryTests;
 import org.eclipse.jdt.debug.tests.core.WorkspaceSourceContainerTests;
 import org.eclipse.jdt.debug.tests.eval.BlockStatementEvaluationTests;
+import org.eclipse.jdt.debug.tests.eval.ExpressionEvalTest;
 import org.eclipse.jdt.debug.tests.eval.GeneralEvalTests;
+import org.eclipse.jdt.debug.tests.eval.GenericsEval17Test;
 import org.eclipse.jdt.debug.tests.eval.GenericsEvalTests;
 import org.eclipse.jdt.debug.tests.eval.LambdaVariableTest;
 import org.eclipse.jdt.debug.tests.eval.SyntheticVariableTests;
@@ -330,7 +332,9 @@
 
 	//add the complete eval suite
 		addTest(new TestSuite(GeneralEvalTests.class));
+		addTest(new TestSuite(GenericsEval17Test.class));
 		addTest(new TestSuite(BlockStatementEvaluationTests.class));
+		addTest(new TestSuite(ExpressionEvalTest.class));
 		if (JavaProjectHelper.isJava8Compatible()) {
 			addTest(new TestSuite(LambdaVariableTest.class));
 		}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsTests.java
index 8ed3797..1fa9e6b 100755
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsTests.java
@@ -516,7 +516,7 @@
 	 */
 	public void testConditionBreakpointReturnNonBooleanObject() throws Exception {
 		String typeName = "HitCountLooper";
-		createConditionalLineBreakpoint(16, typeName, "return new Integer(1)", true);
+		createConditionalLineBreakpoint(16, typeName, "return Integer.valueOf(1)", true);
 		IJavaLineBreakpoint bp1 = createConditionalLineBreakpoint(17, typeName, "return true", true);
 
 		IJavaThread thread = null;
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/JavaBreakpointListenerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/JavaBreakpointListenerTests.java
index 78003e1..caaf4a3 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/JavaBreakpointListenerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/JavaBreakpointListenerTests.java
@@ -72,7 +72,7 @@
 	/**
 	 * Used to test breakpoint install/suspend voting.
 	 */
-	class SuspendVoter implements IJavaBreakpointListener {
+	static class SuspendVoter implements IJavaBreakpointListener {
 
 		int fVote;
 		IJavaBreakpoint fTheBreakpoint;
@@ -782,7 +782,7 @@
 		bp.addBreakpointListener("org.eclipse.jdt.debug.tests.evalListener");
 		EvalualtionBreakpointListener.reset();
 		EvalualtionBreakpointListener.PROJECT = get14Project();
-		EvalualtionBreakpointListener.EXPRESSION = "return new Integer(i);";
+		EvalualtionBreakpointListener.EXPRESSION = "return Integer.valueOf(i);";
 		EvalualtionBreakpointListener.VOTE = IJavaBreakpointListener.SUSPEND;
 
 		IJavaThread thread= null;
@@ -851,7 +851,7 @@
 		second.addBreakpointListener("org.eclipse.jdt.debug.tests.evalListener");
 		EvalualtionBreakpointListener.reset();
 		EvalualtionBreakpointListener.PROJECT = get14Project();
-		EvalualtionBreakpointListener.EXPRESSION = "return new Integer(sum);";
+		EvalualtionBreakpointListener.EXPRESSION = "return Integer.valueOf(sum);";
 		EvalualtionBreakpointListener.VOTE = IJavaBreakpointListener.DONT_SUSPEND;
 		EvalualtionBreakpointListener.RESULT = null;
 
@@ -904,7 +904,7 @@
 		second.addBreakpointListener("org.eclipse.jdt.debug.tests.evalListener");
 		EvalualtionBreakpointListener.reset();
 		EvalualtionBreakpointListener.PROJECT = get14Project();
-		EvalualtionBreakpointListener.EXPRESSION = "return new Integer(sum);";
+		EvalualtionBreakpointListener.EXPRESSION = "return Integer.valueOf(sum);";
 		EvalualtionBreakpointListener.VOTE = IJavaBreakpointListener.SUSPEND;
 		EvalualtionBreakpointListener.RESULT = null;
 
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathContainerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathContainerTests.java
index 9825c81..e32a646 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathContainerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathContainerTests.java
@@ -41,7 +41,7 @@
  */
 public class ClasspathContainerTests extends AbstractDebugTest {
 
-	class FakeContainer implements IClasspathContainer {
+	static class FakeContainer implements IClasspathContainer {
 
 		IClasspathEntry[] entries = new IClasspathEntry[0];
 		/**
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/ExpressionEvalTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/ExpressionEvalTest.java
new file mode 100644
index 0000000..8a59db3
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/ExpressionEvalTest.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Gayan Perera 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:
+ *     Gayan Perera - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.eval;
+
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+
+public class ExpressionEvalTest extends AbstractDebugTest {
+	private IJavaThread javaThread;
+
+	public ExpressionEvalTest(String name) {
+		super(name);
+	}
+
+	@Override
+	protected IJavaProject getProjectContext() {
+		return get14Project();
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndInfix_ExtendedOperands() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false && !(false || false || false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndMixedInfix_ExtendedOperands() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false && !(false || false && false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndInfix() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false && !(false || false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithInfix() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "true && (false || false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false && false || true;");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not true", "true", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_NonShortCircuit() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false & false | true;");
+		// IValue value = doEval(javaThread, "!(false && false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not true", "true", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndInfix_NonShortCircuit() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false & !(false | false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndInfix_ExtendedOperands_NonShortCircuit() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false & !(false | false | false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithPrefixAndMixedInfix_ExtendedOperands_NonShortCircuit() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "false & !(false | false & false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	public void test547462_BooleanExpression_WithInfix_NonShortCircuit() throws Exception {
+		debugWithBreakpoint("EvalSimpleTests", 18);
+		IValue value = doEval(javaThread, "true & (false | false);");
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not false", "false", value.getValueString());
+	}
+
+	private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
+		createLineBreakpoint(lineNumber, testClass);
+		javaThread = launchToBreakpoint(testClass);
+		assertNotNull("The program did not suspend", javaThread);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		try {
+			terminateAndRemove(javaThread);
+		} finally {
+			super.tearDown();
+			removeAllBreakpoints();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEval17Test.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEval17Test.java
index 041a240..c4c32fe 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEval17Test.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/GenericsEval17Test.java
@@ -15,6 +15,7 @@
 
 import org.eclipse.debug.core.model.IValue;
 import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaObject;
 import org.eclipse.jdt.debug.core.IJavaThread;
 import org.eclipse.jdt.debug.tests.AbstractDebugTest;
 
@@ -39,6 +40,83 @@
 		assertEquals("value is not true", "true", value.getValueString());
 	}
 
+	public void testEvaluate_Bug572782_RecursiveGeneric_ExpectedEvalVarValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 15);
+		String snippet = "this";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertTrue("No a IJavaObjectValue", value instanceof IJavaObject);
+		assertEquals("value don't has the correct generic signature", "<T:LBug572782$Generic<LBug572782$ExtendedGeneric<TT;>;>;>Ljava/lang/Object;",
+				((IJavaObject) value).getGenericSignature());
+	}
+
+	public void testEvaluate_Bug572782_RecursiveGeneric_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 15);
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_RecursiveGenericSimple_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 22);
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_RecursiveNDeepGeneric_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 31);
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_InSideStaticMethod_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 41);
+		String snippet = "list.get(0)";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 1", "1", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_RecursiveNDeepGeneric_InSideStaticMethod_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 36);
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_InstanceMethodWithGenerics_ExpectedEvalExpressionValue() throws Exception {
+		debugWithBreakpoint("Bug572782", 45);
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
+	public void testEvaluate_Bug572782_FieldWithGenerics_ExpectedEvalExpressionValue() throws Exception {
+		createWatchpoint("Bug572782.NthGeneric", "items", false, true);
+		javaThread = launchToBreakpoint("Bug572782");
+		assertNotNull("The program did not suspend", javaThread);
+
+		String snippet = "1 + 2";
+		IValue value = doEval(javaThread, snippet);
+
+		assertNotNull("value is null", value);
+		assertEquals("value is not 3", "3", value.getValueString());
+	}
+
 	private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
 		createLineBreakpoint(lineNumber, testClass);
 		javaThread = launchToBreakpoint(testClass);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
index 53b5be3..a76989a 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java
@@ -15,6 +15,7 @@
 
 import org.eclipse.debug.core.model.IValue;
 import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.debug.core.IJavaThread;
 import org.eclipse.jdt.debug.tests.AbstractDebugTest;
 
@@ -145,6 +146,35 @@
 		assertEquals("Actual value is not true", "true", value.getValueString());
 	}
 
+	public void testEvaluate_Bug569413_NestedLambdaCapturedParameters() throws Exception {
+		debugWithBreakpoint("Bug569413", 23);
+
+		IValue pValue = doEval(javaThread, "p");
+		assertEquals("wrong type : ", "java.lang.String", pValue.getReferenceTypeName());
+		assertEquals("wrong result : ", "ab", pValue.getValueString());
+
+		IValue ppValue = doEval(javaThread, "pp");
+		assertEquals("wrong type : ", "Bug569413$TestClass", ppValue.getReferenceTypeName());
+
+		IValue pkgsVar = doEval(javaThread, "pkgs");
+		assertEquals("wrong type : ", "java.util.LinkedHashSet", Signature.getTypeErasure(pkgsVar.getReferenceTypeName()));
+		IValue pkgsValue = doEval(javaThread, "pkgs.toString()");
+		assertEquals("wrong result : ", "[ab, b, c]", pkgsValue.getValueString());
+
+		IValue thisBasePackages = doEval(javaThread, "this.basePackages");
+		assertEquals("wrong type : ", "java.util.HashMap", Signature.getTypeErasure(thisBasePackages.getReferenceTypeName()));
+		IValue thisBasePackagesSize = doEval(javaThread, "this.basePackages.size()");
+		assertEquals("wrong result : ", "0", thisBasePackagesSize.getValueString());
+	}
+
+	public void testEvaluate_Bug569413_NestedLambdaCapturedParameterAndNull() throws Exception {
+		debugWithBreakpoint("Bug569413", 29);
+
+		IValue value = doEval(javaThread, "p");
+		assertEquals("wrong type : ", "java.lang.String", value.getReferenceTypeName());
+		assertEquals("wrong result : ", "ab", value.getValueString());
+	}
+
 	private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception {
 		createLineBreakpoint(lineNumber, testClass);
 		javaThread = launchToBreakpoint(testClass);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfContextualLaunchMenu.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfContextualLaunchMenu.java
index 73ec5b7..6051bf5 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfContextualLaunchMenu.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfContextualLaunchMenu.java
@@ -81,7 +81,7 @@
         assertPerformance();
     }
 
-    private class BogusAction extends Action {
+    private static class BogusAction extends Action {
     }
 
     private class PerfTestContextualLaunchAction extends ContextualLaunchAction {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
index f81274f..037fc01 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
@@ -23,9 +23,11 @@
 import org.eclipse.debug.core.model.IBreakpoint;
 import org.eclipse.debug.core.model.ILineBreakpoint;
 import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
 import org.eclipse.jdi.internal.StringReferenceImpl;
 import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.debug.core.IJavaArray;
 import org.eclipse.jdt.debug.core.IJavaBreakpoint;
 import org.eclipse.jdt.debug.core.IJavaStackFrame;
 import org.eclipse.jdt.debug.core.IJavaThread;
@@ -282,6 +284,523 @@
 		}
 	}
 
+	public void testBug572629_ChainFieldHover_2Chains_ExpectValueFromChain() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 37;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "payload";
+			int offset = part.getViewer().getDocument().get().indexOf("other.payload") + "other.".length();
+			IRegion region = new Region(offset, "payload".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("other.payload", info.getName());
+			assertEquals("r", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ChainFieldHover_ArrayLengthChainsOnThisExpression_ExpectValueFromChain() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 37;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("this.payloads.length") + "this.payloads.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("this.payloads.length", info.getName());
+			assertEquals("1", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ChainFieldHover_ArrayLengthChainsOnVariableExpression_ExpectValueFromChain() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 37;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("other.payloads.length") + "other.payloads.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("other.payloads.length", info.getName());
+			assertEquals("1", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ChainFieldHover_ArrayLengthChainsOnVariableThisExpression_ExpectValueFromChain() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 37;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("this.payloads.length") + "this.payloads.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("this.payloads.length", info.getName());
+			assertEquals("1", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+	public void testBug572629_ChainFieldHover_3Chains_ExpectValueFromChainAtMiddle() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 37;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "payloads";
+			int offset = part.getViewer().getDocument().get().indexOf("other.payloads.length") + "other.".length();
+			IRegion region = new Region(offset, "payloads".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("other.payloads", info.getName());
+			assertTrue(info.getValue() instanceof IJavaArray);
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ChainFieldHover_ArrayLengthOnStaticField_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "equals";
+		final int frameNumber = 2;
+		final int bpLine = 36;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("PAYLOADS.length") + "PAYLOADS.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("PAYLOADS.length", info.getName());
+			assertEquals("1", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_LocalVariableHover_ArrayLength_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOverLocal";
+		final int frameNumber = 2;
+		final int bpLine = 44;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("name.length") + "name.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("name.length", info.getName());
+			assertEquals("4", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ParameterVariableHover_ArrayLength_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOverLocal";
+		final int frameNumber = 2;
+		final int bpLine = 46;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("names.length") + "names.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("names.length", info.getName());
+			assertEquals("1", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_ChainedLocalVariableHover_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOverLocal";
+		final int frameNumber = 2;
+		final int bpLine = 45;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "payload";
+			int offset = part.getViewer().getDocument().get().indexOf("object.payload") + "object.".length();
+			IRegion region = new Region(offset, "payload".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("object.payload", info.getName());
+			assertEquals("p", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug572629_LocalArrayVariableLengthHoverInSideLambda_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "lambda$0";
+		final int frameNumber = 6;
+		final int bpLine = 48;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "length";
+			int offset = part.getViewer().getDocument().get().indexOf("a.length") + "a.".length();
+			IRegion region = new Region(offset, "length".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("a.length", info.getName());
+			assertEquals("4", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug573553_ChainFieldHover_DeepChain_OnThisObjectPrimitive_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOnThis";
+		final int frameNumber = 2;
+		final int bpLine = 53;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "age";
+			int offset = part.getViewer().getDocument().get().indexOf("this.parent.child.age") + "this.parent.child.".length();
+			IRegion region = new Region(offset, "age".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("this.parent.child.age", info.getName());
+			assertEquals("5", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug573553_ChainFieldHover_DeepChain_OnThisObject_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOnThis";
+		final int frameNumber = 2;
+		final int bpLine = 54;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "name";
+			int offset = part.getViewer().getDocument().get().indexOf("this.parent.child.name") + "this.parent.child.".length();
+			IRegion region = new Region(offset, "name".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("this.parent.child.name", info.getName());
+			assertEquals("name", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug573553_ChainFieldHover_DeepChain_Primitive_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOnThis";
+		final int frameNumber = 2;
+		final int bpLine = 55;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "age";
+			int offset = part.getViewer().getDocument().get().lastIndexOf("parent.child.age") + "parent.child.".length();
+			IRegion region = new Region(offset, "age".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("parent.child.age", info.getName());
+			assertEquals("5", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
+	public void testBug573553_ChainFieldHover_DeepChain_Object_ExpectValue() throws Exception {
+		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+		final String typeName = "Bug572629";
+		final String expectedMethod = "hoverOnThis";
+		final int frameNumber = 2;
+		final int bpLine = 56;
+
+		IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+		bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+		IFile file = (IFile) bp.getMarker().getResource();
+		assertEquals(typeName + ".java", file.getName());
+
+		IJavaThread thread = null;
+		try {
+			thread = launchToBreakpoint(typeName);
+			CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+			JavaDebugHover hover = new JavaDebugHover();
+			hover.setEditor(part);
+
+			String variableName = "name";
+			int offset = part.getViewer().getDocument().get().lastIndexOf("parent.child.name") + "parent.child.".length();
+			IRegion region = new Region(offset, "name".length());
+			String text = selectAndReveal(part, bpLine, region);
+			assertEquals(variableName, text);
+			IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+			assertNotNull(info);
+			assertEquals("parent.child.name", info.getName());
+			assertEquals("name", info.getValue().getValueString());
+		} finally {
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
+
 	private CompilationUnitEditor openEditorAndValidateStack(final String expectedMethod, final int expectedFramesNumber, IFile file, IJavaThread thread) throws Exception, DebugException {
 		// Let now all pending jobs proceed, ignore console jobs
 		sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
index 23061d8..f7c06b8 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
@@ -31,7 +31,7 @@
  */
 public class DetailFormatterTests extends AbstractDebugTest {
 
-	class TestListener implements IValueDetailListener {
+	static class TestListener implements IValueDetailListener {
 		IValue value;
 		String result;
 
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestAnonymousInspect.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestAnonymousInspect.java
index 945266e..ef12010 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestAnonymousInspect.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestAnonymousInspect.java
@@ -32,7 +32,7 @@
 	static final String TYPE_NAME = "InspectTests";
 	static final String SNIPPET = "getchar()";
 
-	class Listener implements IEvaluationListener {
+	static class Listener implements IEvaluationListener {
 		IEvaluationResult fResult;
 
 		@Override
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestIntegerAccessUnboxing15.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestIntegerAccessUnboxing15.java
index 949e8b3..b5a66bc 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestIntegerAccessUnboxing15.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/TestIntegerAccessUnboxing15.java
@@ -108,7 +108,7 @@
 	 * @throws Exception
 	 */
 	public void testRowAccess() throws Exception {
-		doAccessTest("matrix[new Integer(0)][0]", 1);
+		doAccessTest("matrix[Integer.valueOf(0)][0]", 1);
 	}
 
 	/**
@@ -117,10 +117,10 @@
 	 * @throws Exception
 	 */
 	public void testColumnAccess() throws Exception {
-		doAccessTest("matrix[2][new Integer(2)]", 9);
+		doAccessTest("matrix[2][Integer.valueOf(2)]", 9);
 	}
 
 	public void testRowColumnAccess() throws Exception {
-		doAccessTest("matrix[1][new Integer(1)]", 5);
+		doAccessTest("matrix[1][Integer.valueOf(1)]", 5);
 	}
 }
diff --git a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/MethodBreakpoints.java b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/MethodBreakpoints.java
index bc55580..44bd93c 100644
--- a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/MethodBreakpoints.java
+++ b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/MethodBreakpoints.java
@@ -22,7 +22,7 @@
 		staticTypeParameter(new ArrayList<String>());
 		MethodBreakpoints<String> breakpoints = new MethodBreakpoints<String>();
 		breakpoints.typeParameter("Testing");
-		breakpoints.methodTypeParameter(new Integer(34));
+		breakpoints.methodTypeParameter(Integer.valueOf(34));
 	}
 	
 	public static <X> void staticTypeParameter(List<X> list) {
diff --git a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
index fccbda3..360128c 100644
--- a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
@@ -38,15 +38,15 @@
  org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.15.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
  org.eclipse.debug.ui;bundle-version="[3.13.400,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.15.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)",
- org.eclipse.jdt.ui;bundle-version="[3.17.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.19.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.22.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.console;bundle-version="[3.4.0,4.0.0)",
- org.eclipse.jdt.core.manipulation;bundle-version="[1.3.0,2.0.0)",
+ org.eclipse.jdt.core.manipulation;bundle-version="[1.14.0,2.0.0)",
  org.eclipse.search;bundle-version="[3.5.0,4.0.0)",
  com.ibm.icu,
  org.eclipse.ui.forms;bundle-version="[3.4.0,4.0.0)",
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
index 7580761..c4df4e9 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaClasspathTab.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.internal.debug.ui.actions.AddProjectAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AddVariableAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AttachSourceAction;
+import org.eclipse.jdt.internal.debug.ui.actions.CopyAction;
 import org.eclipse.jdt.internal.debug.ui.actions.EditClasspathEntryAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction;
@@ -181,6 +182,7 @@
 		createButton(pathButtonComp, new MoveUpAction(fClasspathViewer));
 		createButton(pathButtonComp, new MoveDownAction(fClasspathViewer));
 		createButton(pathButtonComp, new RemoveAction(fClasspathViewer));
+		createButton(pathButtonComp, new CopyAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddProjectAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddJarAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX));
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaConnectTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaConnectTab.java
index 374512a..5ac1c39 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaConnectTab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaConnectTab.java
@@ -241,7 +241,7 @@
 						editor.getPreferenceStore().setValue(key, value);
 					}
 					else if (arg instanceof Connector.BooleanArgument) {
-						editor.getPreferenceStore().setValue(key, Boolean.valueOf(value).booleanValue());
+						editor.getPreferenceStore().setValue(key, Boolean.parseBoolean(value));
 					}
 					else if (arg instanceof Connector.IntegerArgument) {
 						editor.getPreferenceStore().setValue(key, Integer.parseInt(value));
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
index c462d30..8e4f3ad 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaDependenciesTab.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2018 IBM Corporation and others.
+ * Copyright (c) 2018, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -38,6 +38,7 @@
 import org.eclipse.jdt.internal.debug.ui.actions.AddProjectAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AddVariableAction;
 import org.eclipse.jdt.internal.debug.ui.actions.AttachSourceAction;
+import org.eclipse.jdt.internal.debug.ui.actions.CopyAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction;
 import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction;
 import org.eclipse.jdt.internal.debug.ui.actions.OverrideDependenciesAction;
@@ -188,6 +189,7 @@
 		createButton(pathButtonComp, new MoveUpAction(fClasspathViewer));
 		createButton(pathButtonComp, new MoveDownAction(fClasspathViewer));
 		createButton(pathButtonComp, new RemoveAction(fClasspathViewer));
+		createButton(pathButtonComp, new CopyAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddProjectAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddJarAction(fClasspathViewer));
 		createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX));
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 abbb0fa..a79ec95 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
@@ -174,7 +174,7 @@
 
 	}
 
-	public class AttributesLabelProvider extends LabelProvider {
+	public static class AttributesLabelProvider extends LabelProvider {
 		@Override
 		public String getText(Object element) {
 			return ((String[])element)[0];
@@ -498,7 +498,7 @@
 			// recreate the attribute list
 			fValueTmp= fSnippetDocument.get();
 			createAttributeListWidgets();
-		} else if (isValue) {
+		} else {
 			// dispose the attribute list
 			saveAttributeValue();
 			for (Control child : fAttributesContainer.getChildren()) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
index 3008731..479649f 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIModelPresentation.java
@@ -714,7 +714,7 @@
 			}
 			if (item instanceof IMarker) {
 				IBreakpoint bp = getBreakpoint((IMarker)item);
-				if (bp != null && bp instanceof IJavaBreakpoint) {
+				if (bp instanceof IJavaBreakpoint) {
 					return getBreakpointImage((IJavaBreakpoint)bp);
 				}
 			}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
index dc6c0a8..88742e1 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
@@ -15,8 +15,14 @@
 package org.eclipse.jdt.internal.debug.ui;
 
 
+import java.util.Optional;
+import java.util.StringJoiner;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugEvent;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IVariable;
 import org.eclipse.debug.ui.DebugUITools;
@@ -27,6 +33,7 @@
 import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IInitializer;
 import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.ILocalVariable;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.ITypeRoot;
@@ -35,9 +42,11 @@
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jdt.core.dom.FieldAccess;
 import org.eclipse.jdt.core.dom.NodeFinder;
 import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
 import org.eclipse.jdt.core.dom.ThisExpression;
 import org.eclipse.jdt.core.manipulation.SharedASTProviderCore;
@@ -49,6 +58,9 @@
 import org.eclipse.jdt.debug.core.IJavaType;
 import org.eclipse.jdt.debug.core.IJavaValue;
 import org.eclipse.jdt.debug.core.IJavaVariable;
+import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
+import org.eclipse.jdt.debug.eval.IEvaluationListener;
+import org.eclipse.jdt.debug.eval.IEvaluationResult;
 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
 import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIPlaceholderVariable;
 import org.eclipse.jdt.internal.debug.eval.ast.engine.ASTEvaluationEngine;
@@ -284,20 +296,23 @@
 		        return resolveLocalVariable(frame, textViewer, hoverRegion);
 		    }
 
-            IJavaElement[] resolve = null;
-            try {
-                resolve = codeAssist.codeSelect(hoverRegion.getOffset(), 0);
-            } catch (JavaModelException e1) {
-                resolve = new IJavaElement[0];
-            }
-            try {
-            	for (int i = 0; i < resolve.length; i++) {
-            		IJavaElement javaElement = resolve[i];
-            		if (javaElement instanceof IField) {
-            		    IField field = (IField)javaElement;
-            		    IJavaVariable variable = null;
-            		    IJavaDebugTarget debugTarget = (IJavaDebugTarget)frame.getDebugTarget();
-            		    if (Flags.isStatic(field.getFlags())) {
+			IJavaElement[] resolve = resolveElement(hoverRegion.getOffset(), codeAssist);
+			try {
+				boolean onArrayLength = false;
+				if (resolve.length == 0 && isOverNameLength(hoverRegion, document)) {
+					// lets check if this is part of an array variable by jumping 2 chars backward from offset.
+					resolve = resolveElement(hoverRegion.getOffset() - 2, codeAssist);
+					onArrayLength = (resolve.length == 1) && isLocalOrMemberVariable(resolve[0])
+							&& isArrayTypeVariable(resolve[0]);
+				}
+
+				for (int i = 0; i < resolve.length; i++) {
+					IJavaElement javaElement = resolve[i];
+					if (javaElement instanceof IField) {
+						IField field = (IField) javaElement;
+						IJavaVariable variable = null;
+						IJavaDebugTarget debugTarget = (IJavaDebugTarget) frame.getDebugTarget();
+						if (Flags.isStatic(field.getFlags()) && !onArrayLength) {
 							IJavaType[] javaTypes = debugTarget.getJavaTypes(field.getDeclaringType().getFullyQualifiedName());
             		    	if (javaTypes != null) {
 	            		    	for (int j = 0; j < javaTypes.length; j++) {
@@ -346,36 +361,26 @@
             		    } else {
 							if (!frame.isStatic() && !frame.isNative()) {
             		    		// ensure that we only resolve a field access on 'this':
-            		    		if (!(codeAssist instanceof ITypeRoot)) {
+								if (!(codeAssist instanceof ITypeRoot)) {
 									return null;
 								}
-            		    		ITypeRoot typeRoot = (ITypeRoot) codeAssist;
-								ASTNode root = SharedASTProviderCore.getAST(typeRoot, SharedASTProviderCore.WAIT_NO, null);
-            		    		if (root == null) {
-									ASTParser parser = ASTParser.newParser(AST.JLS15);
-	            		    		parser.setSource(typeRoot);
-	            		    		parser.setFocalPosition(hoverRegion.getOffset());
-									root = parser.createAST(null);
-            		    		}
-            		    		ASTNode node = NodeFinder.perform(root, hoverRegion.getOffset(), hoverRegion.getLength());
-            		    		if (node == null) {
+								ITypeRoot typeRoot = (ITypeRoot) codeAssist;
+								ASTNode node = findNodeAtRegion(typeRoot, hoverRegion);
+								if (node == null) {
 									return null;
 								}
 								StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
 								if (locationInParent == FieldAccess.NAME_PROPERTY) {
 									FieldAccess fieldAccess = (FieldAccess) node.getParent();
-									if (!(fieldAccess.getExpression() instanceof ThisExpression)) {
-										return null;
+									if (fieldAccess.getExpression() instanceof ThisExpression) {
+										variable = evaluateField(frame, field);
+									} else {
+										variable = evaluateQualifiedNode(fieldAccess, frame, typeRoot.getJavaProject());
 									}
 								} else if (locationInParent == QualifiedName.NAME_PROPERTY) {
-									return null;
-								}
-
-            		    		String typeSignature = Signature.createTypeSignature(field.getDeclaringType().getFullyQualifiedName(), true);
-            		    		typeSignature = typeSignature.replace('.', '/');
-								IJavaObject ths = frame.getThis();
-								if (ths != null) {
-									variable = ths.getField(field.getElementName(), typeSignature);
+									variable = evaluateQualifiedNode(node.getParent(), frame, typeRoot.getJavaProject());
+								} else {
+									variable = evaluateField(frame, field);
 								}
             		    	}
             		    }
@@ -385,6 +390,19 @@
             			break;
             		}
             		if (javaElement instanceof ILocalVariable) {
+						// if we are on a array, regardless where we are send it to evaluation engine
+						if (onArrayLength) {
+							if (!(codeAssist instanceof ITypeRoot)) {
+								return null;
+							}
+							ITypeRoot typeRoot = (ITypeRoot) codeAssist;
+							ASTNode node = findNodeAtRegion(typeRoot, hoverRegion);
+							if (node == null) {
+								return null;
+							}
+							return evaluateQualifiedNode(node.getParent(), frame, typeRoot.getJavaProject());
+						}
+
             		    ILocalVariable var = (ILocalVariable)javaElement;
             		    IJavaElement parent = var.getParent();
 						while (!(parent instanceof IMethod) && !(parent instanceof IInitializer) && parent != null) {
@@ -456,6 +474,121 @@
 	    return null;
 	}
 
+	private ASTNode findNodeAtRegion(ITypeRoot typeRoot, IRegion hoverRegion) {
+		ASTNode root = SharedASTProviderCore.getAST(typeRoot, SharedASTProviderCore.WAIT_NO, null);
+		if (root == null) {
+			ASTParser parser = ASTParser.newParser(AST.JLS15);
+			parser.setSource(typeRoot);
+			parser.setFocalPosition(hoverRegion.getOffset());
+			root = parser.createAST(null);
+		}
+		return NodeFinder.perform(root, hoverRegion.getOffset(), hoverRegion.getLength());
+	}
+
+	private boolean isArrayTypeVariable(IJavaElement element) throws JavaModelException {
+		String signature;
+		if (element instanceof IField) {
+			signature = ((IField) element).getTypeSignature();
+		} else if (element instanceof ILocalVariable) {
+			signature = ((ILocalVariable) element).getTypeSignature();
+		} else {
+			signature = ""; //$NON-NLS-1$
+		}
+		return signature.startsWith("["); //$NON-NLS-1$
+	}
+
+	private boolean isLocalOrMemberVariable(IJavaElement element) {
+		return (element instanceof IField) || (element instanceof ILocalVariable);
+	}
+
+	private boolean isOverNameLength(IRegion hoverRegion, IDocument document) {
+		try {
+			return "length".equals(document.get(hoverRegion.getOffset(), hoverRegion.getLength())); //$NON-NLS-1$
+		} catch (BadLocationException e) {
+			return false;
+		}
+	}
+
+	private IJavaElement[] resolveElement(int offset, ICodeAssist codeAssist) {
+		IJavaElement[] resolve;
+		try {
+			resolve = codeAssist.codeSelect(offset, 0);
+		} catch (JavaModelException e1) {
+			resolve = new IJavaElement[0];
+		}
+		return resolve;
+	}
+
+	private IJavaVariable evaluateField(IJavaStackFrame frame, IField field) throws DebugException {
+		IJavaObject ths = frame.getThis();
+		if (ths != null) {
+			String typeSignature = Signature.createTypeSignature(field.getDeclaringType().getFullyQualifiedName(), true);
+			typeSignature = typeSignature.replace('.', '/');
+			return ths.getField(field.getElementName(), typeSignature);
+		}
+		return null;
+	}
+
+	private IJavaVariable evaluateQualifiedNode(ASTNode node, IJavaStackFrame frame, IJavaProject project) {
+		StringBuilder snippetBuilder = new StringBuilder();
+		if (node instanceof QualifiedName) {
+			snippetBuilder.append(((QualifiedName) node).getFullyQualifiedName());
+		} else if (node instanceof FieldAccess) {
+			StringJoiner segments = new StringJoiner("."); //$NON-NLS-1$
+			node.accept(new ASTVisitor() {
+				@Override
+				public boolean visit(SimpleName node) {
+					segments.add(node.getFullyQualifiedName());
+					return true;
+				}
+
+				@Override
+				public boolean visit(ThisExpression node) {
+					segments.add("this"); //$NON-NLS-1$
+					return true;
+				}
+
+			});
+			snippetBuilder.append(segments.toString());
+		} else {
+			return null;
+		}
+
+		final String snippet = snippetBuilder.toString();
+		class Evaluator implements IEvaluationListener {
+			private CompletableFuture<IEvaluationResult> result = new CompletableFuture<>();
+
+			@Override
+			public void evaluationComplete(IEvaluationResult result) {
+				this.result.complete(result);
+			}
+
+			public void run() throws DebugException {
+				IAstEvaluationEngine engine = JDIDebugPlugin.getDefault().getEvaluationEngine(project, (IJavaDebugTarget) frame.getDebugTarget());
+				engine.evaluate(snippet, frame, this, DebugEvent.EVALUATION, false);
+			}
+
+			public Optional<IEvaluationResult> getResult() {
+				try {
+					return Optional.ofNullable(result.get());
+				} catch (InterruptedException e) {
+					Thread.currentThread().interrupt();
+				} catch (ExecutionException e) {
+					JDIDebugUIPlugin.log(e);
+				}
+				return Optional.empty();
+			}
+		}
+		Evaluator evaluator = new Evaluator();
+		try {
+			evaluator.run();
+		} catch (DebugException e) {
+			JDIDebugUIPlugin.log(e);
+		}
+		return evaluator.getResult().flatMap(r -> Optional.ofNullable(r.getValue()))
+				.map(r -> new JDIPlaceholderVariable(snippet, r)).orElse(null);
+	}
+
 	public IInformationControlCreator getInformationPresenterControlCreator() {
 		return new ExpressionInformationControlCreator();
 	}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/MemberActionFilter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/MemberActionFilter.java
index 8e63317..7aeb4aa 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/MemberActionFilter.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/MemberActionFilter.java
@@ -95,7 +95,7 @@
 					IAdaptable adapt = DebugUITools.getDebugContext();
 					if(adapt != null) {
 						IDebugTarget adapter = adapt.getAdapter(IDebugTarget.class);
-						if(adapter != null && adapter instanceof IJavaDebugTarget) {
+						if(adapter instanceof IJavaDebugTarget) {
 							IJavaDebugTarget dtarget = (IJavaDebugTarget) adapter;
 							return dtarget.supportsInstanceRetrieval();
 						}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
index b566d0d..84b2af5 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -60,6 +60,7 @@
 	public static String JavaBreakpointPropertiesRulerAction_Breakpoint__Properties_1;
 	public static String MoveDownAction_M_ove_Down_1;
 	public static String MoveUpAction_Move_U_p_1;
+	public static String CopyAction_1;
 
 	public static String OpenFromClipboardAction_ElementToOpen;
 	public static String OpenFromClipboardAction_OpenFromClipboard;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
index 54228df..381f1cc 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ActionMessages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2018 IBM Corporation and others.
+# Copyright (c) 2000, 2021 IBM Corporation and others.
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -46,6 +46,7 @@
 MoveDownAction_M_ove_Down_1=&Down
 MoveUpAction_Move_U_p_1=U&p
 RemoveAction__Remove_1=Re&move
+CopyAction_1=&Copy
 
 AddProjectAction_Add_Project_1=Add Project&s...
 AddProjectAction_Project_Selection_2=Project Selection
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddFolderAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddFolderAction.java
index c45a163..4c133bc 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddFolderAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddFolderAction.java
@@ -53,7 +53,7 @@
 	 * @since 3.2
 	 *
 	 */
-	class FileFilter extends ViewerFilter {
+	static class FileFilter extends ViewerFilter {
 		@Override
 		public boolean select(Viewer viewer, Object parentElement, Object element) {
 			if(element instanceof IProject) {
@@ -130,7 +130,7 @@
 			IRuntimeClasspathEntry entry = iter.next();
 			if (entry.getType() == IRuntimeClasspathEntry.ARCHIVE) {
 				IResource res = entry.getResource();
-				if (res != null && res instanceof IContainer) {
+				if (res instanceof IContainer) {
 					folders.add(res);
 				}
 			}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddJarAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddJarAction.java
index bb22d1a..a9919c9 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddJarAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/AddJarAction.java
@@ -69,7 +69,7 @@
 			IRuntimeClasspathEntry entry = iter.next();
 			if (entry.getType() == IRuntimeClasspathEntry.ARCHIVE) {
 				IResource res = entry.getResource();
-				if (res != null && res instanceof IFile) {
+				if (res instanceof IFile) {
 					jars.add(res.getFullPath());
 				}
 			}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointHitCountAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointHitCountAction.java
index dfe9af6..7990e71 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointHitCountAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/BreakpointHitCountAction.java
@@ -134,7 +134,7 @@
 			@Override
 			public String isValid(String value) {
 				try {
-					hitCount= Integer.valueOf(value.trim()).intValue();
+					hitCount= Integer.parseInt(value.trim());
 				} catch (NumberFormatException nfe) {
 					hitCount= -1;
 				}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/CopyAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/CopyAction.java
new file mode 100644
index 0000000..ced27d9
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/CopyAction.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2021 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:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.actions;
+
+import org.eclipse.jdt.internal.debug.ui.classpath.RuntimeClasspathViewer;
+import org.eclipse.jdt.internal.debug.ui.launcher.IClasspathViewer;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+
+/**
+ * Moves selected entries in a runtime classpath viewer up one position.
+ */
+public class CopyAction extends RuntimeClasspathAction {
+	RuntimeClasspathViewer fClasspathViewer;
+
+	public CopyAction(IClasspathViewer viewer) {
+		super(ActionMessages.CopyAction_1, viewer);
+		fClasspathViewer = (RuntimeClasspathViewer) viewer;
+	}
+
+	@Override
+	public void run() {
+		String text = fClasspathViewer.getTreeViewer().getSelection().toString();
+		Clipboard cp = new Clipboard(null);
+		cp.setContents(new Object[] { text }, new Transfer[] { TextTransfer.getInstance() });
+		cp.dispose();
+	}
+
+	@Override
+	protected boolean updateSelection(IStructuredSelection selection) {
+		if (selection.isEmpty()) {
+			return false;
+		}
+		return getViewer().updateSelection(getActionType(), selection);
+	}
+
+	@Override
+	protected int getActionType() {
+		return COPY;
+	}
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenFromClipboardAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenFromClipboardAction.java
index aa3d273..b6e3e30 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenFromClipboardAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/OpenFromClipboardAction.java
@@ -311,7 +311,7 @@
 			typeName = s.substring(0, typeName.indexOf(".java")); //$NON-NLS-1$
 			String lineNumber = s.substring(index + 1, s.length());
 			lineNumber = lineNumber.trim();
-			int line = (Integer.valueOf(lineNumber)).intValue();
+			int line = Integer.parseInt(lineNumber);
 			getTypeMatches(typeName, matches);
 			return line;
 		}
@@ -326,7 +326,7 @@
 			typeName = typeName.trim();
 			String lineNumber = s.substring(index + 1, s.length());
 			lineNumber = lineNumber.trim();
-			int line = (Integer.valueOf(lineNumber)).intValue();
+			int line = Integer.parseInt(lineNumber);
 			getTypeMatches(typeName, matches);
 			return line;
 		}
@@ -336,7 +336,7 @@
 			String typeLine = s.substring(index1 + 1, index2).trim();
 			int index = typeLine.indexOf(':');
 			String lineNumber = typeLine.substring(index + 1, typeLine.length()).trim();
-			int line = (Integer.valueOf(lineNumber)).intValue();
+			int line = Integer.parseInt(lineNumber);
 
 			Pattern pattern = Pattern.compile(STACK_TRACE_QUALIFIED_LINE_PATTERN);
 			Matcher matcher = pattern.matcher(s);
@@ -361,7 +361,7 @@
 			String method = s.substring(0, index + 1);
 			index = s.indexOf(':');
 			String lineNumber = s.substring(index + 1).trim();
-			int line = (Integer.valueOf(lineNumber)).intValue();
+			int line = Integer.parseInt(lineNumber);
 			getMethodMatches(method, matches);
 			return line;
 		}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RuntimeClasspathAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RuntimeClasspathAction.java
index 733871d..ee61439 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RuntimeClasspathAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/RuntimeClasspathAction.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -37,6 +37,7 @@
 	public static final int ADD= 1;
 	public static final int REMOVE= 2;
 	public static final int MOVE= 3;
+	public static final int COPY = 4;
 
 	private IClasspathViewer fViewer;
 	private Button fButton;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/StepIntoSelectionUtils.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/StepIntoSelectionUtils.java
index f2792a4..c6abc56 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/StepIntoSelectionUtils.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/StepIntoSelectionUtils.java
@@ -83,7 +83,7 @@
      * @throws JavaModelException
      */
     public static IMethod getMethod(ITextSelection selection, IJavaElement element) throws JavaModelException {
-    	if(element != null && element instanceof ICodeAssist) {
+    	if(element instanceof ICodeAssist) {
     		return resolveMethod(selection.getOffset(), selection.getLength(), (ICodeAssist)element);
     	}
     	return null;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
index aab7a8f..19df4ce 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/classpath/RuntimeClasspathViewer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -337,6 +337,7 @@
 					return false;
 				}
 			case RuntimeClasspathAction.REMOVE :
+			case RuntimeClasspathAction.COPY:
 				selected= selection.iterator();
 				while (selected.hasNext()) {
 					IClasspathEntry entry = selected.next();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsPreferencePage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsPreferencePage.java
index 99f35a5..2edb8eb 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsPreferencePage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/JREsPreferencePage.java
@@ -34,6 +34,7 @@
 import org.eclipse.jdt.launching.IVMInstallType;
 import org.eclipse.jdt.launching.JavaRuntime;
 import org.eclipse.jdt.launching.LibraryLocation;
+import org.eclipse.jdt.launching.VMStandin;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.dialogs.IMessageProvider;
@@ -249,9 +250,12 @@
 			AbstractVMInstall install = (AbstractVMInstall) vm;
 			String vmver = install.getJavaVersion();
 			if(vmver == null) {
-				//if we cannot get a version from the VM we must return true, and let the runtime
-				//error sort it out
-				return true;
+				vmver = getVersionFromRealVM(vm);
+				if (vmver == null) {
+					//if we cannot get a version from the VM we must return true, and let the runtime
+					//error sort it out
+					return true;
+				}
 			}
 			int val = compliance.compareTo(vmver);
 			return  val < 0 || val == 0;
@@ -259,6 +263,21 @@
 		return false;
 	}
 
+
+	// If a JRE is newly added and selected without saving, convertToRealVM may not have been
+	// invoked and hence getJavaVersion would be null.
+	private String getVersionFromRealVM(IVMInstall vm) {
+		String vmver = null;
+		if (vm instanceof VMStandin) {
+			IVMInstall convertToRealVM = ((VMStandin) vm).convertToRealVM();
+			if(convertToRealVM instanceof AbstractVMInstall) {
+				vmver = ((AbstractVMInstall) convertToRealVM).getJavaVersion();
+				((VMStandin) vm).getVMInstallType().disposeVMInstall(vm.getId());
+			}
+		}
+		return vmver;
+	}
+
 	/* (non-Javadoc)
 	 * @see org.eclipse.jface.preference.IPreferencePage#performOk()
 	 */
diff --git a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
index 925041e..4091cb6 100644
--- a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
@@ -27,7 +27,7 @@
  org.eclipse.jdt.internal.debug.eval.ast.instructions;x-friends:="org.eclipse.jdt.debug.ui"
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.14.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.22.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)"
 Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
index 35e5d92..231127e 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
@@ -2861,7 +2861,12 @@
 			storeInstruction();
 
 			// store the no-op
-			storeInstruction();
+			// since we add no-op for number of operators (there will be more than one when we have extendedOperands),
+			// we need to store them as well to make sure the next expression such as PrefixExpressions can properly
+			// store the instruction in correct place.
+			for (int i = 0; i < operatorNumber; i++) {
+				storeInstruction();
+			}
 
 		} else { // other operators
 
@@ -3282,13 +3287,13 @@
 		token = removePrefixZerosAndUnderscores(token, false);
 		switch (getBase(token)) {
 		case 8:
-			return Integer.valueOf(token.substring(1), 8).intValue();
+			return Integer.parseInt(token.substring(1), 8);
 		case 16:
-			return Integer.valueOf(token.substring(2), 16).intValue();
+			return Integer.parseInt(token.substring(2), 16);
 		case 2:
-			return Integer.valueOf(token.substring(2), 2).intValue();
+			return Integer.parseInt(token.substring(2), 2);
 		default:
-			return Integer.valueOf(token, 10).intValue();
+			return Integer.parseInt(token, 10);
 		}
 	}
 
@@ -3304,13 +3309,13 @@
 		token = removePrefixZerosAndUnderscores(token, false);
 		switch (getBase(token)) {
 		case 8:
-			return Short.valueOf(token.substring(1), 8).shortValue();
+			return Short.parseShort(token.substring(1), 8);
 		case 16:
-			return Short.valueOf(token.substring(2), 16).shortValue();
+			return Short.parseShort(token.substring(2), 16);
 		case 2:
-			return Short.valueOf(token.substring(2), 2).shortValue();
+			return Short.parseShort(token.substring(2), 2);
 		default:
-			return Short.valueOf(token, 10).shortValue();
+			return Short.parseShort(token, 10);
 		}
 	}
 
@@ -3326,13 +3331,13 @@
 		token = removePrefixZerosAndUnderscores(token, false);
 		switch (getBase(token)) {
 		case 8:
-			return Byte.valueOf(token.substring(1), 8).byteValue();
+			return Byte.parseByte(token.substring(1), 8);
 		case 16:
-			return Byte.valueOf(token.substring(2), 16).byteValue();
+			return Byte.parseByte(token.substring(2), 16);
 		case 2:
-			return Byte.valueOf(token.substring(2), 2).byteValue();
+			return Byte.parseByte(token.substring(2), 2);
 		default:
-			return Byte.valueOf(token, 10).byteValue();
+			return Byte.parseByte(token, 10);
 		}
 	}
 
@@ -3348,13 +3353,13 @@
 		token = removePrefixZerosAndUnderscores(token, true);
 		switch (getBase(token)) {
 		case 8:
-			return Long.valueOf(token.substring(1), 8).longValue();
+			return Long.parseLong(token.substring(1), 8);
 		case 16:
-			return Long.valueOf(token.substring(2), 16).longValue();
+			return Long.parseLong(token.substring(2), 16);
 		case 2:
-			return Long.valueOf(token.substring(2), 2).longValue();
+			return Long.parseLong(token.substring(2), 2);
 		default:
-			return Long.valueOf(token, 10).longValue();
+			return Long.parseLong(token, 10);
 		}
 	}
 
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/BinaryBasedSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/BinaryBasedSourceGenerator.java
index b6d42fe..adf6053 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/BinaryBasedSourceGenerator.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/BinaryBasedSourceGenerator.java
@@ -70,10 +70,10 @@
 		} else {
 			num = sourceLevel;
 		}
-		fSourceMajorLevel = Integer.valueOf(num).intValue();
+		fSourceMajorLevel = Integer.parseInt(num);
 		if (index != -1) {
 			num = sourceLevel.substring(index + 1);
-			fSourceMinorLevel = Integer.valueOf(num).intValue();
+			fSourceMinorLevel = Integer.parseInt(num);
 		} else {
 			fSourceMinorLevel = 0;
 		}
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
index 4b89662..6dae414 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java
@@ -21,6 +21,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Stack;
 
 import org.eclipse.jdt.core.Flags;
@@ -162,9 +163,16 @@
 
 	private Stack<Map<String, String>> fTypeParameterStack = new Stack<>();
 	private Map<String, String> fMatchingTypeParameters = null;
+
+	private enum TypeParameterLocation {
+		TYPE, METHOD, EMPTY;
+	}
+
+	private Stack<TypeParameterLocation> fTypeParameterTypeStack = new Stack<>();
 	private CompilationUnit fCompilationUnit;
 	{
 		fTypeParameterStack.push(Collections.<String,String>emptyMap());
+		fTypeParameterTypeStack.push(TypeParameterLocation.EMPTY);
 	}
 
 	/**
@@ -204,10 +212,10 @@
 		} else {
 			num = sourceLevel;
 		}
-		fSourceMajorLevel = Integer.valueOf(num).intValue();
+		fSourceMajorLevel = Integer.parseInt(num);
 		if (index != -1) {
 			num = sourceLevel.substring(index + 1);
-			fSourceMinorLevel = Integer.valueOf(num).intValue();
+			fSourceMinorLevel = Integer.parseInt(num);
 		} else {
 			fSourceMinorLevel = 0;
 		}
@@ -309,7 +317,9 @@
 	 */
 	void adddTypeParameters(StringBuilder buffer) {
 		if (isSourceLevelGreaterOrEqual(1, 5)) {
-			Collection<String> activeTypeParameters = (fMatchingTypeParameters != null ? fMatchingTypeParameters : fTypeParameterStack.peek()).values();
+			Collection<String> activeTypeParameters = Optional.ofNullable(fMatchingTypeParameters)
+					.map(Map::values).orElse(Collections.emptyList());
+
 			if (!activeTypeParameters.isEmpty()) {
 				Iterator<String> iterator = activeTypeParameters.iterator();
 				buffer.append(Signature.C_GENERIC_START);
@@ -1073,6 +1083,7 @@
 	@Override
 	public void endVisit(MethodDeclaration node) {
 		fTypeParameterStack.pop();
+		fTypeParameterTypeStack.pop();
 	}
 
 	/**
@@ -1083,6 +1094,7 @@
 
 		if (hasError()) {
 			fTypeParameterStack.pop();
+			fTypeParameterTypeStack.pop();
 			return;
 		}
 
@@ -1096,6 +1108,7 @@
 		if (!fEvaluateNextEndTypeDeclaration) {
 			fEvaluateNextEndTypeDeclaration = true;
 			fTypeParameterStack.pop();
+			fTypeParameterTypeStack.pop();
 			return;
 		}
 
@@ -1130,6 +1143,7 @@
 			}
 		}
 		fTypeParameterStack.pop();
+		fTypeParameterTypeStack.pop();
 	}
 
 	/*
@@ -1607,8 +1621,9 @@
 		int lastLine = fCompilationUnit.getLineNumber(node.getStartPosition() + node.getLength());
 
 		List<TypeParameter> typeParameters = node.typeParameters();
-		pushTypeParameters(typeParameters);
-		if (isRightType(node.getParent()) && firstLine <= fLine && fLine <= lastLine) {
+		pushTypeParameters(typeParameters, TypeParameterLocation.METHOD);
+		if (isRightType(node.getParent()) && firstLine <= fLine && fLine <= lastLine
+				&& fTypeParameterTypeStack.peek() == TypeParameterLocation.METHOD) {
 				fMatchingTypeParameters  = fTypeParameterStack.peek();
 		}
 		if (rightTypeFound()) {
@@ -1617,7 +1632,7 @@
 		return true;
 	}
 
-	private void pushTypeParameters(List<TypeParameter> typeParameters) {
+	private void pushTypeParameters(List<TypeParameter> typeParameters, TypeParameterLocation location) {
 		if (!typeParameters.isEmpty()) {
 			HashMap<String,String> newTypeParameters = new HashMap<>(fTypeParameterStack.peek());
 			Iterator<TypeParameter> iterator = typeParameters.iterator();
@@ -1627,8 +1642,10 @@
 				newTypeParameters.put(boundName, typeParameter.toString());
 			}
 			fTypeParameterStack.push(newTypeParameters); // Push the new "scope"
+			fTypeParameterTypeStack.push(location);
 		} else {
 			fTypeParameterStack.push(fTypeParameterStack.peek()); // Push the same
+			fTypeParameterTypeStack.push(fTypeParameterTypeStack.peek());
 		}
 	}
 
@@ -2019,7 +2036,7 @@
 	@Override
 	public boolean visit(TypeDeclaration node) {
 		List<TypeParameter> typeParameters = node.typeParameters();
-		pushTypeParameters(typeParameters);
+		pushTypeParameters(typeParameters, TypeParameterLocation.TYPE);
 		if (rightTypeFound()) {
 			fEvaluateNextEndTypeDeclaration = false;
 			return false;
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ObjectReferenceImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ObjectReferenceImpl.java
index 936b268..e3a0e3b 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ObjectReferenceImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ObjectReferenceImpl.java
@@ -125,7 +125,7 @@
 	/**
 	 * Inner class used to return monitor info.
 	 */
-	private class MonitorInfo {
+	private static class MonitorInfo {
 		ThreadReferenceImpl owner;
 		int entryCount;
 		ArrayList<ThreadReference> waiters;
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadGroupReferenceImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadGroupReferenceImpl.java
index 49fc4ae..aa5927d 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadGroupReferenceImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadGroupReferenceImpl.java
@@ -140,7 +140,7 @@
 	/**
 	 * Inner class used to return children info.
 	 */
-	private class ChildrenInfo {
+	private static class ChildrenInfo {
 		List<ThreadReference> childThreads;
 		List<ThreadGroupReference> childThreadGroups;
 	}
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java
index 0ca6cc3..02dcd0b 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineManagerImpl.java
@@ -120,8 +120,7 @@
 			PropertyResourceBundle prefs = new PropertyResourceBundle(stream);
 
 			try {
-				fVerbose = Boolean
-						.valueOf(prefs.getString("User.verbose")).booleanValue(); //$NON-NLS-1$
+				fVerbose = Boolean.parseBoolean(prefs.getString("User.verbose")); //$NON-NLS-1$
 			} catch (MissingResourceException e) {
 			}
 
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectorImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectorImpl.java
index 8a720d9..c751793 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectorImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectorImpl.java
@@ -111,7 +111,7 @@
 	/**
 	 * Argument class for arguments that are used to establish a connection.
 	 */
-	public abstract class ArgumentImpl implements
+	public abstract static class ArgumentImpl implements
 			com.sun.jdi.connect.Connector.Argument {
 		/**
 		 * Serial version id.
@@ -185,7 +185,7 @@
 		public abstract String toString();
 	}
 
-	public class StringArgumentImpl extends ArgumentImpl implements StringArgument {
+	public static class StringArgumentImpl extends ArgumentImpl implements StringArgument {
 		private static final long serialVersionUID = 6009335074727417445L;
 
 		private String fValue;
@@ -217,7 +217,7 @@
 
 	}
 
-	public class IntegerArgumentImpl extends ArgumentImpl implements IntegerArgument {
+	public static class IntegerArgumentImpl extends ArgumentImpl implements IntegerArgument {
 		private static final long serialVersionUID = 6009335074727417445L;
 		private Integer fValue;
 		private int fMin;
@@ -305,7 +305,7 @@
 		}
 	}
 
-	public class BooleanArgumentImpl extends ArgumentImpl implements BooleanArgument {
+	public static class BooleanArgumentImpl extends ArgumentImpl implements BooleanArgument {
 		private static final long serialVersionUID = 6009335074727417445L;
 		private Boolean fValue;
 
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
index c6aa9e3..02caffe 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketTransportService.java
@@ -59,7 +59,7 @@
 		}
 	};
 
-	private class SocketListenKey extends ListenKey {
+	private static class SocketListenKey extends ListenKey {
 		private String fAddress;
 
 		SocketListenKey(String address) {
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java
index cd3c6e0..c50d2fb 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java
@@ -796,7 +796,7 @@
 		return fModifierKindMap;
 	}
 
-	class ExceptionFilter {
+	static class ExceptionFilter {
 		/**
 		 * If non-null, specifies that exceptions which are instances of
 		 * fExceptionFilterRef will be reported.
@@ -808,7 +808,7 @@
 		boolean fNotifyUncaught = false;
 	}
 
-	class ThreadStepFilter {
+	static class ThreadStepFilter {
 		/** ThreadReference of thread in which to step. */
 		protected ThreadReferenceImpl fThread = null;
 		/** Size of each step. */
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpCommandPacket.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpCommandPacket.java
index f6bad5a..79539ba 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpCommandPacket.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpCommandPacket.java
@@ -266,7 +266,7 @@
 					continue;
 				}
 				int value = field.getInt(null);
-				setNames.put(new Integer(value), removePrefix(name));
+				setNames.put(Integer.valueOf(value), removePrefix(name));
 			} catch (IllegalAccessException e) {
 				// Will not occur for own class.
 			} catch (IllegalArgumentException e) {
@@ -295,7 +295,7 @@
 				Integer val = (Integer) field.get(null);
 				int value = val.intValue();
 				int set = value >>> 8;
-				String setName = setNames.get(new Integer(set));
+				String setName = setNames.get(Integer.valueOf(set));
 				String entryName = setName + " - " + removePrefix(name); //$NON-NLS-1$
 
 				fgCommandMap.put(val, entryName);
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpReplyPacket.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpReplyPacket.java
index 35e2f18..bbcecbd 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpReplyPacket.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/JdwpReplyPacket.java
@@ -148,7 +148,7 @@
 				continue;
 
 			try {
-				Integer intValue = new Integer(field.getInt(null));
+				Integer intValue = Integer.valueOf(field.getInt(null));
 				fErrorMap.put(intValue, field.getName());
 			} catch (IllegalAccessException e) {
 				// Will not occur for own class.
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructure.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructure.java
index 41f8c2f..12655f7 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructure.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructure.java
@@ -224,8 +224,7 @@
 					JDIDebugPlugin.getUniqueIdentifier(), JDIDebugPlugin.ERROR,
 					LogicalStructuresMessages.JavaLogicalStructures_0, null));
 		}
-		fSubtypes = Boolean.valueOf(
-				configurationElement.getAttribute("subtypes")).booleanValue(); //$NON-NLS-1$
+		fSubtypes = Boolean.parseBoolean(configurationElement.getAttribute("subtypes")); //$NON-NLS-1$
 		fValue = configurationElement.getAttribute("value"); //$NON-NLS-1$
 		fDescription = configurationElement.getAttribute("description"); //$NON-NLS-1$
 		if (fDescription == null) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIModificationVariable.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIModificationVariable.java
index fe500fc..87230b1 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIModificationVariable.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIModificationVariable.java
@@ -70,13 +70,12 @@
 				String flse = Boolean.FALSE.toString();
 				String tre = Boolean.TRUE.toString();
 				if (expression.equals(tre) || expression.equals(flse)) {
-					boolean booleanValue = Boolean.valueOf(expression)
-							.booleanValue();
+					boolean booleanValue = Boolean.parseBoolean(expression);
 					vmValue = vm.mirrorOf(booleanValue);
 				}
 				break;
 			case 'B':
-				byte byteValue = Byte.valueOf(expression).byteValue();
+				byte byteValue = Byte.parseByte(expression);
 				vmValue = vm.mirrorOf(byteValue);
 				break;
 			case 'C':
@@ -120,23 +119,23 @@
 				}
 				break;
 			case 'S':
-				short shortValue = Short.valueOf(expression).shortValue();
+				short shortValue = Short.parseShort(expression);
 				vmValue = vm.mirrorOf(shortValue);
 				break;
 			case 'I':
-				int intValue = Integer.valueOf(expression).intValue();
+				int intValue = Integer.parseInt(expression);
 				vmValue = vm.mirrorOf(intValue);
 				break;
 			case 'J':
-				long longValue = Long.valueOf(expression).longValue();
+				long longValue = Long.parseLong(expression);
 				vmValue = vm.mirrorOf(longValue);
 				break;
 			case 'F':
-				float floatValue = Float.valueOf(expression).floatValue();
+				float floatValue = Float.parseFloat(expression);
 				vmValue = vm.mirrorOf(floatValue);
 				break;
 			case 'D':
-				double doubleValue = Double.valueOf(expression).doubleValue();
+				double doubleValue = Double.parseDouble(expression);
 				vmValue = vm.mirrorOf(doubleValue);
 				break;
 			case 'L':
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 7dff265..fba88a9 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
@@ -497,14 +497,14 @@
 				if (synVars.length + 1 == allFields.size()) {
 					while (listIterator.hasNext()) {
 						FieldImpl field = (FieldImpl) listIterator.next();
-						String newName = field.name();
+						// remove 'this' field from the fields of the lambda
 						if (i == 0) {
-							newName = "this"; //$NON-NLS-1$
+							listIterator.remove();
 						} else {
-							newName = synVars[i - 1].getName();
+							String newName = synVars[i - 1].getName();
+							FieldImpl newField = createRenamedCopy(field, newName);
+							listIterator.set(newField);
 						}
-						FieldImpl newField = createRenamedCopy(field, newName);
-						listIterator.set(newField);
 						i++;
 					}
 				}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
index e495b02..c384253 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java
@@ -3739,7 +3739,7 @@
 	 *
 	 * @since 3.3.0
 	 */
-	class SerialPerObjectRule implements ISchedulingRule {
+	static class SerialPerObjectRule implements ISchedulingRule {
 
 		private Object fObject = null;
 
diff --git a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
index 6a82271..f6d0b4f 100644
--- a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
@@ -7,10 +7,10 @@
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)"
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.19.0,4.0.0)"
 Eclipse-LazyStart: true
 Eclipse-PlatformFilter: (osgi.os=macosx)
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF
index 4d3c710..a5d271e 100644
--- a/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF
@@ -10,7 +10,7 @@
 Require-Bundle: org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
  org.eclipse.jface;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui;bundle-version="[3.5.0,4.0.0)"
 Bundle-Activator: org.eclipse.jdt.internal.ui.macbundler.MacOSXUILaunchingPlugin
diff --git a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
index 2891fb5..f1c428d 100644
--- a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
@@ -15,7 +15,7 @@
  org.eclipse.jdt.launching.sourcelookup.advanced,
  org.eclipse.jdt.launching.sourcelookup.containers
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.14.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.24.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.26.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.17.0,4.0.0)",
  org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)",
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/CompositeId.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/CompositeId.java
index e5f30f4..f56d1b1 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/CompositeId.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/CompositeId.java
@@ -29,7 +29,7 @@
 		ArrayList<String> parts= new ArrayList<>();
 		int commaIndex= idString.indexOf(',');
 		while (commaIndex > 0) {
-			int length= Integer.valueOf(idString.substring(0, commaIndex)).intValue();
+			int length= Integer.parseInt(idString.substring(0, commaIndex));
 			String part= idString.substring(commaIndex+1, commaIndex+1+length);
 			parts.add(part);
 			idString= idString.substring(commaIndex+1+length);
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
index c5d9d43..d2b45ab 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/DefaultProjectClasspathEntry.java
@@ -91,7 +91,7 @@
 		setJavaProject(project);
 		name = memento.getAttribute("exportedEntriesOnly"); //$NON-NLS-1$
 		if (name != null) {
-			fExportedEntriesOnly = Boolean.valueOf(name).booleanValue();
+			fExportedEntriesOnly = Boolean.parseBoolean(name);
 		}
 	}
 	/* (non-Javadoc)
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/PackageFragmentRootSourceContainerTypeDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/PackageFragmentRootSourceContainerTypeDelegate.java
index 666b987..1a05695 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/PackageFragmentRootSourceContainerTypeDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/PackageFragmentRootSourceContainerTypeDelegate.java
@@ -45,7 +45,7 @@
 					abort(LaunchingMessages.PackageFragmentRootSourceContainerTypeDelegate_6, null);
 				}
 				IJavaElement root = JavaCore.create(string);
-				if (root != null && root instanceof IPackageFragmentRoot) {
+				if (root instanceof IPackageFragmentRoot) {
 					return new PackageFragmentRootSourceContainer((IPackageFragmentRoot)root);
 				}
 				abort(LaunchingMessages.PackageFragmentRootSourceContainerTypeDelegate_7, null);
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
index 0f89647..872f463 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMRunner.java
@@ -345,7 +345,7 @@
 		return vmargs;
 	}
 
-	protected class CommandDetails {
+	protected static class CommandDetails {
 		private String[] commandLine;
 		private String[] envp;
 		private File workingDir;