Merge master

Change-Id: I19b5b053fb5871ac6762110a4a945fbc5e65b7a7
diff --git a/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java b/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java
index e60580b..7adcb30 100644
--- a/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java
+++ b/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java
@@ -736,7 +736,7 @@
 	private void launchSunTarget() {
 		try {
 			// Launch target VM
-			StringBuffer binDirectory= new StringBuffer();
+			StringBuilder binDirectory= new StringBuilder();
 			if (fTargetAddress.endsWith("jre")) {
 				binDirectory.append(fTargetAddress.substring(0, fTargetAddress.length() - 4));
 			} else {
diff --git a/org.eclipse.jdt.debug.tests/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.debug.tests/.settings/org.eclipse.jdt.core.prefs
index 8bbf89e..7b96560 100644
--- a/org.eclipse.jdt.debug.tests/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.debug.tests/.settings/org.eclipse.jdt.core.prefs
@@ -11,9 +11,12 @@
 org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled

 org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore

 org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull

+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=

 org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault

+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=

 org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled

 org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable

+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=

 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled

 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled

 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate

@@ -25,6 +28,7 @@
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate

 org.eclipse.jdt.core.compiler.doc.comment.support=enabled

 org.eclipse.jdt.core.compiler.maxProblemPerUnit=100

+org.eclipse.jdt.core.compiler.problem.APILeak=warning

 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning

 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error

 org.eclipse.jdt.core.compiler.problem.autoboxing=ignore

@@ -75,6 +79,7 @@
 org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning

 org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore

 org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning

+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning

 org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error

 org.eclipse.jdt.core.compiler.problem.nullReference=error

 org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning

@@ -82,6 +87,7 @@
 org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning

 org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning

 org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore

+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning

 org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning

 org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore

 org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error

@@ -89,7 +95,7 @@
 org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning

 org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning

 org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore

-org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning

+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=error

 org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore

 org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore

 org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore

@@ -99,12 +105,16 @@
 org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled

 org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled

 org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore

+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning

 org.eclipse.jdt.core.compiler.problem.typeParameterHiding=ignore

 org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled

 org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=error

 org.eclipse.jdt.core.compiler.problem.unclosedCloseable=ignore

 org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore

 org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=error

+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning

+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled

+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info

 org.eclipse.jdt.core.compiler.problem.unnecessaryElse=error

 org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error

 org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore

diff --git a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
index f3fc911..c69a798 100644
--- a/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug.tests; singleton:=true
-Bundle-Version: 3.11.100.qualifier
+Bundle-Version: 3.11.200.qualifier
 Bundle-ClassPath: javadebugtests.jar
 Bundle-Activator: org.eclipse.jdt.debug.testplugin.JavaTestPlugin
 Bundle-Vendor: %providerName
@@ -37,12 +37,12 @@
  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.8.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.6.100,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.7.100,4.0.0)",
- org.eclipse.jdt.debug.ui;bundle-version="[3.6.100,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.6.0,4.0.0)",
- org.eclipse.debug.ui;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.15.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.debug.core;bundle-version="[3.12.0,4.0.0)",
+ org.eclipse.debug.ui;bundle-version="[3.13.0,4.0.0)",
  org.eclipse.core.runtime,
  org.eclipse.ui.console,
  org.eclipse.test.performance,
diff --git a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
index a9bfee7..1c9980b 100644
--- a/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
+++ b/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java
@@ -103,7 +103,7 @@
 	private String[] linkTextsAtPositions(int... offsets) throws BadLocationException {
 		IDocument document = fConsole.getDocument();
 
-		List<String> texts = new ArrayList<String>(offsets.length);
+		List<String> texts = new ArrayList<>(offsets.length);
 		List<Position> positions = linkPositions(offsets);
 		for (Position pos : positions) {
 			String matchText = document.get(pos.getOffset(), pos.getLength());
@@ -113,7 +113,7 @@
 	}
 
 	private List<Position> linkPositions(int... offsets) {
-		List<Position> filteredPositions = new ArrayList<Position>(offsets.length);
+		List<Position> filteredPositions = new ArrayList<>(offsets.length);
 		for (Position position : allLinkPositions()) {
 			for (int offset : offsets) {
 				if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
diff --git a/org.eclipse.jdt.debug.tests/java8/LongClasspath.java b/org.eclipse.jdt.debug.tests/java8/LongClasspath.java
new file mode 100644
index 0000000..0b196af
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/java8/LongClasspath.java
@@ -0,0 +1,7 @@
+public class LongClasspath {
+
+    public static void main(String[] args) {
+    	System.out.println("Hello");
+    }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/pom.xml b/org.eclipse.jdt.debug.tests/pom.xml
index d439a32..6dcf809 100644
--- a/org.eclipse.jdt.debug.tests/pom.xml
+++ b/org.eclipse.jdt.debug.tests/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.debug.tests</artifactId>
-  <version>3.11.100-SNAPSHOT</version>
+  <version>3.11.200-SNAPSHOT</version>
   <packaging>eclipse-test-plugin</packaging>
   <properties>
     <code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/EvalualtionBreakpointListener.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/EvalualtionBreakpointListener.java
index 1eefbec..405d433 100644
--- a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/EvalualtionBreakpointListener.java
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/EvalualtionBreakpointListener.java
@@ -71,7 +71,7 @@
 	/**
 	 * List of breakpoints with compilation errors
 	 */
-	public static List<IJavaLineBreakpoint> COMPILATION_ERRORS = new ArrayList<IJavaLineBreakpoint>();
+	public static List<IJavaLineBreakpoint> COMPILATION_ERRORS = new ArrayList<>();
 
 	/**
 	 * Lock used to notify when a notification is received.
@@ -81,7 +81,7 @@
 	/**
 	 * List of breakpoints with runtime errors
 	 */
-	public static List<IJavaLineBreakpoint> RUNTIME_ERRORS = new ArrayList<IJavaLineBreakpoint>();
+	public static List<IJavaLineBreakpoint> RUNTIME_ERRORS = new ArrayList<>();
 
 	public static void reset() {
 		VOTE = IJavaBreakpointListener.DONT_CARE;
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaAlernateModeTab.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaAlernateModeTab.java
index 49a4b93..de0c4f3 100644
--- a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaAlernateModeTab.java
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaAlernateModeTab.java
@@ -39,7 +39,7 @@
 	 * @return the set of modes this tab supports
 	 */
 	public Set<String> getModes() {
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add("alternate");
 		return modes;
 	}
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java
index 5ce5fac..ca6728e 100644
--- a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java
@@ -59,6 +59,7 @@
 	public static final String JAVA_SE_1_6_EE_NAME = "JavaSE-1.6";
 	public static final String JAVA_SE_1_7_EE_NAME = "JavaSE-1.7";
 	public static final String JAVA_SE_1_8_EE_NAME = "JavaSE-1.8";
+	public static final String JAVA_SE_9_EE_NAME = "JavaSE-9";
 
 	/**
 	 * path to the test src for 'testprograms'
@@ -466,7 +467,7 @@
 	public static void removeFromClasspath(IJavaProject jproject, IPath path) throws JavaModelException {
 		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
 		int nEntries= oldEntries.length;
-		ArrayList<IClasspathEntry> list= new ArrayList<IClasspathEntry>(nEntries);
+		ArrayList<IClasspathEntry> list= new ArrayList<>(nEntries);
 		for (int i= 0 ; i < nEntries ; i++) {
 			IClasspathEntry curr= oldEntries[i];
 			if (!path.equals(curr.getPath())) {
@@ -485,7 +486,7 @@
 	 */
 	public static void addToClasspath(IJavaProject jproject, IClasspathEntry cpe) throws JavaModelException {
 		IClasspathEntry[] oldEntries= jproject.getRawClasspath();
-		ArrayList<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(oldEntries.length);
+		ArrayList<IClasspathEntry> entries = new ArrayList<>(oldEntries.length);
 		for (int i= 0; i < oldEntries.length; i++) {
 			if (oldEntries[i].equals(cpe)) {
 				return;
@@ -570,7 +571,7 @@
 	 */
 	public static void importFile(File file, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException {
 		IImportStructureProvider structureProvider = FileSystemStructureProvider.INSTANCE;
-		List<File> files = new ArrayList<File>(1);
+		List<File> files = new ArrayList<>(1);
 		files.add(file);
 		try {
 			ImportOperation op= new ImportOperation(destPath, file.getParentFile(), structureProvider, new ImportOverwriteQuery(), files);
@@ -590,7 +591,7 @@
 	private static void addJavaFiles(File dir, List<File> collection) throws IOException {
 		File[] files = dir.listFiles();
 		if(files != null) {
-			List<File> subDirs = new ArrayList<File>(2);
+			List<File> subDirs = new ArrayList<>(2);
 			for (int i = 0; i < files.length; i++) {
 				if (files[i].isFile()) {
 					collection.add(files[i]);
diff --git a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TestDetailPaneFactory.java b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TestDetailPaneFactory.java
index 3aadb80..eca3553 100644
--- a/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TestDetailPaneFactory.java
+++ b/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/detailpane/TestDetailPaneFactory.java
@@ -50,7 +50,7 @@
 	 */
 	@Override
 	public Set<String> getDetailPaneTypes(IStructuredSelection selection) {
-		Set<String> possibleIDs = new HashSet<String>(2);
+		Set<String> possibleIDs = new HashSet<>(2);
 		if (selection != null){
 			if (selection.size() == 1 && selection.getFirstElement() instanceof IJavaVariable){
 				possibleIDs.add(SimpleDetailPane.ID);
diff --git a/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/lib/classpath.jar b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/lib/classpath.jar
new file mode 100644
index 0000000..401654f
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/lib/classpath.jar
Binary files differ
diff --git a/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/module-info.java b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/module-info.java
new file mode 100644
index 0000000..188c640
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/module-info.java
@@ -0,0 +1,3 @@
+module test.classpath {
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/test/classpath/Main.java b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/test/classpath/Main.java
new file mode 100644
index 0000000..2c24818
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/classpathModuleProject/src/test/classpath/Main.java
@@ -0,0 +1,9 @@
+package test.classpath;
+
+public class Main {
+
+    public static void main(String[] args) {
+    	System.out.println("Hello world");
+    }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/testresources/classpathProject/lib/classpath.jar b/org.eclipse.jdt.debug.tests/testresources/classpathProject/lib/classpath.jar
new file mode 100644
index 0000000..401654f
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/classpathProject/lib/classpath.jar
Binary files differ
diff --git a/org.eclipse.jdt.debug.tests/testresources/classpathProject/src/test/classpath/Main.java b/org.eclipse.jdt.debug.tests/testresources/classpathProject/src/test/classpath/Main.java
new file mode 100644
index 0000000..2c24818
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testresources/classpathProject/src/test/classpath/Main.java
@@ -0,0 +1,9 @@
+package test.classpath;
+
+public class Main {
+
+    public static void main(String[] args) {
+    	System.out.println("Hello world");
+    }
+
+}
\ No newline at end of file
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 bfd3a57..aaa5fa2 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
@@ -1064,7 +1064,7 @@
 		ILaunch launch = configuration.launch(mode, null, false, register);
 		Object suspendee= waiter.waitForEvent();
 		if (suspendee == null) {
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
             buf.append("Test case: "); //$NON-NLS-1$
             buf.append(getName());
             buf.append("\n"); //$NON-NLS-1$
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 9a50482..1c8e529 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
@@ -84,6 +84,7 @@
 import org.eclipse.jdt.debug.tests.core.WorkspaceSourceContainerTests;
 import org.eclipse.jdt.debug.tests.eval.GeneralEvalTests;
 import org.eclipse.jdt.debug.tests.eval.GenericsEvalTests;
+import org.eclipse.jdt.debug.tests.launching.ClasspathShortenerTests;
 import org.eclipse.jdt.debug.tests.launching.ConfigurationEncodingTests;
 import org.eclipse.jdt.debug.tests.launching.ConfigurationResourceMappingTests;
 import org.eclipse.jdt.debug.tests.launching.ContributedTabTests;
@@ -94,6 +95,8 @@
 import org.eclipse.jdt.debug.tests.launching.LaunchShortcutTests;
 import org.eclipse.jdt.debug.tests.launching.LaunchTests;
 import org.eclipse.jdt.debug.tests.launching.LaunchesTests;
+import org.eclipse.jdt.debug.tests.launching.LongClassPathTests;
+import org.eclipse.jdt.debug.tests.launching.LongModulePathTests;
 import org.eclipse.jdt.debug.tests.launching.MigrationDelegateTests;
 import org.eclipse.jdt.debug.tests.launching.PListParserTests;
 import org.eclipse.jdt.debug.tests.launching.ProjectClasspathVariableTests;
@@ -345,5 +348,12 @@
 	//add the complete eval suite
 		addTest(new TestSuite(GeneralEvalTests.class));
 		//addTest(EvalTestSuite.suite());
+
+		// long classpath tests
+		addTest(new TestSuite(ClasspathShortenerTests.class));
+		addTest(LongClassPathTests.suite());
+		if (JavaProjectHelper.isJava9Compatible()) {
+			addTest(new TestSuite(LongModulePathTests.class));
+		}
 	}
 }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractToggleBreakpointsTarget.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractToggleBreakpointsTarget.java
index 9a07b6f..0f2dc95 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractToggleBreakpointsTarget.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractToggleBreakpointsTarget.java
@@ -40,8 +40,8 @@
 

 	class Listener implements IBreakpointListener {

 

-		List<IBreakpoint> added = new ArrayList<IBreakpoint>();

-		List<IBreakpoint> removed = new ArrayList<IBreakpoint>();

+		List<IBreakpoint> added = new ArrayList<>();

+		List<IBreakpoint> removed = new ArrayList<>();

 

 		@Override

 		public void breakpointAdded(IBreakpoint breakpoint) {

diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java
index fc33a1f..85e2175 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java
@@ -79,7 +79,7 @@
 	 * @return List
 	 */
 	protected List<IJavaLineBreakpoint> createBreakpoints(String typeName) throws Exception {
-		List<IJavaLineBreakpoint> bps = new ArrayList<IJavaLineBreakpoint>();
+		List<IJavaLineBreakpoint> bps = new ArrayList<>();
 		// anonymous class
 		bps.add(createUnregisteredLineBreakpoint(43, typeName));
 		// blocks
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointMethodLocator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointMethodLocator.java
index c77c93a..9dc2f9d 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointMethodLocator.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointMethodLocator.java
@@ -91,7 +91,7 @@
 		if (node.getExtraDimensions() != 0 || Modifier.isAbstract(node.getModifiers())) {
 			return null;
 		}
-		StringBuffer signature= new StringBuffer();
+		StringBuilder signature= new StringBuilder();
 		signature.append('(');
 		List<SingleVariableDeclaration> parameters = node.parameters();
 		for (Iterator<SingleVariableDeclaration> iter = parameters.iterator(); iter.hasNext();) {
@@ -113,7 +113,7 @@
 		return signature.toString();
 	}
 
-	private void appendTypeLetter(StringBuffer signature, PrimitiveType type) {
+	private void appendTypeLetter(StringBuilder signature, PrimitiveType type) {
 		PrimitiveType.Code code= type.getPrimitiveTypeCode();
 		if (code == PrimitiveType.BYTE) {
 			signature.append('B');
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsWithGenerics.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsWithGenerics.java
index 68d4138..c0b2c45 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsWithGenerics.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpointsWithGenerics.java
@@ -247,7 +247,7 @@
 		String type = "a.b.c.bug403028";
 		IJavaThread thread = null;
 		try {
-			String condition = "StringBuffer buf = new StringBuffer();"
+			String condition = "StringBuilder buf = new StringBuilder();"
 					+ "buf.append(\"{\");"
 					+ "Iterator i = this.entrySet().iterator();"
 					+ "boolean hasNext = i.hasNext();"
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java
index d65f6ca..e17edba 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java
@@ -43,7 +43,7 @@
 	 */
 	public void testDeferredBreakpoints() throws Exception {
 		String typeName = "Breakpoints";
-		List<IBreakpoint> bps = new ArrayList<IBreakpoint>();
+		List<IBreakpoint> bps = new ArrayList<>();
 		int[] lines = new int[]{
 				43,		// anonymous class
 				102,	// blocks
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ImportBreakpointsTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ImportBreakpointsTest.java
index 0ff0a73..bdd8dd5 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ImportBreakpointsTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ImportBreakpointsTest.java
@@ -48,7 +48,7 @@
 	 */
 	public void testBreakpointImportFile() throws Exception {
 		try {
-			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<IJavaBreakpoint>();
+			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<>();
 			String typeName = "DropTests";
 			breakpoints.add(createClassPrepareBreakpoint(typeName));
 			breakpoints.add(createLineBreakpoint(32, typeName));
@@ -88,7 +88,7 @@
 	 */
 	public void testBreakpointImportBuffer() throws Exception {
 		try {
-			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<IJavaBreakpoint>();
+			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<>();
 			String typeName = "DropTests";
 			breakpoints.add(createClassPrepareBreakpoint(typeName));
 			breakpoints.add(createLineBreakpoint(32, typeName));
@@ -117,7 +117,7 @@
 	 */
 	public void testBreakpointImportOverwrite() throws Exception {
 		try {
-			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<IJavaBreakpoint>();
+			ArrayList<IJavaBreakpoint> breakpoints = new ArrayList<>();
 			String typeName = "DropTests";
 			breakpoints.add(createClassPrepareBreakpoint(typeName));
 			breakpoints.add(createLineBreakpoint(32, typeName));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests.java
index bbcca75..0505c82 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests.java
@@ -46,7 +46,7 @@
 	 */
 	public void testEntryAndExitBreakpoints() throws Exception {
 		String typeName = "DropTests";
-		List<IJavaMethodBreakpoint> bps = new ArrayList<IJavaMethodBreakpoint>();
+		List<IJavaMethodBreakpoint> bps = new ArrayList<>();
 		// method 4 - entry
 		bps.add(createMethodBreakpoint(typeName, "method4", "()V", true, false));
 		// method 1 - exit
@@ -133,7 +133,7 @@
 	 */
 	public void testInnerClassNotHit() throws Exception {
 		String typeNamePattern = "A";
-		List<IJavaMethodBreakpoint> bps = new ArrayList<IJavaMethodBreakpoint>();
+		List<IJavaMethodBreakpoint> bps = new ArrayList<>();
 		// method b - entry
 		bps.add(createMethodBreakpoint(typeNamePattern, "b", "()V", true, false));
 
@@ -162,7 +162,7 @@
 	 */
 	public void testInnerClassesHit() throws Exception {
 		String typeNamePattern = "A*";
-		List<IJavaMethodBreakpoint> bps = new ArrayList<IJavaMethodBreakpoint>();
+		List<IJavaMethodBreakpoint> bps = new ArrayList<>();
 		// method b - entry
 		bps.add(createMethodBreakpoint(typeNamePattern, "b", "()V", true, false));
 
@@ -408,7 +408,7 @@
 	 */
 	public void testSkipMethodBreakpoint() throws Exception {
 		String typeName = "DropTests";
-		List<IJavaMethodBreakpoint> bps = new ArrayList<IJavaMethodBreakpoint>();
+		List<IJavaMethodBreakpoint> bps = new ArrayList<>();
 		// method 4 - entry
 		bps.add(createMethodBreakpoint(typeName, "method4", "()V", true, false));
 		// method 1 - exit
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java
index 7d29f20..674ad65 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java
@@ -94,7 +94,7 @@
 	 */
 	public void testGenericArrayEntryBreakpoints() throws Exception {
 		String typeName = "a.b.c.GenericMethodEntryTest";
-		List<IJavaMethodBreakpoint> bps = new ArrayList<IJavaMethodBreakpoint>();
+		List<IJavaMethodBreakpoint> bps = new ArrayList<>();
 		// func(T[] arr, int m, int n) - entry
 		bps.add(createMethodBreakpoint(typeName, "func", "([Ljava/lang/Comparable;II)I", true, false));
 		// func(int m, int n)
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/PatternBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/PatternBreakpointTests.java
index f9d3e87..4cb6b97 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/PatternBreakpointTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/PatternBreakpointTests.java
@@ -41,7 +41,7 @@
 	public void testPatternBreakpoints() throws Exception {
 		String sourceName = "Breakpoints.java";
 		String pattern = "Break";
-		List<IJavaPatternBreakpoint> bps = new ArrayList<IJavaPatternBreakpoint>();
+		List<IJavaPatternBreakpoint> bps = new ArrayList<>();
 		// anonymous class
 		bps.add(createPatternBreakpoint(43, sourceName, pattern));
 		// blocks
@@ -176,7 +176,7 @@
 	public void testSkipPatternBreakpoint() throws Exception {
 		String sourceName = "Breakpoints.java";
 		String pattern = "Break";
-		List<IJavaPatternBreakpoint> bps = new ArrayList<IJavaPatternBreakpoint>();
+		List<IJavaPatternBreakpoint> bps = new ArrayList<>();
 		// anonymous class
 		bps.add(createPatternBreakpoint(43, sourceName, pattern));
 		// blocks
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TargetPatternBreakpointTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TargetPatternBreakpointTests.java
index 87d0a2f..b0a26e1 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TargetPatternBreakpointTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/TargetPatternBreakpointTests.java
@@ -49,7 +49,7 @@
 		JDIDebugPlugin.getDefault().addJavaBreakpointListener(this);
 
 		String sourceName = "Breakpoints.java";
-		List<IJavaTargetPatternBreakpoint> bps = new ArrayList<IJavaTargetPatternBreakpoint>();
+		List<IJavaTargetPatternBreakpoint> bps = new ArrayList<>();
 		// anonymous class
 		bps.add(createTargetPatternBreakpoint(43, sourceName));
 		// blocks
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
index d40f7a7..53d1bcc 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ThreadNameChangeTests.java
@@ -13,7 +13,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -155,15 +157,32 @@
 	}
 
 	private IThread findThread(IJavaThread thread, String name) throws DebugException {
-		IThread t = Arrays.stream(thread.getDebugTarget().getThreads()).filter(x -> {
+		return findThread(thread, name, 5_000);
+	}
+
+	private IThread findThread(IJavaThread thread, String name, long timeout) throws DebugException {
+		Predicate<IThread> predicate = x -> {
 			try {
 				return x.getName().equals(name);
 			}
 			catch (DebugException e1) {
 			}
 			return false;
-		}).findFirst().get();
-		return t;
+		};
+		IThread[] threads = {};
+
+		// Wait until timeout or JDIDebugTarget.ThreadStartHandler has added the thread.
+		long start = System.currentTimeMillis();
+		while (System.currentTimeMillis() - start <= timeout) {
+			threads = thread.getDebugTarget().getThreads();
+			Optional<IThread> match = Arrays.stream(threads).filter(predicate).findFirst();
+			if (match.isPresent()) {
+				return match.get();
+			}
+		}
+
+		throw new AssertionError("Timeout of " + timeout + "ms reached, thread with name \"" + name + "\" not found in set of threads: "
+				+ Arrays.asList(threads));
 	}
 
 	/**
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ArgumentTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ArgumentTests.java
index d18597f..5d233cb 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ArgumentTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ArgumentTests.java
@@ -42,7 +42,7 @@
 
 	private class ConsoleArgumentOutputRetriever implements IConsoleLineTrackerExtension {
 
-		StringBuffer buffer;
+		StringBuilder buffer;
 		IDocument document;
 		boolean closed = false;
 
@@ -57,7 +57,7 @@
 		 */
 		@Override
 		public void init(IConsole console) {
-			buffer = new StringBuffer();
+			buffer = new StringBuilder();
 			document = console.getDocument();
 		}
 
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/BootpathTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/BootpathTests.java
index fc822d6..390245b 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/BootpathTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/BootpathTests.java
@@ -75,7 +75,7 @@
 		pre.setClasspathProperty(IRuntimeClasspathEntry.BOOTSTRAP_CLASSES);
 		newpath[0] = pre;
 		System.arraycopy(classpath, 0, newpath, 1, classpath.length);
-		List<String> mementos = new ArrayList<String>(newpath.length);
+		List<String> mementos = new ArrayList<>(newpath.length);
 		for (int i = 0; i < newpath.length; i++) {
 			IRuntimeClasspathEntry entry = newpath[i];
 			mementos.add(entry.getMemento());
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathProviderTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathProviderTests.java
index f6c5e0c..9da9048 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathProviderTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ClasspathProviderTests.java
@@ -462,7 +462,7 @@
 		String location1 = bin1.getLocation().toOSString();
 		String location2 = bin2.getLocation().toOSString();
 
-		List<String> list = new ArrayList<String>();
+		List<String> list = new ArrayList<>();
 		for (int i = 0; i < entries.length; i++) {
 			list.add(entries[i]);
 		}
@@ -485,7 +485,7 @@
 		IFolder bin = ResourcesPlugin.getWorkspace().getRoot().getFolder(project.getOutputLocation());
 		String location = bin.getLocation().toOSString();
 
-		List<String> list = new ArrayList<String>();
+		List<String> list = new ArrayList<>();
 		for (int i = 0; i < entries.length; i++) {
 			list.add(entries[i]);
 		}
@@ -517,7 +517,7 @@
         // test runtime class path resolution
         String[] entries = JavaRuntime.computeDefaultRuntimeClassPath(project);
         String jarPath = get14Project().getProject().getLocation().append("src").append("A.jar").toOSString();
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
 		for (int i = 0; i < entries.length; i++) {
 			list.add(entries[i]);
 		}
@@ -553,7 +553,7 @@
         // test runtime class path resolution
         String[] entries = JavaRuntime.computeDefaultRuntimeClassPath(project);
         String jarPath = get14Project().getProject().getLocation().append("src").append("A.jar").toOSString();
-        List<String> list = new ArrayList<String>();
+        List<String> list = new ArrayList<>();
 		for (int i = 0; i < entries.length; i++) {
 			list.add(entries[i]);
 		}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EnvironmentTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EnvironmentTests.java
index 0b0ad85..47747bb 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EnvironmentTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EnvironmentTests.java
@@ -50,7 +50,7 @@
 		if (win32) {
 			ILaunchConfigurationType type = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 			ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, "testWinOSCaseInsensitiveOverride");
-			Map<String, String> override = new HashMap<String, String>();
+			Map<String, String> override = new HashMap<>();
 			override.put("pAtH", "OVERRIDE");
 			workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, override);
 			String[] environment = getLaunchManager().getEnvironment(workingCopy);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java
index 294fdd1..2b74c09 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/EventSetTests.java
@@ -30,7 +30,7 @@
 
 	public void testDoubleBreakpoint() throws Exception {
 		String typeName = "Breakpoints";
-		List<IJavaLineBreakpoint> bps = new ArrayList<IJavaLineBreakpoint>();
+		List<IJavaLineBreakpoint> bps = new ArrayList<>();
 		// add two breakpoints at the same location
 		bps.add(createLineBreakpoint(88, typeName));
 		bps.add(createLineBreakpoint(88, typeName));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java
index b4bf175..cf64aef 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/InstanceVariableTests.java
@@ -80,7 +80,7 @@
 
 			String[] names = ((IJavaReferenceType)object.getJavaType()).getDeclaredFieldNames();
 			assertEquals("Should be 7 declared fields", 7, names.length);
-			List<String> fields = new ArrayList<String>();
+			List<String> fields = new ArrayList<>();
 			for (int i = 0; i < names.length; i++) {
 				String string = names[i];
 				fields.add(string);
@@ -114,7 +114,7 @@
 
 			String[] names = ((IJavaReferenceType)object.getJavaType()).getDeclaredFieldNames();
 			assertEquals("Should be 3 declared fields", 3, names.length);
-			List<String> fields = new ArrayList<String>();
+			List<String> fields = new ArrayList<>();
 			for (int i = 0; i < names.length; i++) {
 				String string = names[i];
 				fields.add(string);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/RemoteJavaApplicationTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/RemoteJavaApplicationTests.java
index ed1a22b..e71ed50 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/RemoteJavaApplicationTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/RemoteJavaApplicationTests.java
@@ -59,7 +59,7 @@
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "-Djava.compiler=NONE -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,suspend=y,server=y");
 		// use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2)
-		Map<String, String> map = new HashMap<String, String>(1);
+		Map<String, String> map = new HashMap<>(1);
 		map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java");
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
 		ILaunchConfiguration launchRemoteVMConfig = config.doSave();
@@ -72,7 +72,7 @@
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR);
 		IVMConnector connector = JavaRuntime.getVMConnector(IJavaLaunchConfigurationConstants.ID_SOCKET_ATTACH_VM_CONNECTOR);
 		Map<String, ? extends Connector.Argument> def = connector.getDefaultArguments();
-		Map<String, String> argMap = new HashMap<String, String>(def.size());
+		Map<String, String> argMap = new HashMap<>(def.size());
 		Iterator<String> iter = connector.getArgumentOrder().iterator();
 		while (iter.hasNext()) {
 			String key = iter.next();
@@ -138,7 +138,7 @@
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_CONNECTOR, IJavaLaunchConfigurationConstants.ID_SOCKET_LISTEN_VM_CONNECTOR);
 		IVMConnector connector = JavaRuntime.getVMConnector(IJavaLaunchConfigurationConstants.ID_SOCKET_LISTEN_VM_CONNECTOR);
 		Map<String, ? extends Connector.Argument> def = connector.getDefaultArguments();
-		Map<String, String> argMap = new HashMap<String, String>(def.size());
+		Map<String, String> argMap = new HashMap<>(def.size());
 		Iterator<String> iter = connector.getArgumentOrder().iterator();
 		while (iter.hasNext()) {
 			String key = iter.next();
@@ -155,7 +155,7 @@
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, get14Project().getElementName());
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, "-Djava.compiler=NONE -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,suspend=y,server=n");
 		// use 'java' instead of 'javaw' to launch tests (javaw is problematic on JDK1.4.2)
-		Map<String, String> map = new HashMap<String, String>(1);
+		Map<String, String> map = new HashMap<>(1);
 		map.put(IJavaLaunchConfigurationConstants.ATTR_JAVA_COMMAND, "java");
 		config.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP, map);
 		ILaunchConfiguration launchRemoteVMConfig = config.doSave();
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StringSubstitutionTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StringSubstitutionTests.java
index f662d3e..4e97d20 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StringSubstitutionTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/StringSubstitutionTests.java
@@ -396,7 +396,7 @@
 	 */
 	public void testAddNotificaiton() throws CoreException {
 		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
-		List<IValueVariable> vars = new ArrayList<IValueVariable>();
+		List<IValueVariable> vars = new ArrayList<>();
 		IValueVariable one = manager.newValueVariable("var_one", null);
 		IValueVariable two = manager.newValueVariable("var_two", null);
 		vars.add(one);
@@ -444,7 +444,7 @@
 	 */
 	public void testRemoveNotificaiton() throws CoreException {
 		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
-		List<IValueVariable> vars = new ArrayList<IValueVariable>();
+		List<IValueVariable> vars = new ArrayList<>();
 		IValueVariable one = manager.newValueVariable("var_one", null);
 		IValueVariable two = manager.newValueVariable("var_two", null);
 		vars.add(one);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
index afa2b26..02c8f39 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/TypeTests.java
@@ -35,7 +35,7 @@
 		IJavaType[] types = new IJavaType[3];
 		int index = 0;
 		String typeName = "Breakpoints";
-		List<IJavaLineBreakpoint> bps = new ArrayList<IJavaLineBreakpoint>();
+		List<IJavaLineBreakpoint> bps = new ArrayList<>();
 		// main
 		bps.add(createLineBreakpoint(52, typeName));
 		// threading
@@ -82,7 +82,7 @@
 
     public void testClassLoader() throws Exception {
         String typeName = "Breakpoints";
-        List<IJavaLineBreakpoint> bps = new ArrayList<IJavaLineBreakpoint>();
+        List<IJavaLineBreakpoint> bps = new ArrayList<>();
         // instance method
         bps.add(createLineBreakpoint(81, typeName));
         bps.add(createLineBreakpoint(88, typeName));
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/VMInstallTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/VMInstallTests.java
index f7a9b46..0d4d0ba 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/VMInstallTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/VMInstallTests.java
@@ -253,7 +253,7 @@
 	 * @return preference store key
 	 */
 	private String getSystemPropertyKey(IVMInstall vm, String property) {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append("PREF_VM_INSTALL_SYSTEM_PROPERTY");
 		buffer.append("."); //$NON-NLS-1$
 		buffer.append(vm.getVMInstallType().getId());
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/NestedTypeTestGenerator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/NestedTypeTestGenerator.java
index 63236e9..d3ee66f 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/NestedTypeTestGenerator.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/NestedTypeTestGenerator.java
@@ -120,7 +120,7 @@
 	}
 
 	public static void gen_AA_aa() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('c', 2, code);
@@ -142,7 +142,7 @@
 	}
 
 	public static void gen_AA_aaStatic() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('d', 2, code);
@@ -155,7 +155,7 @@
 	}
 
 	public static void gen_AB_ab() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('c', 2, code);
@@ -182,7 +182,7 @@
 	}
 
 	public static void gen_AC_ac() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('g', 2, code);
@@ -197,7 +197,7 @@
 	}
 
 	public static void gen_AD_ad() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('g', 2, code);
@@ -212,7 +212,7 @@
 	}
 
 	public static void gen_A_a() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 1, code);
 		createTest('c', 1, code);
@@ -236,7 +236,7 @@
 	}
 
 	public static void gen_AE_ae() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('h', 2, code);
@@ -246,7 +246,7 @@
 	}
 
 	public static void gen_AF_af() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTest('h', 2, code);
@@ -256,7 +256,7 @@
 	}
 
 	public static void gen_A_aStatic() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 1, code);
 		createTest('d', 1, code);
@@ -274,7 +274,7 @@
 	}
 
 	public static void gen_BB_bb() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -308,7 +308,7 @@
 	}
 
 	public static void gen_BC_bc() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -330,7 +330,7 @@
 	}
 
 	public static void gen_BD_bd() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -352,7 +352,7 @@
 	}
 
 	public static void gen_B_b() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 1, code);
 		createTest('b', 1, code);
@@ -384,7 +384,7 @@
 	}
 
 	public static void gen_CB_cb() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -400,7 +400,7 @@
 	}
 
 	public static void gen_CC_cc() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -416,7 +416,7 @@
 	}
 
 	public static void gen_CD_cd() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -432,7 +432,7 @@
 	}
 
 	public static void gen_C_c() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 1, code);
 		createTest('b', 1, code);
@@ -450,7 +450,7 @@
 	}
 
 	public static void gen_DB_db() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -466,7 +466,7 @@
 	}
 
 	public static void gen_DC_dc() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -482,7 +482,7 @@
 	}
 
 	public static void gen_DD_dd() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 2, code);
 		createTest('b', 2, code);
@@ -498,7 +498,7 @@
 	}
 
 	public static void gen_D_d() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('a', 1, code);
 		createTest('b', 1, code);
@@ -516,7 +516,7 @@
 	}
 
 	public static void gen_evalNestedTypeTest() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 
 		createTest('a', 0, code);
@@ -547,7 +547,7 @@
 	}
 
 	public static void gen_EB_eb() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -556,7 +556,7 @@
 	}
 
 	public static void gen_EC_ec() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -565,7 +565,7 @@
 	}
 
 	public static void gen_ED_ed() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -574,7 +574,7 @@
 	}
 
 	public static void gen_E_e() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 1, code);
 		createTest('f', 1, code);
@@ -584,7 +584,7 @@
 	}
 
 	public static void gen_FB_fb() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -593,7 +593,7 @@
 	}
 
 	public static void gen_FC_fc() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -602,7 +602,7 @@
 	}
 
 	public static void gen_FD_fd() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 2, code);
 		createTestsStaticFields(code);
@@ -611,7 +611,7 @@
 	}
 
 	public static void gen_F_f() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 1, code);
 		createTest('f', 1, code);
@@ -621,7 +621,7 @@
 	}
 
 	public static void gen_evalNestedTypeTestStatic() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest('b', 0, code);
 		createTest('d', 0, code);
@@ -648,7 +648,7 @@
 	}
 
 	public static void gen_main() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTestsStaticFields(code);
 
@@ -657,7 +657,7 @@
 
 	// ------------------------------
 
-	public static void createTestsStaticFields(StringBuffer code) {
+	public static void createTestsStaticFields(StringBuilder code) {
 		createTestQualifier(T_T, 'b', code);
 		createTestQualifier(T_T, 'd', code);
 		createTestQualifier(T_T, 'f', code);
@@ -689,7 +689,7 @@
 		createTestQualifier(T_B_BB, 'j', code);
 	}
 
-	public static void createTestsStaticFields_A(StringBuffer code) {
+	public static void createTestsStaticFields_A(StringBuilder code) {
 		createTestsStaticFields(code);
 		createTestQualifier(T_AA, 'd', code);
 		createTestQualifier(T_AA, 'f', code);
@@ -699,7 +699,7 @@
 		createTestQualifier(T_AB, 'j', code);
 	}
 
-	public static void createTestsStaticFields_B(StringBuffer code) {
+	public static void createTestsStaticFields_B(StringBuilder code) {
 		createTestsStaticFields(code);
 		createTestQualifier(T_BB, 'd', code);
 		createTestQualifier(T_BB, 'f', code);
@@ -708,7 +708,7 @@
 
 	// ------------------------------
 
-	public static void createTest(char variable, int level, StringBuffer code) {
+	public static void createTest(char variable, int level, StringBuilder code) {
 		code.append("\tpublic void testEvalNestedTypeTest_" + variable + "() throws Throwable {\n");
 		tryBlockBegin(code);
 
@@ -725,7 +725,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void createTestThis(char variable, int level, StringBuffer code) {
+	public static void createTestThis(char variable, int level, StringBuilder code) {
 		code.append("\tpublic void testEvalNestedTypeTest_this_" + variable + "() throws Throwable {\n");
 		tryBlockBegin(code);
 
@@ -744,7 +744,7 @@
 
 
 
-	public static void createTestQualifier(int qualifier, char variable, StringBuffer code) {
+	public static void createTestQualifier(int qualifier, char variable, StringBuilder code) {
 		String strQualifier= qualifiers[qualifier];
 		code.append("\tpublic void testEvalNestedTypeTest_" + strQualifier + "_" + variable + "() throws Throwable {\n");
 		tryBlockBegin(code);
@@ -764,9 +764,9 @@
 
 	//---------------------
 
-	public static void createJavaFile(StringBuffer tests, int lineNumber, int numberFrames) throws Exception {
+	public static void createJavaFile(StringBuilder tests, int lineNumber, int numberFrames) throws Exception {
 
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		code.append("/*******************************************************************************\n");
 		code.append(" * Copyright (c) 2002, 2003 IBM Corporation and others.\n");
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/OtherTestsGenerator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/OtherTestsGenerator.java
index b34c075..97b30f9 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/OtherTestsGenerator.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/OtherTestsGenerator.java
@@ -33,7 +33,7 @@
 	}
 
 	public static void genTestsOperators1() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		genTestTypeBinaryOpTypeBinaryPromotion(T_int, Op_plus, T_int, code);
 		genTestTypeBinaryOpTypeBinaryPromotion(T_String, Op_plus, T_String, code);
@@ -44,7 +44,7 @@
 	}
 
 	public static void genTestsOperators2() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		genTestLocalVarAssignment(T_int, code);
 		genTestLocalVarAssignment(T_String, code);
@@ -55,7 +55,7 @@
 	}
 
 	public static void genTestsArray() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		genTestArrayValue(T_int, code);
 		genTestArrayLength(T_int, code);
@@ -71,7 +71,7 @@
 	}
 
 	public static void genTestsNestedTypes1() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		NestedTypeTestGenerator.createTest('a', 2, code);
 		NestedTypeTestGenerator.createTest('d', 2, code);
@@ -103,7 +103,7 @@
 	}
 
 	public static void genTestsNestedTypes2() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		NestedTypeTestGenerator.createTest('f', 0, code);
 		NestedTypeTestGenerator.createTestQualifier(NestedTypeTestGenerator.T_T, 'b', code);
@@ -130,7 +130,7 @@
 
 
 	public static void genTestsTypeHierarchy1() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		TypeHierarchyTestsGenerator.createTestQualifier(TypeHierarchyTestsGenerator.IAA, TypeHierarchyTestsGenerator.M1, code);
 		TypeHierarchyTestsGenerator.createTestQualifier(TypeHierarchyTestsGenerator.AA, TypeHierarchyTestsGenerator.M2, code);
@@ -159,7 +159,7 @@
 	}
 
 	public static void genTestsTypeHierarchy2() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		TypeHierarchyTestsGenerator.createTest_TestC(code, TypeHierarchyTestsGenerator.CC);
 
@@ -170,7 +170,7 @@
 	 * Method genTestNumberLiteral.
 	 */
 	private static void genTestNumberLiteral() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTestNumberLiteral1("0", T_int, code);
 		createTestNumberLiteral1("00", T_int, code);
@@ -234,7 +234,7 @@
 	/**
 	 * Method createTestNumberLiteral.
 	 */
-	private static void createTestNumberLiteral1(String literal, int type, StringBuffer code) {
+	private static void createTestNumberLiteral1(String literal, int type, StringBuilder code) {
 		String tName= fTypeName[type];
 
 		code.append("\tpublic void test" + literal.replace('-', 'N').replace('.', '_').replace('+', 'P') + "() throws Throwable {\n");
@@ -249,7 +249,7 @@
 	/**
 	 * Method createTestNumberLiteral.
 	 */
-	private static void createTestNumberLiteral2(String literal, int type, StringBuffer code) {
+	private static void createTestNumberLiteral2(String literal, int type, StringBuilder code) {
 		String tName= fTypeName[type];
 
 		code.append("\tpublic void test" + literal.replace('-', 'N').replace('.', '_').replace('+', 'P') + "() throws Throwable {\n");
@@ -265,13 +265,13 @@
 	}
 
 
-	public static void createJavaFile(StringBuffer tests, String className, String testClass, int lineNumber, int numberFrames, int hitCount) throws Exception {
+	public static void createJavaFile(StringBuilder tests, String className, String testClass, int lineNumber, int numberFrames, int hitCount) throws Exception {
 		createJavaFile(tests, className, testClass, lineNumber, numberFrames, hitCount, true);
 	}
 
-	public static void createJavaFile(StringBuffer tests, String className, String testClass, int lineNumber, int numberFrames, int hitCount, boolean importJDIObjectValue) throws Exception {
+	public static void createJavaFile(StringBuilder tests, String className, String testClass, int lineNumber, int numberFrames, int hitCount, boolean importJDIObjectValue) throws Exception {
 
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		code.append("/*******************************************************************************\n");
 		code.append(" * Copyright (c) 2002, 2003 IBM Corporation and others.\n");
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TestGenerator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TestGenerator.java
index 46622de..230fb2f 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TestGenerator.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TestGenerator.java
@@ -185,7 +185,7 @@
 
 	public static void genTestsNumericTypeAllOpsAllTypes(int type) throws Exception {
 
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = typeUpperName[type] + "OperatorsTests";
 
@@ -221,7 +221,7 @@
 	}
 
 	public static void genTestsBooleanAllOpsBoolean() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "BooleanOperatorsTests";
 
@@ -235,7 +235,7 @@
 
 	public static void genTestsStringPlusOpAllTypes() throws Exception {
 
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "StringPlusOpTests";
 
@@ -256,7 +256,7 @@
 	}
 
 	public static void genTestsLocalVarValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "LocalVarValueTests";
 
@@ -278,7 +278,7 @@
 	}
 
 	public static void genTestsLocalVarAssignment() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "LocalVarAssignmentTests";
 
@@ -300,7 +300,7 @@
 
 	public static void genTestsNumericTypeAllAssignmentOpsAllTypes(int type) throws Exception {
 
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = typeUpperName[type] + "AssignmentOperatorsTests";
 
@@ -324,7 +324,7 @@
 	}
 
 	public static void genTestsBooleanAllAssignmentOpsBoolean() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "BooleanAssignmentOperatorsTests";
 
@@ -345,7 +345,7 @@
 
 	public static void genTestsStringPlusAssignmentOpAllTypes() throws Exception {
 
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "StringPlusAssignmentOpTests";
 
@@ -366,7 +366,7 @@
 	}
 
 	public static void genTestsNumericTypeCast() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "NumericTypesCastTests";
 
@@ -382,7 +382,7 @@
 	}
 
 	public static void genTestsAllIntegerTypesAllXfixOps() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "XfixOperatorsTests";
 
@@ -398,7 +398,7 @@
 	}
 
 	public static void genTestsQualifiedFieldValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "QualifiedFieldValueTests";
 
@@ -416,7 +416,7 @@
 	}
 
 	public static void genTestsQualifiedStaticFieldValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "QualifiedStaticFieldValueTests";
 
@@ -432,7 +432,7 @@
 
 		createJavaFile(className, "EvalTypeTests", 73, 1, true, code);
 
-		code = new StringBuffer();
+		code = new StringBuilder();
 
 		className = "QualifiedStaticFieldValueTests2";
 
@@ -450,7 +450,7 @@
 	}
 
 	public static void genTestsFieldValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "FieldValueTests";
 
@@ -468,7 +468,7 @@
 	}
 
 	public static void genTestsStaticFieldValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "StaticFieldValueTests";
 
@@ -490,7 +490,7 @@
 	}
 
 	public static void genTestsArrayValue() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "ArrayValueTests";
 
@@ -518,7 +518,7 @@
 	}
 
 	public static void genTestsArrayAssignment() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "ArrayAssignmentTests";
 
@@ -536,7 +536,7 @@
 	}
 
 	public static void genTestsArrayAllocation() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "ArrayAllocationTests";
 
@@ -554,7 +554,7 @@
 	}
 
 	public static void genTestsArrayInitialization() throws Exception {
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		String className = "ArrayInitializationTests";
 
@@ -572,7 +572,7 @@
 	}
 	//----------------------------
 
-	public static void genTestsNumericTypeArithmeticOpNumericTypes(int type, int op, StringBuffer code) {
+	public static void genTestsNumericTypeArithmeticOpNumericTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + ", " + fTypeName[T_float] + ", " + fTypeName[T_double] + "}\n" +
 					"\n");
@@ -587,7 +587,7 @@
 
 	}
 
-	public static void genTestsNumericTypeComparisonOpNumericTypes(int type, int op, StringBuffer code) {
+	public static void genTestsNumericTypeComparisonOpNumericTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + ", " + fTypeName[T_float] + ", " + fTypeName[T_double] + "}\n" +
 					"\n");
@@ -602,7 +602,7 @@
 
 	}
 
-	public static void genTestsIntegerTypeShiftOpIntegerTypes(int type, int op, StringBuffer code) {
+	public static void genTestsIntegerTypeShiftOpIntegerTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + "}\n" +
 					"\n");
@@ -615,7 +615,7 @@
 
 	}
 
-	public static void genTestsIntegerTypeBooleanOpIntegerTypes(int type, int op, StringBuffer code) {
+	public static void genTestsIntegerTypeBooleanOpIntegerTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + "}\n" +
 					"\n");
@@ -628,7 +628,7 @@
 
 	}
 
-	public static void genTestsNumericTypeArithmeticAssignmentOpNumericTypes(int type, int op, StringBuffer code) {
+	public static void genTestsNumericTypeArithmeticAssignmentOpNumericTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + ", " + fTypeName[T_float] + ", " + fTypeName[T_double] + "}\n" +
 					"\n");
@@ -643,7 +643,7 @@
 
 	}
 
-	public static void genTestsIntegerTypeArithmeticAssignmentOpIntegerTypes(int type, int op, StringBuffer code) {
+	public static void genTestsIntegerTypeArithmeticAssignmentOpIntegerTypes(int type, int op, StringBuilder code) {
 
 		code.append("\t// " + fTypeName[type] + " " + opSymbol[op] + " {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + ", " + fTypeName[T_float] + ", " + fTypeName[T_double] + "}\n" +
 					"\n");
@@ -656,7 +656,7 @@
 
 	}
 
-	public static void genTestsNumericTypeCast(int type, StringBuffer code) {
+	public static void genTestsNumericTypeCast(int type, StringBuilder code) {
 
 		code.append("\t// (" + fTypeName[type] + ") {" + fTypeName[T_byte] + ", " + fTypeName[T_char] + ", " + fTypeName[T_short] + ", " + fTypeName[T_int] + ", " + fTypeName[T_long] + ", " + fTypeName[T_float] + ", " + fTypeName[T_double] + "}\n" +
 					"\n");
@@ -671,7 +671,7 @@
 
 	}
 
-	public static void genTestsNumericTypeAllXfixOps(int type, StringBuffer code) {
+	public static void genTestsNumericTypeAllXfixOps(int type, StringBuilder code) {
 
 		code.append("\t// {" + opSymbol[Op_prefixPlusPlus] + ", " + opSymbol[Op_prefixMinusMinus] + "} " + fTypeName[type] + "\n" +
 					"\t// " + fTypeName[type] + " {" + opSymbol[Op_postfixPlusPlus] + ", " + opSymbol[Op_postfixMinusMinus] + "}\n" +
@@ -685,7 +685,7 @@
 
 	//----------------------------
 
-	public static void genTestTypeBinaryOpTypeBinaryPromotion(int type1, int op, int type2, StringBuffer code) {
+	public static void genTestTypeBinaryOpTypeBinaryPromotion(int type1, int op, int type2, StringBuilder code) {
 
 		int promotedType = getPromotionType(type1, type2);
 
@@ -702,7 +702,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestTypeBinaryOpTypeBooleanResult(int type1, int op, int type2, StringBuffer code) {
+	public static void genTestTypeBinaryOpTypeBooleanResult(int type1, int op, int type2, StringBuilder code) {
 
 		int promotedType = T_boolean;
 
@@ -722,7 +722,7 @@
 
 	}
 
-	public static void genTestTypeBinaryOpTypeUnaryPromotion(int type1, int op, int type2, StringBuffer code) {
+	public static void genTestTypeBinaryOpTypeUnaryPromotion(int type1, int op, int type2, StringBuilder code) {
 
 		int promotedType = getUnaryPromotionType(type1);
 
@@ -739,7 +739,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestBooleanBinaryOpBoolean(int op, StringBuffer code) {
+	public static void genTestBooleanBinaryOpBoolean(int op, StringBuilder code) {
 
 		int type = T_boolean;
 
@@ -763,7 +763,7 @@
 
 	}
 
-	public static void genTestUnaryOpNumericType(int type, int op, StringBuffer code) {
+	public static void genTestUnaryOpNumericType(int type, int op, StringBuilder code) {
 
 		int promotedType = getUnaryPromotionType(type);
 
@@ -784,7 +784,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestUnaryOpBoolean(int op, StringBuffer code) {
+	public static void genTestUnaryOpBoolean(int op, StringBuilder code) {
 
 		int type = T_boolean;
 
@@ -804,7 +804,7 @@
 
 	}
 
-	public static void genTestLocalVarValue(int type, StringBuffer code ) {
+	public static void genTestLocalVarValue(int type, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "() throws Throwable {\n");
@@ -816,7 +816,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestLocalVarAssignment(int type, StringBuffer code) {
+	public static void genTestLocalVarAssignment(int type, StringBuilder code) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "() throws Throwable {\n");
@@ -832,7 +832,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestTypeAssignmentOpType(int type1, int op, int type2, StringBuffer code) {
+	public static void genTestTypeAssignmentOpType(int type1, int op, int type2, StringBuilder code) {
 
 		String t1UName = typeUpperName[type1];
 		String t2UName = typeUpperName[type2];
@@ -857,7 +857,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestNumericTypeCast(int type1, int type2, StringBuffer code) {
+	public static void genTestNumericTypeCast(int type1, int type2, StringBuilder code) {
 
 		String t1UName = typeUpperName[type1];
 		String t2UName = typeUpperName[type2];
@@ -872,7 +872,7 @@
 
 	}
 
-	public static void genTestNumericTypePrefixOp(int type, int op, StringBuffer code) {
+	public static void genTestNumericTypePrefixOp(int type, int op, StringBuilder code) {
 
 		String tUName = typeUpperName[type];
 		String oUName = opUpperName[op];
@@ -886,7 +886,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestNumericTypePostfixOp(int type, int op, StringBuffer code) {
+	public static void genTestNumericTypePostfixOp(int type, int op, StringBuilder code) {
 
 		String tUName = typeUpperName[type];
 		String oUName = opUpperName[op];
@@ -900,7 +900,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestFieldValue(int type, int prefix, StringBuffer code ) {
+	public static void genTestFieldValue(int type, int prefix, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "FieldValue() throws Throwable {\n");
@@ -912,7 +912,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestStaticFieldValue(int type, int prefix, StringBuffer code ) {
+	public static void genTestStaticFieldValue(int type, int prefix, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "StaticFieldValue() throws Throwable {\n");
@@ -924,7 +924,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestArrayValue(int type, StringBuffer code ) {
+	public static void genTestArrayValue(int type, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "ArrayValue() throws Throwable {\n");
@@ -944,7 +944,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestArrayLength(int type, StringBuffer code ) {
+	public static void genTestArrayLength(int type, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "ArrayLength() throws Throwable {\n");
@@ -956,7 +956,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestArrayAssignment(int type, StringBuffer code ) {
+	public static void genTestArrayAssignment(int type, StringBuilder code ) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "ArrayAssignment() throws Throwable {\n");
@@ -976,7 +976,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestArrayAllocation(int type, StringBuffer code) {
+	public static void genTestArrayAllocation(int type, StringBuilder code) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "ArrayAllocation() throws Throwable {\n");
@@ -988,7 +988,7 @@
 		code.append("\t}\n\n");
 	}
 
-	public static void genTestArrayInitialization(int type, StringBuffer code) {
+	public static void genTestArrayInitialization(int type, StringBuilder code) {
 		String tUName = typeUpperName[type];
 
 		code.append("\tpublic void test" + tUName + "ArrayAllocation() throws Throwable {\n");
@@ -1002,7 +1002,7 @@
 
 	//-------------------------------
 
-	public static void genCodeBinaryOp(int type1, int op, int type2, int resultType, int var1, int var2, boolean first, StringBuffer code) {
+	public static void genCodeBinaryOp(int type1, int op, int type2, int resultType, int var1, int var2, boolean first, StringBuilder code) {
 
 		String t1Name = fTypeName[type1];
 		String t1UName = typeUpperName[type1];
@@ -1031,7 +1031,7 @@
 		}
 	}
 
-	public static void genCodeUnaryOp(int type, int op, int resultType, int var, boolean first, StringBuffer code) {
+	public static void genCodeUnaryOp(int type, int op, int resultType, int var, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1050,14 +1050,14 @@
 		}
 	}
 
-	public static void genCodeLocalVarValue(int type, int var, boolean first, StringBuffer code) {
+	public static void genCodeLocalVarValue(int type, int var, boolean first, StringBuilder code) {
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
 
 		genCodeLocalVarValue(type,var, vName + tUName + "Value", first, code);
 	}
 
-	public static void genCodeLocalVarValue(int type, int var, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeLocalVarValue(int type, int var, String referenceExpression, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1079,7 +1079,7 @@
 		}
 	}
 
-	public static void genCodeLocalVarAssignment(int type, int var, int imm, boolean first, StringBuffer code) {
+	public static void genCodeLocalVarAssignment(int type, int var, int imm, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1104,7 +1104,7 @@
 		genCodeLocalVarValue(type, var, iName + tUName + "Value", false, code);
 	}
 
-	public static void genCodeAssignmentOp(int type1, int op, int type2, int var, int imm, boolean first, StringBuffer code) {
+	public static void genCodeAssignmentOp(int type1, int op, int type2, int var, int imm, boolean first, StringBuilder code) {
 		String t1Name = fTypeName[type1];
 		String t1UName = typeUpperName[type1];
 		String t2Name = fTypeName[type2];
@@ -1130,7 +1130,7 @@
 		genCodeLocalVarValue(type1, var, "tmp" + vName, false, code);
 	}
 
-	public static void genCodeCast(int type1, int type2, int imm, boolean first, StringBuffer code) {
+	public static void genCodeCast(int type1, int type2, int imm, boolean first, StringBuilder code) {
 		String t1Name = fTypeName[type1];
 		String t1UName = typeUpperName[type1];
 		String t2Name = fTypeName[type2];
@@ -1146,7 +1146,7 @@
 		}
 	}
 
-	public static void genCodePrefixOp(int type, int op, int var, boolean first, StringBuffer code) {
+	public static void genCodePrefixOp(int type, int op, int var, boolean first, StringBuilder code) {
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
@@ -1164,7 +1164,7 @@
 		genCodeLocalVarValue(type, var, "tmp" + vName, false, code);
 	}
 
-	public static void genCodePostfixOp(int type, int op, int var, boolean first, StringBuffer code) {
+	public static void genCodePostfixOp(int type, int op, int var, boolean first, StringBuilder code) {
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
@@ -1182,14 +1182,14 @@
 		genCodeLocalVarValue(type, var, "tmp" + vName, false, code);
 	}
 
-	public static void genCodeFieldValue(int type, int var, int prefix, boolean first, StringBuffer code) {
+	public static void genCodeFieldValue(int type, int var, int prefix, boolean first, StringBuilder code) {
 		String tUName = typeUpperName[type];
 		String fName = field[var];
 
 		genCodeFieldValue(type, var, prefix, fName + tUName + "Value", first, code);
 	}
 
-	public static void genCodeFieldValue(int type, int var, int prefix, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeFieldValue(int type, int var, int prefix, String referenceExpression, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1212,7 +1212,7 @@
 		}
 	}
 
-	public static void genCodeArrayLength(int type, int var, boolean first, StringBuffer code) {
+	public static void genCodeArrayLength(int type, int var, boolean first, StringBuilder code) {
 
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
@@ -1221,7 +1221,7 @@
 
 	}
 
-	public static void genCodeArrayLength(int type, int var, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeArrayLength(int type, int var, String referenceExpression, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1232,7 +1232,7 @@
 		genCodeReturnValueCheckPrimitiveType(tName + " array length", fTypeName[T_int], typeUpperName[T_int], referenceExpression, first, code);
 	}
 
-	public static void genCodeArrayValue(int type, int var, int index, boolean first, StringBuffer code) {
+	public static void genCodeArrayValue(int type, int var, int index, boolean first, StringBuilder code) {
 
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
@@ -1240,7 +1240,7 @@
 		genCodeArrayValue(type, var, index, vName + tUName + "Value[" + index + "]", first, code);
 	}
 
-	public static void genCodeArrayValue(int type, int var, int index, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeArrayValue(int type, int var, int index, String referenceExpression, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1262,7 +1262,7 @@
 		}
 	}
 
-	public static void genCodeArrayAssignment(int type, int var, int index, int imm, boolean first, StringBuffer code) {
+	public static void genCodeArrayAssignment(int type, int var, int index, int imm, boolean first, StringBuilder code) {
 
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
@@ -1287,7 +1287,7 @@
 		genCodeArrayValue(type, var, index, iName + tUName + "Value", false, code);
 	}
 
-	public static void genCodeArrayAllocation(int type, int var, int dim, boolean first, StringBuffer code) {
+	public static void genCodeArrayAllocation(int type, int var, int dim, boolean first, StringBuilder code) {
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
 		String charUName = typeUpperName[T_char];
@@ -1303,7 +1303,7 @@
 		genCodeArrayLength(type, var, iName + charUName + "Value", false, code);
 	}
 
-	public static void genCodeArrayInitialization(int type, int var, boolean first, StringBuffer code) {
+	public static void genCodeArrayInitialization(int type, int var, boolean first, StringBuilder code) {
 		String tName = fTypeName[type];
 		String tUName = typeUpperName[type];
 		String vName = fVariable[var];
@@ -1337,57 +1337,57 @@
 
 	//----------------------------
 
-	public static void genCodeEval(String expression, boolean first, StringBuffer code) {
+	public static void genCodeEval(String expression, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? "IValue " : IInternalDebugCoreConstants.EMPTY_STRING) + "value = eval(" + expression + ");\n");
 	}
 
-	public static void genCodeReturnTypeCheck(String test, String typeName, boolean first, StringBuffer code) {
+	public static void genCodeReturnTypeCheck(String test, String typeName, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? "String " : IInternalDebugCoreConstants.EMPTY_STRING) + "typeName = value.getReferenceTypeName();\n" +
 					"\t\tassertEquals(\"" + test + " : wrong type : \", \"" + typeName + "\", typeName);\n");
 	}
 
-	public static void genCodeReturnValueCheckPrimitiveType(String test, String resType, String uResType, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeReturnValueCheckPrimitiveType(String test, String resType, String uResType, String referenceExpression, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? resType + " " : IInternalDebugCoreConstants.EMPTY_STRING) + resType + "Value = ((IJavaPrimitiveValue)value).get" + uResType + "Value();\n" +
 					"\t\tassertEquals(\"" + test + " : wrong result : \", " + referenceExpression + ", " + resType+ "Value);\n");
 	}
 
-	public static void genCodeReturnValueCheckFloatDoubleType(String test, String resType, String uResType, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeReturnValueCheckFloatDoubleType(String test, String resType, String uResType, String referenceExpression, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? resType + " " : IInternalDebugCoreConstants.EMPTY_STRING) + resType + "Value = ((IJavaPrimitiveValue)value).get" + uResType + "Value();\n" +
 					"\t\tassertEquals(\"" + test + " : wrong result : \", " + referenceExpression + ", " + resType+ "Value, 0);\n");
 	}
 
-	public static void genCodeReturnValueCheckStringType(String test, String referenceExpression, boolean first, StringBuffer code) {
+	public static void genCodeReturnValueCheckStringType(String test, String referenceExpression, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? "String " : IInternalDebugCoreConstants.EMPTY_STRING) + "stringValue = ((JDIObjectValue)value).getValueString();\n" +
 					"\t\tassertEquals(\"" + test + " : wrong result : \", " + referenceExpression + ", " + "stringValue);\n");
 	}
 
-/*	public static void genCodeReturnValueCheckObjectType(String test, String referenceExpression, boolean first, StringBuffer code) {
+/*	public static void genCodeReturnValueCheckObjectType(String test, String referenceExpression, boolean first, StringBuilder code) {
 		code.append("\t\t" + ((first)? "Object " : IInternalDebugUIConstants.EMPTY_STRING) + "objectValue = ((JDIObjectValue)value).getValueString();\n" +
 					"\t\tassertEquals(\"" + test + " : wrong result : \" + " + "objectValue, " + "objectValue, " + referenceExpression + ");\n");
 	}*/
 
-	public static void genCodeSetTmp(String varName, int type, int op, String value, boolean init , StringBuffer code) {
+	public static void genCodeSetTmp(String varName, int type, int op, String value, boolean init , StringBuilder code) {
 		code.append("\t\t" + ((init)? fTypeName[type] + " " : IInternalDebugCoreConstants.EMPTY_STRING) + varName + " " + opSymbol[op] + " " + value + ";\n");
 	}
 
 
-	public static void tryBlockBegin(StringBuffer code) {
+	public static void tryBlockBegin(StringBuilder code) {
 		code.append("\t\ttry {\n\t\tinit();\n");
 	}
 
-	public static void tryBlockEnd(StringBuffer code) {
+	public static void tryBlockEnd(StringBuilder code) {
 		code.append("\t\t} finally {\n\t\tend();\n\t\t}\n");
 	}
 
 	//------------------------------
 
-	public static void createJavaFile(String className, String testClass, int breakPointLine, int frameNumber, boolean importJDIObjectValue, StringBuffer tests) throws Exception {
+	public static void createJavaFile(String className, String testClass, int breakPointLine, int frameNumber, boolean importJDIObjectValue, StringBuilder tests) throws Exception {
 		createJavaFile(className, testClass, breakPointLine, frameNumber, importJDIObjectValue, true, tests);
 	}
 
-	public static void createJavaFile(String className, String testClass, int breakPointLine, int frameNumber, boolean importJDIObjectValue, boolean importIJavaPrimitiveValue, StringBuffer tests) throws Exception {
+	public static void createJavaFile(String className, String testClass, int breakPointLine, int frameNumber, boolean importJDIObjectValue, boolean importIJavaPrimitiveValue, StringBuilder tests) throws Exception {
 
-		StringBuffer code = new StringBuffer();
+		StringBuilder code = new StringBuilder();
 
 		code.append("/*******************************************************************************\n");
 		code.append(" * Copyright (c) 2002, 2003 IBM Corporation and others.\n");
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TypeHierarchyTestsGenerator.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TypeHierarchyTestsGenerator.java
index aa38e5a..26471e6 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TypeHierarchyTestsGenerator.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/generator/TypeHierarchyTestsGenerator.java
@@ -84,7 +84,7 @@
 	}
 
 	public static void  gen_main() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTestQualifier(IAA, M1, code);
 		createTestQualifier(IAB, M1, code);
@@ -150,7 +150,7 @@
 	}
 
 	public static void gen_aa_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, AA);
 
@@ -158,7 +158,7 @@
 	}
 
 	public static void gen_ab_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, AB);
 
@@ -166,7 +166,7 @@
 	}
 
 	public static void gen_ac_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, AC);
 
@@ -174,7 +174,7 @@
 	}
 
 	public static void gen_bb_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, BB);
 
@@ -182,7 +182,7 @@
 	}
 
 	public static void gen_bc_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, BC);
 
@@ -190,7 +190,7 @@
 	}
 
 	public static void gen_cc_testA() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestA(code, CC);
 
@@ -198,7 +198,7 @@
 	}
 
 	public static void gen_bb_testB() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestB(code, BB);
 
@@ -206,7 +206,7 @@
 	}
 
 	public static void gen_bc_testB() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestB(code, BC);
 
@@ -214,7 +214,7 @@
 	}
 
 	public static void gen_cc_testB() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestB(code, CC);
 
@@ -222,7 +222,7 @@
 	}
 
 	public static void gen_cc_testC() throws Exception {
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		createTest_TestC(code, CC);
 
@@ -231,13 +231,13 @@
 
 	//-------------
 
-	public static void createTest_TestA(StringBuffer code, int qualifier) {
+	public static void createTest_TestA(StringBuilder code, int qualifier) {
 		createTest(instanceLevel[qualifier], M1, code);
 		createTest(instanceLevel[qualifier], M2, code);
 		createTest(0, S2, code);
 	}
 
-	public static void createTest_TestB(StringBuffer code, int qualifier) {
+	public static void createTest_TestB(StringBuilder code, int qualifier) {
 		createTest(instanceLevel[qualifier], M1, code);
 		createTest(instanceLevel[qualifier], M2, code);
 		createTest(1, S2, code);
@@ -248,7 +248,7 @@
 		createTestQualifier(SUPER_A, M2, code);
 	}
 
-	public static void createTest_TestC(StringBuffer code, int qualifier) {
+	public static void createTest_TestC(StringBuilder code, int qualifier) {
 		createTest(instanceLevel[qualifier], M1, code);
 		createTest(instanceLevel[qualifier], M2, code);
 		createTest(2, S2, code);
@@ -266,7 +266,7 @@
 
 	//-------------
 
-	public static void createTest(int level, int method, StringBuffer code) {
+	public static void createTest(int level, int method, StringBuilder code) {
 		String strMethod= methods[method];
 		code.append("\tpublic void testEvalNestedTypeTest_" + strMethod + "() throws Throwable {\n");
 		tryBlockBegin(code);
@@ -280,7 +280,7 @@
 	}
 
 
-	public static void createTestQualifier(int qualifier, int method, StringBuffer code) {
+	public static void createTestQualifier(int qualifier, int method, StringBuilder code) {
 		String strQualifier= qualifiers[qualifier];
 		String nameQualifier= strQualifier.replace('(', '_').replace(')', '_').replace(' ', '_');
 		String strMethod= methods[method];
@@ -299,9 +299,9 @@
 	//------------
 
 
-	public static void createJavaFile(StringBuffer tests, int lineNumber, int numberFrames, int hitCount) throws Exception {
+	public static void createJavaFile(StringBuilder tests, int lineNumber, int numberFrames, int hitCount) throws Exception {
 
-		StringBuffer code= new StringBuffer();
+		StringBuilder code= new StringBuilder();
 
 		code.append("/*******************************************************************************\n");
 		code.append(" * Copyright (c) 2002, 2003 IBM Corporation and others.\n");
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ClasspathShortenerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ClasspathShortenerTests.java
new file mode 100644
index 0000000..2dee9bf
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ClasspathShortenerTests.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Cedric Chabanois and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Cedric Chabanois (cchabanois@gmail.com) - initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.launching;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.URIUtil;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.debug.tests.connectors.MockLaunch;
+import org.eclipse.jdt.internal.launching.ClasspathShortener;
+
+public class ClasspathShortenerTests extends AbstractDebugTest {
+	private static final String MAIN_CLASS = "my.package.MainClass";
+	private static final String ENCODING_ARG = "-Dfile.encoding=UTF-8";
+	private static final String JAVA_10_PATH = "/usr/lib/jvm/java-10-jdk-amd64/bin/java";
+	private static final String JAVA_8_PATH = "/usr/lib/jvm/java-8-openjdk-amd64/bin/java";
+	private ClasspathShortenerForTest classpathShortener;
+	private String userHome;
+
+	public ClasspathShortenerTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		userHome = System.getProperty("user.home");
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		if (classpathShortener != null) {
+			classpathShortener.getProcessTempFiles().forEach(file -> file.delete());
+		}
+		super.tearDown();
+	}
+
+	public void testNoNeedToShortenShortClasspath() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-classpath", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "10.0.1", cmdLine, 4, null);
+
+		// When
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertFalse(result);
+	}
+
+	public void testShortenClasspathWhenCommandLineIsTooLong() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-classpath", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "10.0.1", cmdLine, 4, null);
+
+		// When
+		classpathShortener.setMaxCommandLineLength(100);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+	}
+
+	public void testShortenClasspathWhenClasspathArgumentIsTooLong() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-classpath", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "10.0.1", cmdLine, 4, null);
+
+		// When
+		classpathShortener.setMaxArgLength(40);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+	}
+
+	public void testForceClasspathOnlyJar() throws Exception {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-classpath", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "10.0.1", cmdLine, 4, null);
+
+		// When
+		classpathShortener.setForceUseClasspathOnlyJar(true);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(1, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { JAVA_10_PATH, ENCODING_ARG, "-classpath", classpathShortener.getProcessTempFiles().get(0).getAbsolutePath(),
+				MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+		List<File> classpathJars = getClasspathJarsFromJarManifest(classpathShortener.getProcessTempFiles().get(0));
+		assertEquals(new File(userHomePath("/workspace/myProject/bin")), classpathJars.get(0).getCanonicalFile());
+		assertEquals(new File(userHomePath("/workspace/myProject/lib/lib 1.jar")), classpathJars.get(1).getCanonicalFile());
+	}
+
+	public void testArgFileUsedForLongClasspathOnJava9() throws Exception {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-cp", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "10.0.1", cmdLine, 4, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(1, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { JAVA_10_PATH, ENCODING_ARG, "@" + classpathShortener.getProcessTempFiles().get(0).getAbsolutePath(),
+				MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+		assertEquals("-classpath " + classpath, getFileContents(classpathShortener.getProcessTempFiles().get(0)));
+	}
+
+	public void testArgFileUsedForLongModulePath() throws Exception {
+		// Given
+		String modulepath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-p", modulepath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_WIN32, "10.0.1", cmdLine, 4, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(1, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { JAVA_10_PATH, ENCODING_ARG, "@" + classpathShortener.getProcessTempFiles().get(0).getAbsolutePath(),
+				MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+		assertEquals("--module-path " + modulepath, getFileContents(classpathShortener.getProcessTempFiles().get(0)));
+	}
+
+	public void testLongClasspathAndLongModulePath() throws Exception {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/lib/lib 2.jar"), userHomePath("/workspace/myProject/lib/lib 3.jar"));
+		String modulepath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_10_PATH, ENCODING_ARG, "-cp", classpath, "-p", modulepath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_WIN32, "10.0.1", cmdLine, 6, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(2, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { JAVA_10_PATH, ENCODING_ARG, "@" + classpathShortener.getProcessTempFiles().get(0).getAbsolutePath(),
+				"@" + classpathShortener.getProcessTempFiles().get(1).getAbsolutePath(), MAIN_CLASS, "-arg1",
+				"arg2" }, classpathShortener.getCmdLine());
+		assertEquals("-classpath " + classpath, getFileContents(classpathShortener.getProcessTempFiles().get(0)));
+		assertEquals("--module-path " + modulepath, getFileContents(classpathShortener.getProcessTempFiles().get(1)));
+	}
+
+	public void testClasspathOnlyJarUsedForLongClasspathOnJava8() throws Exception {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_8_PATH, ENCODING_ARG, "-cp", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_LINUX, "1.8.0_171", cmdLine, 4, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		classpathShortener.setAllowToUseClasspathOnlyJar(true);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(1, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { JAVA_8_PATH, ENCODING_ARG, "-cp", classpathShortener.getProcessTempFiles().get(0).getAbsolutePath(),
+				MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+		List<File> classpathJars = getClasspathJarsFromJarManifest(classpathShortener.getProcessTempFiles().get(0));
+		assertEquals(new File(userHomePath("/workspace/myProject/bin")), classpathJars.get(0).getCanonicalFile());
+		assertEquals(new File(userHomePath("/workspace/myProject/lib/lib 1.jar")), classpathJars.get(1).getCanonicalFile());
+	}
+
+	public void testClasspathEnvVariableUsedForLongClasspathOnJava8OnWindows() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_8_PATH, ENCODING_ARG, "-cp", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_WIN32, "1.8.0_171", cmdLine, 4, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		Map<String, String> nativeEnvironment = new LinkedHashMap<>();
+		nativeEnvironment.put("PATH", "C:\\WINDOWS\\System32;C:\\WINDOWS");
+		classpathShortener.setNativeEnvironment(nativeEnvironment);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(0, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { "PATH=C:\\WINDOWS\\System32;C:\\WINDOWS", "CLASSPATH=" + classpath }, classpathShortener.getEnvp());
+		assertArrayEquals(new String[] { JAVA_8_PATH, ENCODING_ARG, MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+	}
+
+	public void testClasspathUsedOnWindowsWhenEnvp() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_8_PATH, ENCODING_ARG, "-cp", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		String[] envp = new String[] { "MYVAR1=value1", "MYVAR2=value2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_WIN32, "1.8.0_171", cmdLine, 4, envp);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(0, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { "MYVAR1=value1", "MYVAR2=value2", "CLASSPATH=" + classpath }, classpathShortener.getEnvp());
+		assertArrayEquals(new String[] { JAVA_8_PATH, ENCODING_ARG, MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+	}
+
+	public void testClasspathInEnvironmentReplacedOnWindows() {
+		// Given
+		String classpath = getClasspathOrModulePath(userHomePath("/workspace/myProject/bin"), userHomePath("/workspace/myProject/lib/lib 1.jar"));
+		String[] cmdLine = new String[] { JAVA_8_PATH, ENCODING_ARG, "-cp", classpath, MAIN_CLASS, "-arg1", "arg2" };
+		classpathShortener = new ClasspathShortenerForTest(Platform.OS_WIN32, "1.8.0_171", cmdLine, 4, null);
+		classpathShortener.setMaxCommandLineLength(100);
+
+		// When
+		Map<String, String> nativeEnvironment = new LinkedHashMap<>();
+		nativeEnvironment.put("PATH", "C:\\WINDOWS\\System32;C:\\WINDOWS");
+		nativeEnvironment.put("CLASSPATH", "C:\\myJars\\jar1.jar");
+		classpathShortener.setNativeEnvironment(nativeEnvironment);
+		boolean result = classpathShortener.shortenCommandLineIfNecessary();
+
+		// Then
+		assertTrue(result);
+		assertEquals(0, classpathShortener.getProcessTempFiles().size());
+		assertArrayEquals(new String[] { "PATH=C:\\WINDOWS\\System32;C:\\WINDOWS", "CLASSPATH=" + classpath }, classpathShortener.getEnvp());
+		assertArrayEquals(new String[] { JAVA_8_PATH, ENCODING_ARG, MAIN_CLASS, "-arg1", "arg2" }, classpathShortener.getCmdLine());
+	}
+
+	private String getFileContents(File file) throws UnsupportedEncodingException, IOException {
+		return new String(Files.readAllBytes(file.toPath()), "UTF-8");
+	}
+
+	private String getClasspathAttributeFromJarManifest(File jarFile) throws FileNotFoundException, IOException {
+		try (JarInputStream jarStream = new JarInputStream(new FileInputStream(jarFile))) {
+			Manifest mf = jarStream.getManifest();
+			return mf.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
+		}
+	}
+
+	private List<File> getClasspathJarsFromJarManifest(File jarFile) throws FileNotFoundException, IOException {
+		File parentDir = jarFile.getParentFile();
+		String classpath = getClasspathAttributeFromJarManifest(jarFile);
+		return Arrays.stream(classpath.split(" ")).map(relativePath -> {
+			try {
+				return new File(URIUtil.makeAbsolute(new URI(relativePath), parentDir.toURI()));
+			} catch (URISyntaxException e) {
+				throw new RuntimeException(e);
+			}
+		}).collect(Collectors.toList());
+	}
+
+	private String userHomePath(String path) {
+		return userHome + path;
+	}
+
+	private String getClasspathOrModulePath(String... classpathElements) {
+		return String.join(";", classpathElements);
+	}
+
+	private static class ClasspathShortenerForTest extends ClasspathShortener {
+		private boolean forceUseClasspathOnlyJar = false;
+		private boolean allowToUseClasspathOnlyJar = false;
+		private int maxArgLength = Integer.MAX_VALUE;
+		private int maxCommandLineLength = Integer.MAX_VALUE;
+		private Map<String, String> nativeEnvironment = new HashMap<>();
+
+		public ClasspathShortenerForTest(String os, String javaVersion, String[] cmdLine, int classpathArgumentIndex, String[] envp) {
+			super(os, javaVersion, new MockLaunch(), cmdLine, classpathArgumentIndex, null, envp);
+		}
+
+		public void setAllowToUseClasspathOnlyJar(boolean allowToUseClasspathOnlyJar) {
+			this.allowToUseClasspathOnlyJar = allowToUseClasspathOnlyJar;
+		}
+
+		public void setForceUseClasspathOnlyJar(boolean forceUseClasspathOnlyJar) {
+			this.forceUseClasspathOnlyJar = forceUseClasspathOnlyJar;
+		}
+
+		@Override
+		protected String getLaunchConfigurationName() {
+			return "launch";
+		}
+
+		@Override
+		protected String getLaunchTimeStamp() {
+			return Long.toString(System.currentTimeMillis());
+		}
+
+		@Override
+		protected boolean handleClasspathTooLongStatus() throws CoreException {
+			return allowToUseClasspathOnlyJar;
+		}
+
+		@Override
+		protected boolean getLaunchConfigurationUseClasspathOnlyJarAttribute() throws CoreException {
+			return forceUseClasspathOnlyJar;
+		}
+
+		@Override
+		protected int getMaxArgLength() {
+			return maxArgLength;
+		}
+
+		@Override
+		protected int getMaxCommandLineLength() {
+			return maxCommandLineLength;
+		}
+
+		public void setMaxArgLength(int maxArgLength) {
+			this.maxArgLength = maxArgLength;
+		}
+
+		public void setMaxCommandLineLength(int maxCommandLineLength) {
+			this.maxCommandLineLength = maxCommandLineLength;
+		}
+
+		public void setNativeEnvironment(Map<String, String> nativeEnvironment) {
+			this.nativeEnvironment = nativeEnvironment;
+		}
+
+		@Override
+		protected Map<String, String> getNativeEnvironment() {
+			return nativeEnvironment;
+		}
+
+		@Override
+		protected char getPathSeparatorChar() {
+			// always use ';' as separator (tests would fail on windows otherwise with paths c:\ ...)
+			return ';';
+		}
+
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ContributedTabTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ContributedTabTests.java
index b85f4e5..f3412f3 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ContributedTabTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ContributedTabTests.java
@@ -50,11 +50,11 @@
 		javagroup.createTabs(getLaunchConfigurationDialog(IDebugUIConstants.ID_DEBUG_LAUNCH_GROUP), ILaunchManager.DEBUG_MODE);
 		ILaunchConfigurationTab[] tabs = javagroup.getTabs();
 		assertTrue("Wrong number of tabs", tabs.length >= 11); //$NON-NLS-1$
-		Set<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		Set<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<>();
 		for(int i = 0; i < tabs.length; i++) {
 			tabset.add(tabs[i].getClass());
 		}
-		Set<Class<? extends ILaunchConfigurationTab>> contribs = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		Set<Class<? extends ILaunchConfigurationTab>> contribs = new HashSet<>();
 		contribs.add(ContributedTestTab1.class);
 		contribs.add(JavaAlernateModeTab.class);
 		assertTrue("java tab group should contain all contributed tabs", tabset.containsAll(contribs)); //$NON-NLS-1$
@@ -105,11 +105,11 @@
 		assertNotNull("java tab group cannot be null", javagroup); //$NON-NLS-1$
 		javagroup.createTabs(getLaunchConfigurationDialog(IDebugUIConstants.ID_DEBUG_LAUNCH_GROUP), ILaunchManager.DEBUG_MODE);
 		ILaunchConfigurationTab[] tabs = javagroup.getTabs();
-		HashSet<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		HashSet<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<>();
 		for (int i = 0; i < tabs.length; i++) {
 			tabset.add(tabs[i].getClass());
 		}
-		HashSet<Class<? extends ILaunchConfigurationTab>> contribs = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		HashSet<Class<? extends ILaunchConfigurationTab>> contribs = new HashSet<>();
 		contribs.add(ContributedTestTab2.class);
 		contribs.add(ContributedTestTab3.class);
 		assertTrue("the tab set must only contain test tab 2 and test tab 3", tabset.containsAll(contribs)); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchDelegateTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchDelegateTests.java
index b7944b5..9614fe2 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchDelegateTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchDelegateTests.java
@@ -85,7 +85,7 @@
 		ILaunchManager manager = getLaunchManager();
 		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add("alternate"); //$NON-NLS-1$
 		modes.add(ILaunchManager.DEBUG_MODE);
 		assertTrue("Should support mixed mode (alternate/debug)", type.supportsModeCombination(modes)); //$NON-NLS-1$
@@ -103,7 +103,7 @@
 		ILaunchManager manager = getLaunchManager();
 		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.DEBUG_MODE);
 		assertTrue("Should support mode (debug)", type.supportsModeCombination(modes)); //$NON-NLS-1$
 		ILaunchDelegate[] delegates = type.getDelegates(modes);
@@ -126,7 +126,7 @@
 		ILaunchManager manager = getLaunchManager();
 		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add("alternate"); //$NON-NLS-1$
 		assertTrue("Should support mode (alternate)", type.supportsModeCombination(modes)); //$NON-NLS-1$
 		ILaunchDelegate[] delegates = type.getDelegates(modes);
@@ -147,7 +147,7 @@
 		String[][] modesavail = {{"alternate"}, {"debug", "alternate"}, {"debug", "alternate2"}}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
 		HashSet<String> modes = null;
 		for(int i = 0; i < modesavail.length; i++) {
-			modes = new HashSet<String>(Arrays.asList(modesavail[i]));
+			modes = new HashSet<>(Arrays.asList(modesavail[i]));
 			assertTrue("Should support modes "+modes.toString(), type.supportsModeCombination(modes)); //$NON-NLS-1$
 			ILaunchDelegate[] delegates = type.getDelegates(modes);
 			assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
@@ -164,17 +164,17 @@
 		ILaunchManager manager = getLaunchManager();
 		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add("alternate2"); //$NON-NLS-1$
 		assertTrue("Should support mode 'alternate2'", type.supportsModeCombination(modes)); //$NON-NLS-1$
 		ILaunchDelegate[] delegates = type.getDelegates(modes);
 		assertTrue("missing delegate", delegates.length > 0); //$NON-NLS-1$
 		assertEquals("Wrong number of delegates, should be 2 only "+delegates.length+" found", 2, delegates.length); //$NON-NLS-1$ //$NON-NLS-2$
-		HashSet<Class<? extends ILaunchConfigurationDelegate>> dels = new HashSet<Class<? extends ILaunchConfigurationDelegate>>();
+		HashSet<Class<? extends ILaunchConfigurationDelegate>> dels = new HashSet<>();
 		for(int i = 0; i < delegates.length; i++) {
 			dels.add(delegates[i].getDelegate().getClass());
 		}
-		HashSet<Object> ds = new HashSet<Object>(Arrays.asList(new Object[] {TestLaunchDelegate1.class, TestLaunchDelegate2.class}));
+		HashSet<Object> ds = new HashSet<>(Arrays.asList(new Object[] {TestLaunchDelegate1.class, TestLaunchDelegate2.class}));
 		assertTrue("There must be only TestLaunchDelegate1 and TestLaunchDelegate2 as registered delegates for the mode alternate2 and the local java type", ds.containsAll(dels)); //$NON-NLS-1$
 	}
 
@@ -185,7 +185,7 @@
 		ILaunchManager manager = getLaunchManager();
 		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
 		assertNotNull("Missing java application launch config type", type); //$NON-NLS-1$
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add("alternate2"); //$NON-NLS-1$
 		modes.add("foo"); //$NON-NLS-1$
 		assertTrue("Should not support modes: "+modes.toString(), !type.supportsModeCombination(modes)); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchModeTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchModeTests.java
index 460398c..a7f39c4 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchModeTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchModeTests.java
@@ -176,7 +176,7 @@
 		testGroup.createTabs(dialog, "TEST_MODE"); //$NON-NLS-1$
 
 		ILaunchConfigurationTab[] tabs = standardGroup.getTabs();
-		HashSet<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		HashSet<Class<? extends ILaunchConfigurationTab>> tabset = new HashSet<>();
 		for(int i = 0; i< tabs.length; i++) {
 			tabset.add(tabs[i].getClass());
 		}
@@ -188,11 +188,11 @@
 				SourceLookupTab.class,
 				EnvironmentTab.class,
 				CommonTab.class};
-		assertTrue("Tab set does not contain all default java tabs", tabset.containsAll(new HashSet<Class<?>>(Arrays.asList(classes)))); //$NON-NLS-1$
+		assertTrue("Tab set does not contain all default java tabs", tabset.containsAll(new HashSet<>(Arrays.asList(classes)))); //$NON-NLS-1$
 
 		tabs = testGroup.getTabs();
 		assertEquals("Wrong number of tabs in the test group", 4, tabs.length); //$NON-NLS-1$
-		tabset = new HashSet<Class<? extends ILaunchConfigurationTab>>();
+		tabset = new HashSet<>();
 		for(int i = 0; i< tabs.length; i++) {
 			tabset.add(tabs[i].getClass());
 		}
@@ -201,7 +201,7 @@
 				JavaArgumentsTab.class,
 				JavaJRETab.class,
 				JavaClasspathTab.class};
-		assertTrue("Test tab set does not contain all default tabs", tabset.containsAll(new HashSet<Class<?>>(Arrays.asList(classes)))); //$NON-NLS-1$
+		assertTrue("Test tab set does not contain all default tabs", tabset.containsAll(new HashSet<>(Arrays.asList(classes)))); //$NON-NLS-1$
 		standardGroup.dispose();
 		testGroup.dispose();
 	}
@@ -223,7 +223,7 @@
 	 */
 	public void testDefaultDebugLaunchPerspective2() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes =  new HashSet<String>();
+		HashSet<String> modes =  new HashSet<>();
 		modes.add(ILaunchManager.DEBUG_MODE);
 		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
 	}
@@ -245,7 +245,7 @@
 	 */
 	public void testDefaultRunLaunchPerspective2() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.RUN_MODE);
 		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
 	}
@@ -277,7 +277,7 @@
 	 */
 	public void testResetDebugLaunchPerspective2() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.DEBUG_MODE);
 		assertEquals("Java debug perspective should be debug", IDebugUIConstants.ID_DEBUG_PERSPECTIVE, DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
 		// set to NONE
@@ -298,7 +298,7 @@
 	 */
 	public void testResetDebugPerspectiveJavaLaunchDelegate() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.DEBUG_MODE);
 		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
 		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
@@ -337,7 +337,7 @@
 	 */
 	public void testResetRunLaunchPerspective2() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.RUN_MODE);
 		assertNull("Java run perspective should be null", DebugUITools.getLaunchPerspective(javaType, null, modes)); //$NON-NLS-1$
 		// set to Java perspective
@@ -357,7 +357,7 @@
 	 */
 	public void testResetRunPerspectiveJavaLaunchDelegate() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.RUN_MODE);
 		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
 		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
@@ -378,7 +378,7 @@
 	 */
 	public void testDefaultDebugPerspectiveJavaLaunchDelegate() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.DEBUG_MODE);
 		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
 		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
@@ -394,7 +394,7 @@
 	 */
 	public void testDefaultRunPerspectiveJavaLaunchDelegate() {
 		ILaunchConfigurationType javaType = getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION);
-		HashSet<String> modes = new HashSet<String>();
+		HashSet<String> modes = new HashSet<>();
 		modes.add(ILaunchManager.RUN_MODE);
 		ILaunchDelegate delegate = ((LaunchManager)getLaunchManager()).getLaunchDelegate("org.eclipse.jdt.launching.localJavaApplication"); //$NON-NLS-1$
 		assertNotNull("Java launch delegate should not be null", delegate); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchShortcutTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchShortcutTests.java
index fabc034..2f7a922 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchShortcutTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchShortcutTests.java
@@ -144,7 +144,7 @@
 	 * @since 3.3
 	 */
 	public List<LaunchShortcutExtension> getApplicableLaunchShortcuts(String typeid) {
-		List<LaunchShortcutExtension> list = new ArrayList<LaunchShortcutExtension>();
+		List<LaunchShortcutExtension> list = new ArrayList<>();
 		LaunchShortcutExtension ext = null;
 		List<LaunchShortcutExtension> shortcuts = getLaunchConfigurationManager().getLaunchShortcuts();
 		for(int i = 0; i < shortcuts.size(); i++) {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchTests.java
index 820d110..4ad59d7 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LaunchTests.java
@@ -46,7 +46,7 @@
 		String typeName = "Breakpoints";		 //$NON-NLS-1$
 		ILaunchConfiguration configuration = getLaunchConfiguration(typeName);
 		getLaunchManager().addLaunchListener(this);
-		HashSet<String> set = new HashSet<String>();
+		HashSet<String> set = new HashSet<>();
 		set.add(ILaunchManager.DEBUG_MODE);
 		ensurePreferredDelegate(configuration, set);
 		ILaunch launch = configuration.launch(ILaunchManager.DEBUG_MODE, null);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java
new file mode 100644
index 0000000..758bcac
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Cedric Chabanois and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Cedric Chabanois (cchabanois@gmail.com) - initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.launching;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeThat;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.internal.launching.LaunchingPlugin;
+import org.eclipse.jdt.launching.AbstractVMInstall;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.JavaRuntime;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Test long classpaths. OSs have limits in term of command line length or argument length. We handle this limit differently depending on the VM
+ * version and OS.
+ *
+ */
+public class LongClassPathTests extends AbstractDebugTest {
+	private static final String MAIN_TYPE_NAME = "test.classpath.Main";
+	private static final IPath CLASSPATH_PROJECT_CONTENT_PATH = new Path("testresources/classpathProject");
+	private IJavaProject javaProject;
+	private ILaunchConfiguration launchConfiguration;
+	private IJavaThread thread;
+
+	public LongClassPathTests(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		TestSuite suite = new TestSuite();
+		suite.addTest(new LongClassPathTests("testVeryLongClasspathWithClasspathOnlyJar"));
+		if (JavaProjectHelper.isJava9Compatible()) {
+			suite.addTest(new LongClassPathTests("testVeryLongClasspathWithArgumentFile"));
+		} else if (Platform.getOS().equals(Platform.OS_WIN32)) {
+			suite.addTest(new LongClassPathTests("testVeryLongClasspathWithEnvironmentVariable"));
+		}
+		return suite;
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		try {
+			if (thread != null) {
+				terminateAndRemove(thread);
+			}
+			if (javaProject != null) {
+				javaProject.getProject().delete(true, true, null);
+			}
+			if (launchConfiguration != null) {
+				launchConfiguration.delete();
+			}
+		} catch (CoreException ce) {
+			// ignore
+		} finally {
+			super.tearDown();
+		}
+	}
+
+	/*
+	 * When classpathOnlyJar is enabled, a classpath-only jar is created.
+	 */
+	public void testVeryLongClasspathWithClasspathOnlyJar() throws Exception {
+		// Given
+		javaProject = createJavaProjectClone("testVeryLongClasspathWithClasspathOnlyJar", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_1_6_EE_NAME, true);
+		launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME);
+		int minClasspathLength = 300000;
+		setLongClasspath(javaProject, minClasspathLength);
+		launchConfiguration = enableClasspathOnlyJar(launchConfiguration);
+		waitForBuild();
+
+		// When
+		thread = launchAndSuspend(launchConfiguration);
+
+		// Then
+		File tempFile = getTempFile(thread.getLaunch()).orElseThrow(() -> new RuntimeException("No temp file"));
+		assertTrue(tempFile.exists());
+		assertTrue(tempFile.getName().endsWith(".jar"));
+		String actualClasspath = doEval(thread, "System.getProperty(\"java.class.path\")").getValueString();
+		assertTrue(actualClasspath.contains(tempFile.getAbsolutePath()));
+		assertTrue(actualClasspath.length() < minClasspathLength);
+
+		// When
+		resumeAndExit(thread);
+
+		// Then
+		if (!Platform.getOS().equals(Platform.OS_WIN32)) {
+			// On windows, temp file deletion may fail
+			assertFalse(tempFile.exists());
+		}
+	}
+
+	/*
+	 * When JVM > 9, an argument file for the classpath is created when classpath is too long
+	 */
+	public void testVeryLongClasspathWithArgumentFile() throws Exception {
+		javaProject = createJavaProjectClone("testVeryLongClasspathWithArgumentFile", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, true);
+		launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME);
+		assumeTrue(isArgumentFileSupported(launchConfiguration));
+		int minClasspathLength = 300000;
+
+		// Given
+		setLongClasspath(javaProject, minClasspathLength);
+		waitForBuild();
+
+		// When
+		thread = launchAndSuspend(launchConfiguration);
+
+		// Then
+		File tempFile = getTempFile(thread.getLaunch()).orElseThrow(() -> new RuntimeException("No temp file"));
+		assertTrue(tempFile.exists());
+		assertTrue(tempFile.getName().endsWith(".txt"));
+		assertTrue(doEval(thread, "System.getProperty(\"java.class.path\")").getValueString().length() >= minClasspathLength);
+
+		// When
+		resumeAndExit(thread);
+
+		// Then
+		if (!Platform.getOS().equals(Platform.OS_WIN32)) {
+			// On windows, temp file deletion may fail
+			assertFalse(tempFile.exists());
+		}
+	}
+
+	/*
+	 * On Windows, for JVM < 9, the CLASSPATH env variable is used if classpath is too long
+	 */
+	public void testVeryLongClasspathWithEnvironmentVariable() throws Exception {
+		assumeThat(Platform.getOS(), equalTo(Platform.OS_WIN32));
+
+		// Given
+		javaProject = createJavaProjectClone("testVeryLongClasspath", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_1_6_EE_NAME, true);
+		launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME);
+		assumeFalse(isArgumentFileSupported(launchConfiguration));
+		int minClasspathLength = 300000;
+		setLongClasspath(javaProject, minClasspathLength);
+		waitForBuild();
+
+		// When
+		thread = launchAndSuspend(launchConfiguration);
+
+		// Then
+		assertTrue(doEval(thread, "System.getProperty(\"java.class.path\")").getValueString().length() >= minClasspathLength);
+		resumeAndExit(thread);
+	}
+
+	private Optional<File> getTempFile(ILaunch launch) {
+		IProcess process = launch.getProcesses()[0];
+		String tempFile = process.getAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES);
+		if (tempFile == null) {
+			return Optional.empty();
+		}
+		return Optional.of(new File(tempFile));
+	}
+
+	private boolean isArgumentFileSupported(ILaunchConfiguration launchConfiguration) throws CoreException {
+		IVMInstall vmInstall = JavaRuntime.computeVMInstall(launchConfiguration);
+		if (vmInstall instanceof AbstractVMInstall) {
+			AbstractVMInstall install = (AbstractVMInstall) vmInstall;
+			String vmver = install.getJavaVersion();
+			if (JavaCore.compareJavaVersions(vmver, JavaCore.VERSION_9) >= 0) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private ILaunchConfiguration enableClasspathOnlyJar(ILaunchConfiguration launchConfiguration) throws CoreException {
+		ILaunchConfigurationWorkingCopy configurationWorkingCopy = launchConfiguration.getWorkingCopy();
+		configurationWorkingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, true);
+		return configurationWorkingCopy.doSave();
+	}
+
+	private ILaunchConfiguration createLaunchConfigurationStopInMain(IJavaProject javaProject, String mainTypeName) throws Exception, CoreException {
+		ILaunchConfiguration launchConfiguration;
+		launchConfiguration = createLaunchConfiguration(javaProject, mainTypeName);
+		ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy();
+		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, true);
+		launchConfiguration = wc.doSave();
+		return launchConfiguration;
+	}
+
+	private void setLongClasspath(IJavaProject javaProject, int minClassPathLength) throws Exception {
+		StringBuilder sb = new StringBuilder();
+		List<IClasspathEntry> classpathEntries = new ArrayList<>();
+		int i = 0;
+		while (sb.length() < minClassPathLength) {
+			String jarName = "library" + i + ".jar";
+			IPath targetPath = javaProject.getPath().append("lib/" + jarName);
+			javaProject.getProject().getFile("lib/classpath.jar").copy(targetPath, IResource.FORCE, new NullProgressMonitor());
+			IClasspathAttribute moduleClasspathAttribute = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true");
+			classpathEntries.add(JavaCore.newLibraryEntry(targetPath, null, null, null, new IClasspathAttribute[] {
+					moduleClasspathAttribute }, false));
+			if (i != 0) {
+				sb.append(File.pathSeparator);
+			}
+			sb.append(javaProject.getProject().getFile("lib/" + jarName).getLocation().toString());
+			i++;
+		}
+		classpathEntries.add(JavaCore.newLibraryEntry(javaProject.getPath().append("lib/classpath.jar"), null, null));
+		sb.append(File.pathSeparator);
+		sb.append(javaProject.getProject().getFile("lib/classpath.jar").getLocation().toString());
+		classpathEntries.addAll(Arrays.asList(javaProject.getRawClasspath()));
+		javaProject.setRawClasspath(classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]), null);
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongModulePathTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongModulePathTests.java
new file mode 100644
index 0000000..b22ddca
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongModulePathTests.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Cedric Chabanois and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Cedric Chabanois (cchabanois@gmail.com) - initial implementation
+ *******************************************************************************/
+package org.eclipse.jdt.debug.tests.launching;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.debug.core.IJavaThread;
+import org.eclipse.jdt.debug.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.debug.tests.AbstractDebugTest;
+import org.eclipse.jdt.internal.launching.LaunchingPlugin;
+import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathSupport;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
+
+/**
+ * Test long module-path. OSs have limits in term of command line length or argument length. We use an argument file when module-path is too long.
+ *
+ */
+public class LongModulePathTests extends AbstractDebugTest {
+	private static final IPath CLASSPATH_PROJECT_CONTENT_PATH = new Path("testresources/classpathModuleProject");
+	private static final String MAIN_TYPE_NAME = "test.classpath.Main";
+	private IJavaProject javaProject;
+	private IJavaThread thread;
+	private ILaunchConfiguration launchConfiguration;
+
+	public LongModulePathTests(String name) {
+		super(name);
+	}
+
+	@Override
+	protected void tearDown() throws Exception {
+		try {
+			if (thread != null) {
+				terminateAndRemove(thread);
+			}
+			if (javaProject != null) {
+				javaProject.getProject().delete(true, true, null);
+			}
+			if (launchConfiguration != null) {
+				launchConfiguration.delete();
+			}
+		} catch (CoreException ce) {
+			// ignore
+		} finally {
+			super.tearDown();
+		}
+	}
+
+	/*
+	 * When JVM > 9, an argument file for the modulepath is created when modulepath is too long
+	 */
+	public void testVeryLongModulepathWithArgumentFile() throws Exception {
+		// Given
+		javaProject = createJavaProjectClone("testVeryLongModulePath", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, true);
+		useComplianceFromExecutionEnvironment(javaProject);
+		useModuleForJREContainer(javaProject);
+		launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME);
+		int minModulePathLength = 300000;
+		setLongModulepath(javaProject, minModulePathLength);
+		waitForBuild();
+
+		// When
+		thread = launchAndSuspend(launchConfiguration);
+
+		// Then
+		File tempFile = getTempFile(thread.getLaunch()).orElseThrow(() -> new RuntimeException("No temp file"));
+		assertTrue(tempFile.exists());
+		assertTrue(tempFile.getName().endsWith(".txt"));
+		assertTrue(doEval(thread, "System.getProperty(\"jdk.module.path\")").getValueString().length() >= minModulePathLength);
+
+		// When
+		resumeAndExit(thread);
+
+		// Then
+		if (!Platform.getOS().equals(Platform.OS_WIN32)) {
+			// On windows, temp file deletion may fail
+			assertFalse(tempFile.exists());
+		}
+	}
+
+	private ILaunchConfiguration createLaunchConfigurationStopInMain(IJavaProject javaProject, String mainTypeName) throws Exception, CoreException {
+		ILaunchConfiguration launchConfiguration;
+		launchConfiguration = createLaunchConfiguration(javaProject, mainTypeName);
+		ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy();
+		wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, true);
+		launchConfiguration = wc.doSave();
+		return launchConfiguration;
+	}
+
+	private void setLongModulepath(IJavaProject javaProject, int minModulePathLength) throws Exception {
+		StringBuilder sb = new StringBuilder();
+		List<IClasspathEntry> classpathEntries = new ArrayList<>();
+		int i = 0;
+		while (sb.length() < minModulePathLength) {
+			String jarName = "library" + i + ".jar";
+			IPath targetPath = javaProject.getPath().append("lib/" + jarName);
+			javaProject.getProject().getFile("lib/classpath.jar").copy(targetPath, IResource.FORCE, new NullProgressMonitor());
+			IClasspathAttribute moduleClasspathAttribute = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true");
+			classpathEntries.add(JavaCore.newLibraryEntry(targetPath, null, null, null, new IClasspathAttribute[] {
+					moduleClasspathAttribute }, false));
+			if (i != 0) {
+				sb.append(File.pathSeparator);
+			}
+			sb.append(javaProject.getProject().getFile("lib/" + jarName).getLocation().toString());
+			i++;
+		}
+		IClasspathAttribute moduleClasspathAttribute = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true");
+		classpathEntries.add(JavaCore.newLibraryEntry(javaProject.getPath().append("lib/classpath.jar"), null, null, null, new IClasspathAttribute[] {
+				moduleClasspathAttribute }, false));
+		sb.append(File.pathSeparator);
+		sb.append(javaProject.getProject().getFile("lib/classpath.jar").getLocation().toString());
+		classpathEntries.addAll(Arrays.asList(javaProject.getRawClasspath()));
+		javaProject.setRawClasspath(classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]), null);
+	}
+
+	private void useComplianceFromExecutionEnvironment(IJavaProject javaProject) throws JavaModelException {
+		IExecutionEnvironment executionEnvironment = getExecutionEnvironment(javaProject);
+		Map<String, String> eeOptions = BuildPathSupport.getEEOptions(executionEnvironment);
+		eeOptions.forEach((optionName, optionValue) -> javaProject.setOption(optionName, optionValue));
+	}
+
+	private IExecutionEnvironment getExecutionEnvironment(IJavaProject javaProject) throws JavaModelException {
+		IClasspathEntry[] entries = javaProject.getRawClasspath();
+		for (int i = 0; i < entries.length; i++) {
+			IClasspathEntry entry = entries[i];
+			if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+				String eeId = JavaRuntime.getExecutionEnvironmentId(entry.getPath());
+				if (eeId != null) {
+					return JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(eeId);
+				}
+			}
+		}
+		return null;
+	}
+
+	private void useModuleForJREContainer(IJavaProject javaProject) throws JavaModelException {
+		IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
+		for (int i = 0; i < rawClasspath.length; i++) {
+			IClasspathEntry classpathEntry = rawClasspath[i];
+			if (classpathEntry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
+				IClasspathAttribute moduleClasspathAttribute = JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true");
+				classpathEntry = JavaCore.newContainerEntry(classpathEntry.getPath(), classpathEntry.getAccessRules(), new IClasspathAttribute[] {
+						moduleClasspathAttribute }, classpathEntry.isExported());
+				rawClasspath[i] = classpathEntry;
+			}
+		}
+		javaProject.setRawClasspath(rawClasspath, null);
+	}
+
+	private Optional<File> getTempFile(ILaunch launch) {
+		IProcess process = launch.getProcesses()[0];
+		String tempFile = process.getAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES);
+		if (tempFile == null) {
+			return Optional.empty();
+		}
+		return Optional.of(new File(tempFile));
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/PListParserTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/PListParserTests.java
index a583941..fc1e37b 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/PListParserTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/PListParserTests.java
@@ -49,7 +49,7 @@
 			Object[] jres = (Object[]) obj;
 			assertEquals("Should be 3 entries in the array", 3, jres.length);
 			// the first map
-			HashMap<String, Comparable<?>> map = new HashMap<String, Comparable<?>>();
+			HashMap<String, Comparable<?>> map = new HashMap<>();
 			map.put("JVMArch", "i386");
 			map.put("JVMBundleID", "com.apple.javajdk15");
 			map.put("JVMEnabled", Boolean.TRUE);
@@ -62,7 +62,7 @@
 			map.put("testint", new Integer(42));
 			assertEquals("Incorrect values parsed", map, jres[0]);
 
-			map = new HashMap<String, Comparable<?>>();
+			map = new HashMap<>();
 			map.put("JVMArch", "x86_64");
 			map.put("JVMBundleID", "com.apple.javajdk16");
 			map.put("JVMEnabled", Boolean.TRUE);
@@ -73,7 +73,7 @@
 			map.put("JVMVersion", "1.6.0_20");
 			assertEquals("Incorrect values parsed", map, jres[1]);
 
-			map = new HashMap<String, Comparable<?>>();
+			map = new HashMap<>();
 			map.put("JVMArch", "x86_64");
 			map.put("JVMBundleID", "com.apple.javajdk15");
 			map.put("JVMEnabled", Boolean.TRUE);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ProjectClasspathVariableTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ProjectClasspathVariableTests.java
index de033d5..644580c 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ProjectClasspathVariableTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ProjectClasspathVariableTests.java
@@ -98,7 +98,7 @@
 		IProject project = get14Project().getProject();
 		setSelection(project);
 		String cp = manager.performStringSubstitution("${project_classpath}");
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		// expecting default output location and A.jar
 		buffer.append(ResourcesPlugin.getWorkspace().getRoot().getFolder(get14Project().getOutputLocation()).getLocation().toOSString());
 		buffer.append(File.pathSeparatorChar);
@@ -125,7 +125,7 @@
 		IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
 		String projectName = get14Project().getElementName();
 		String cp = manager.performStringSubstitution("${project_classpath:" + projectName + "}");
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		// expecting default output location and A.jar
 		buffer.append(ResourcesPlugin.getWorkspace().getRoot().getFolder(get14Project().getOutputLocation()).getLocation().toOSString());
 		buffer.append(File.pathSeparatorChar);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/BreakpointManagerPerfTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/BreakpointManagerPerfTests.java
index 72f1551..ef5358a 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/BreakpointManagerPerfTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/BreakpointManagerPerfTests.java
@@ -53,7 +53,7 @@
 		assertTrue("The type "+fgTypeName+" must be a file", type.getResource().getType() == IResource.FILE);
 		IEditorPart editor = openEditor((IFile)type.getResource());
 		assertNotNull("the editor for "+fgTypeName+" should have been created", editor);
-		ArrayList<IBreakpoint> bps = new ArrayList<IBreakpoint>(count);
+		ArrayList<IBreakpoint> bps = new ArrayList<>(count);
 		IBreakpoint bp = createClassPrepareBreakpoint(type);
 		if(bp != null) {
 			bps.add(bp);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfDebugBaselineTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfDebugBaselineTest.java
index 1d52314..0ee727e 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfDebugBaselineTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/performance/PerfDebugBaselineTest.java
@@ -28,7 +28,7 @@
     public void testBaseline() {
         tagAsSummary("Baseline Test", Dimension.ELAPSED_PROCESS);
         Performance perf = Performance.getDefault();
-        StringBuffer buffer = new StringBuffer();
+        StringBuilder buffer = new StringBuilder();
         for (int i = 0; i < 10000; i++) {
             buffer.append("at org.eclipse.jdt.internal.debug.core.model.JDILocalVariable.retrieveValue(JDILocalVariable.java:56\n");
         }
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MemberParser.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MemberParser.java
index 6d7badb..ce71648 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MemberParser.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MemberParser.java
@@ -64,7 +64,7 @@
 		newname = newname.replace('$','.');//ensure proper format was used.
 		String parsed[] = newname.split("\\."); //$NON-NLS-1$
 		//make list of types to find
-		ArrayList<String> typeList = new ArrayList<String>();
+		ArrayList<String> typeList = new ArrayList<>();
 		for (int splitNum = 0; splitNum < parsed.length; splitNum++) {
 			typeList.add(parsed[splitNum]);
 		}
@@ -78,7 +78,7 @@
 	private static ICompilationUnit[] getAllCompilationUnits(IPackageFragment[] fragments) throws JavaModelException {
 		if(fragments == null)
 			return null;
-		final Set<ICompilationUnit> results = new HashSet<ICompilationUnit>();
+		final Set<ICompilationUnit> results = new HashSet<>();
 		for (int fragmentNum = 0; fragmentNum < fragments.length; fragmentNum++) {
 			if(fragments[fragmentNum].containsJavaResources()){
 				ICompilationUnit cunits[] = fragments[fragmentNum].getCompilationUnits();
@@ -114,7 +114,7 @@
 		if(types==null)
 			return null;
 
-		final Set<IMethod> results = new HashSet<IMethod>();
+		final Set<IMethod> results = new HashSet<>();
 		for (int typeNum = 0; typeNum < types.length; typeNum++) {
 			IMethod[] methods = types[typeNum].getMethods();
 			for (int methodNum = 0; methodNum < methods.length; methodNum++) {
@@ -132,7 +132,7 @@
 	 * @throws JavaModelException
 	 */
 	private static IPackageFragment[] getAllPackageFragments(IProject[] projects) throws JavaModelException {
-		final Set<IPackageFragment> results = new HashSet<IPackageFragment>();
+		final Set<IPackageFragment> results = new HashSet<>();
 		for (int projectNum = 0; projectNum < projects.length; projectNum++) {
 			IJavaProject javaProj = JavaCore.create(projects[projectNum]);
 			if(javaProj!= null && javaProj.exists() && javaProj.hasChildren()){
@@ -162,7 +162,7 @@
 		if(cunits == null)
 			return null;
 
-		final Set<IType> results = new HashSet<IType>();
+		final Set<IType> results = new HashSet<>();
 		for (int cunitNum = 0; cunitNum < cunits.length; cunitNum++) {
 			IType types[] = cunits[cunitNum].getTypes(); //get all topLevel types
 			for (int typeNum = 0; typeNum < types.length; typeNum++) {
@@ -182,7 +182,7 @@
 	private static IType[] getAllTypes(IMethod[] methods) throws JavaModelException {
 		if(methods==null)
 			return null;
-		final Set<IJavaElement> results = new HashSet<IJavaElement>();
+		final Set<IJavaElement> results = new HashSet<>();
 		for (int methodNum = 0; methodNum < methods.length; methodNum++) {
 			IJavaElement[] children = methods[methodNum].getChildren();
 			for (int childNum = 0; childNum < children.length; childNum++) {
@@ -205,7 +205,7 @@
 		if(types == null)
 			return null;
 		IType[] newtypes = types;
-		final Set<IType> results = new HashSet<IType>();
+		final Set<IType> results = new HashSet<>();
 		//get all the obvious type declarations
 		for (int mainTypeNum = 0; mainTypeNum < newtypes.length; mainTypeNum++) {
 			IType declaredTypes[] = newtypes[mainTypeNum].getTypes();
@@ -243,7 +243,7 @@
 	 * @throws JavaModelException
 	 */
 	private static IPackageFragment[] getAllPackageFragments(String packageName, IProject[] projects) throws JavaModelException{
-		final Set<IPackageFragment> results = new HashSet<IPackageFragment>();
+		final Set<IPackageFragment> results = new HashSet<>();
 		for (int projectNum = 0; projectNum < projects.length; projectNum++) {
 			IJavaProject javaProj = JavaCore.create(projects[projectNum]);
 			if(javaProj!= null && javaProj.exists() && javaProj.hasChildren()){
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MockReorgQueries.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MockReorgQueries.java
index 6717f90..6492c41 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MockReorgQueries.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/refactoring/MockReorgQueries.java
@@ -18,7 +18,7 @@
 import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgQueries;
 
 public class MockReorgQueries implements IReorgQueries {
-	private final List<Integer> fQueriesRun= new ArrayList<Integer>();
+	private final List<Integer> fQueriesRun= new ArrayList<>();
 
 	@Override
 	public IConfirmQuery createYesNoQuery(String queryTitle, boolean allowCancel, int queryID) {
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DetailPaneManagerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DetailPaneManagerTests.java
index 62bec77..5084832 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DetailPaneManagerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DetailPaneManagerTests.java
@@ -69,7 +69,7 @@
 		String id = fManager.getUserPreferredDetailPane(new HashSet<String>());
 		assertEquals("Incorrect pane ID", null, id);
 
-		Set<String> detailPanes = new HashSet<String>();
+		Set<String> detailPanes = new HashSet<>();
 		detailPanes.add("NewPane1");
 		id = fManager.getUserPreferredDetailPane(detailPanes);
 		assertEquals("Incorrect pane ID", null, id);
@@ -101,7 +101,7 @@
 		id = fManager.getUserPreferredDetailPane(null);
 		assertEquals("Incorrect pane ID", null, id);
 
-		Set<String> detailPanes = new HashSet<String>();
+		Set<String> detailPanes = new HashSet<>();
 		detailPanes.add("Example1");
 		fManager.setPreferredDetailPane(detailPanes, "Example1");
 		id = fManager.getUserPreferredDetailPane(detailPanes);
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/InstructionPointerManagerTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/InstructionPointerManagerTests.java
index ec5a30b..17c41ba 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/InstructionPointerManagerTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/InstructionPointerManagerTests.java
@@ -67,7 +67,7 @@
 	private MyPerspectiveListener fPerspectiveListener;
 	private MyAnnotationListener fAnnotationListener;
 	private IPartListener2 fPartListener;
-	private Set<IAnnotationModel> fAnnotationModelsWithListeners = new HashSet<IAnnotationModel>();
+	private Set<IAnnotationModel> fAnnotationModelsWithListeners = new HashSet<>();
 
 	private static final String typeThreadStack = "org.eclipse.debug.tests.targets.ThreadStack";
 	private static final String typeClassOne = "org.eclipse.debug.tests.targets.ClassOne";
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java
index 4a3d594..b8fe58d 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java
@@ -132,7 +132,7 @@
 	}
 
 	private List<?> getJavaElementMatches(final String textData) {
-		final List<?> matches = new ArrayList<Object>();
+		final List<?> matches = new ArrayList<>();
 		Display.getDefault().syncExec(new Runnable() {
 			@Override
 			public void run() {
@@ -145,7 +145,7 @@
 	private void setupTypeTest(String typeName) throws CoreException {
 		IPackageFragment pack= fSourceFolder.createPackageFragment("p", false, null);
 		((IContainer)pack.getUnderlyingResource()).setDefaultCharset("UTF-8", null);
-		StringBuffer buf= new StringBuffer();
+		StringBuilder buf= new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class " + typeName + " {\n");
 		buf.append("	void getMatching$Pattern(){\n");
@@ -302,7 +302,7 @@
 	// method tests
 	private void setupMethodTest() throws JavaModelException {
 		IPackageFragment pack= fSourceFolder.createPackageFragment("p", false, null);
-		StringBuffer buf= new StringBuffer();
+		StringBuilder buf= new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class OpenFromClipboardTests {\n");
 		buf.append("	private void invokeOpenFromClipboardCommand() {\n");
@@ -385,7 +385,7 @@
 
 	private void setupMethodWithDollarSignTest() throws JavaModelException {
 		IPackageFragment pack = fSourceFolder.createPackageFragment("p", false, null);
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class OpenFromClipboard$Tests {\n");
 		buf.append("	private void invokeOpenFromClipboardCommand() {\n");
@@ -434,7 +434,7 @@
 	// member tests
 	private void setupMemberTest() throws JavaModelException {
 		IPackageFragment pack = fSourceFolder.createPackageFragment("p", false, null);
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class OpenFromClipboardTests {\n");
 		buf.append("	private void invokeOpenFromClipboardCommand(String s) {\n");
@@ -500,7 +500,7 @@
 
 	private void setupQualifiedNameWithDollarSignTest() throws JavaModelException {
 		IPackageFragment pack = fSourceFolder.createPackageFragment("p", false, null);
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class OpenFromClipboard$Tests {\n");
 		buf.append("	private void invokeOpenFromClipboardCommand() {\n");
@@ -547,7 +547,7 @@
 	// stack element tests
 	private void setupStackElementTest() throws JavaModelException {
 		IPackageFragment pack = fSourceFolder.createPackageFragment("p", false, null);
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		buf.append("package p;\n");
 		buf.append("public class OpenFromClipboardTests {\n");
 		buf.append("	private void invokeOpenFromClipboardCommand(char ch) {\n");
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/ViewManagementTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/ViewManagementTests.java
index bd5d010..d2469fb 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/ViewManagementTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/ViewManagementTests.java
@@ -258,13 +258,13 @@
 	}
 
 	protected String buildRemainingEventsMessage() {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		partsMessage("Parts did not open: ", fExpectingOpenEvents, buffer);
 		partsMessage("Parts did not close: ", fExpectingCloseEvents, buffer);
 		return buffer.toString();
 	}
 
-	private void partsMessage(String header, List<String> partIds, StringBuffer buffer) {
+	private void partsMessage(String header, List<String> partIds, StringBuilder buffer) {
 		String[] ids = partIds.toArray(new String[partIds.size()]);
 		if (ids.length > 0) {
 			buffer.append(header);
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 e31a48a..f35f589 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
@@ -78,7 +78,7 @@
 			createLineBreakpoint(10, typename);
 			thread = launchToBreakpoint(typename);
 			assertNotNull("The program did not suspend", thread);
-			String snippet = "StringBuffer buf = new StringBuffer();\n"
+			String snippet = "StringBuilder buf = new StringBuilder();\n"
 					+ "buf.append(\"{\");\n"
 					+ "Iterator i = this.entrySet().iterator();\n"
 					+ "boolean hasNext = i.hasNext();\n"
@@ -129,7 +129,7 @@
 			createLineBreakpoint(10, typename);
 			thread = launchToBreakpoint(typename);
 			assertNotNull("The program did not suspend", thread);
-			String snippet = "StringBuffer buf = new StringBuffer();\n"
+			String snippet = "StringBuilder buf = new StringBuilder();\n"
 					+ "buf.append(this);\n"
 					+ "return buf.toString();";
 			formatter = new DetailFormatter("java.util.HashMap", snippet, true);
diff --git a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
index bd2d5f9..142b919 100644
--- a/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF
@@ -39,8 +39,8 @@
  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.debug.ui;bundle-version="[3.13.100,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.10.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.jdt.debug;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.jdt.ui;bundle-version="[3.15.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)",
@@ -50,7 +50,7 @@
  com.ibm.icu,
  org.eclipse.ui.forms;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.core.resources,
- org.eclipse.debug.core;bundle-version="[3.9.0,4.0.0)"
+ org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Automatic-Module-Name: org.eclipse.jdt.debug.ui
diff --git a/org.eclipse.jdt.debug.ui/plugin.xml b/org.eclipse.jdt.debug.ui/plugin.xml
index 7d4b03a..9cdacd2 100644
--- a/org.eclipse.jdt.debug.ui/plugin.xml
+++ b/org.eclipse.jdt.debug.ui/plugin.xml
@@ -2495,6 +2495,12 @@
             class="org.eclipse.jdt.internal.debug.ui.EvaluationStackFrameContextStatusHandler"
             id="org.eclipse.jdt.debug.ui.statusHandler.evaluationStackFrameContextStatusHandler"
             plugin="org.eclipse.jdt.debug"/>
+      <statusHandler
+            class="org.eclipse.jdt.internal.debug.ui.launcher.ClasspathTooLongStatusHandler"
+            code="125"
+            id="org.eclipse.jdt.debug.ui.statusHandler.classpathTooLongStatusHandler"
+            plugin="org.eclipse.jdt.launching">
+      </statusHandler>
    </extension>
    <extension
          point="org.eclipse.debug.core.sourceLocators">
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/JavaUISourceLocator.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/JavaUISourceLocator.java
index f6b0a52..522755e 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/JavaUISourceLocator.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/JavaUISourceLocator.java
@@ -283,7 +283,7 @@
 		String handle = fJavaProject.getHandleIdentifier();
 		String findAll = Boolean.valueOf(isFindAllSourceElements()).toString();
 
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append("<project>"); //$NON-NLS-1$
 		buffer.append(handle);
 		buffer.append("</project>"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
index 0135a65..46175ab 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/breakpoints/JavaBreakpointConditionEditor.java
@@ -780,13 +780,13 @@
 
 		gc.dispose();
 
-		StringBuffer dashes= new StringBuffer();
+		StringBuilder dashes= new StringBuilder();
 		int chars= (((width - fMessageLength) / fSeparatorWidth) / 2) - 2;
 		for (int i= 0; i < chars; i++) {
 			dashes.append('-');
 		}
 
-		StringBuffer result= new StringBuffer();
+		StringBuilder result= new StringBuilder();
 		result.append(dashes);
 		result.append(" " + separatorLabel + " "); //$NON-NLS-1$//$NON-NLS-2$
 		result.append(dashes);
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 ff7f8f5..6fadda6 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
@@ -96,6 +96,7 @@
 	protected ILaunchConfiguration fLaunchConfiguration;
 
 	private Button fExcludeTestCodeButton;
+	private Button fUseClasspathOnlyJarButton;
 
 	/**
 	 * Constructor
@@ -155,6 +156,14 @@
 				updateLaunchConfigurationDialog();
 			}
 		});
+		fUseClasspathOnlyJarButton = SWTFactory.createCheckButton(comp, LauncherMessages.VMArgumentsBlock_1, null, false, 1);
+		fUseClasspathOnlyJarButton.addSelectionListener(new SelectionAdapter() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				setDirty(true);
+				updateLaunchConfigurationDialog();
+			}
+		});
 	}
 
 	/**
@@ -228,6 +237,7 @@
 		fClasspathViewer.getTreeViewer().expandToLevel(2);
 		try {
 			fExcludeTestCodeButton.setSelection(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_EXCLUDE_TEST_CODE, false));
+			fUseClasspathOnlyJarButton.setSelection(configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, false));
 		} catch (CoreException e) {
 		}
 	}
@@ -321,6 +331,7 @@
 			catch (CoreException e) {
 				JDIDebugUIPlugin.statusDialog(LauncherMessages.JavaClasspathTab_Unable_to_save_classpath_1, e.getStatus());
 			}
+			configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, fUseClasspathOnlyJarButton.getSelection());
 		}
 	}
 
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 0c73fed..8573e9d 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
@@ -364,7 +364,7 @@
 			if (editor instanceof StringFieldEditor) {
 				String value = ((StringFieldEditor)editor).getStringValue();
 				if (!arg.isValid(value)) {
-					StringBuffer label = new StringBuffer(LegacyActionTools.removeMnemonics(arg.label()));
+					StringBuilder label = new StringBuilder(LegacyActionTools.removeMnemonics(arg.label()));
 					if (label.lastIndexOf(ConnectMessages.SocketConnectionLabelSeparator) == label.length() - 1) {
 						label = label.deleteCharAt(label.length() - 1);
 					}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaJRETab.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaJRETab.java
index 33f200f..fa87bd3 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaJRETab.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/debug/ui/launchConfigurations/JavaJRETab.java
@@ -220,6 +220,11 @@
 		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_NAME, (String)null);
 		configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_INSTALL_TYPE, (String)null);
 
+		// we don't want to use classpath only jars for modular projects
+		if (JavaRuntime.isModularConfiguration(configuration)) {
+			configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, false);
+		}
+
 		// Handle any attributes in the VM-specific area
 		ILaunchConfigurationTab dynamicTab = getDynamicTab();
 		if (dynamicTab == null) {
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 5750161..a60e1e6 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
@@ -219,7 +219,7 @@
 			if (item instanceof IJavaVariable) {
 				return getVariableText((IJavaVariable) item);
 			} else if (item instanceof IStackFrame) {
-				StringBuffer label= new StringBuffer(getStackFrameText((IStackFrame) item));
+				StringBuilder label= new StringBuilder(getStackFrameText((IStackFrame) item));
 				if (item instanceof IJavaStackFrame) {
 					if (((IJavaStackFrame)item).isOutOfSynch()) {
 						label.append(DebugUIMessages.JDIModelPresentation___out_of_synch__1);
@@ -249,7 +249,7 @@
 			} else if (item instanceof NoMonitorInformationElement) {
                 return DebugUIMessages.JDIModelPresentation_5;
             } else {
-				StringBuffer label= new StringBuffer();
+				StringBuilder label= new StringBuilder();
 				if (item instanceof IJavaThread) {
 					label.append(getThreadText((IJavaThread) item, showQualified));
 					if (((IJavaThread)item).isOutOfSynch()) {
@@ -313,7 +313,7 @@
 	 * Build the text for an IJavaThread.
 	 */
 	protected String getThreadText(IJavaThread thread, boolean qualified) throws CoreException {
-		StringBuffer key = new StringBuffer("thread_"); //$NON-NLS-1$
+		StringBuilder key = new StringBuilder("thread_"); //$NON-NLS-1$
 		String[] args = null;
 		IBreakpoint[] breakpoints= thread.getBreakpoints();
 		if (thread.isDaemon()) {
@@ -461,7 +461,7 @@
 		}
 		boolean isObject= isObjectValue(signature);
 		boolean isArray= value instanceof IJavaArray;
-		StringBuffer buffer= new StringBuffer();
+		StringBuilder buffer= new StringBuilder();
 		if(isUnknown(signature)) {
 			buffer.append(signature);
 		} else if (isObject && !isString && (refTypeName.length() > 0)) {
@@ -507,7 +507,7 @@
 		return buffer.toString().trim();
 	}
 
-	private StringBuffer appendUnsignedText(IJavaValue value, StringBuffer buffer) throws DebugException {
+	private StringBuilder appendUnsignedText(IJavaValue value, StringBuilder buffer) throws DebugException {
 		String unsignedText= getValueUnsignedText(value);
 		if (unsignedText != null) {
 			buffer.append(" ["); //$NON-NLS-1$
@@ -517,7 +517,7 @@
 		return buffer;
 	}
 
-	protected StringBuffer appendHexText(IJavaValue value, StringBuffer buffer) throws DebugException {
+	protected StringBuilder appendHexText(IJavaValue value, StringBuilder buffer) throws DebugException {
 		String hexText = getValueHexText(value);
 		if (hexText != null) {
 			buffer.append(" ["); //$NON-NLS-1$
@@ -527,7 +527,7 @@
 		return buffer;
 	}
 
-	protected StringBuffer appendCharText(IJavaValue value, StringBuffer buffer) throws DebugException {
+	protected StringBuilder appendCharText(IJavaValue value, StringBuilder buffer) throws DebugException {
 		String charText= getValueCharText(value);
 		if (charText != null) {
 			buffer.append(" ["); //$NON-NLS-1$
@@ -634,7 +634,7 @@
 				return null;
 		}
 		char charValue= (char)longValue;
-		StringBuffer charText = new StringBuffer();
+		StringBuilder charText = new StringBuilder();
 		if (Character.getType(charValue) == Character.CONTROL) {
 			Character ctrl = new Character((char) (charValue + 64));
 			charText.append('^');
@@ -1276,7 +1276,7 @@
 		} catch (DebugException e1) {
 		}
 		boolean showTypes= isShowVariableTypeNames();
-		StringBuffer buff= new StringBuffer();
+		StringBuilder buff= new StringBuilder();
 		String typeName= DebugUIMessages.JDIModelPresentation_unknown_type__2;
 		try {
 			typeName= var.getReferenceTypeName();
@@ -1399,7 +1399,7 @@
 
 	protected String getExpressionText(IExpression expression) throws DebugException {
 		boolean showTypes= isShowVariableTypeNames();
-		StringBuffer buff= new StringBuffer();
+		StringBuilder buff= new StringBuilder();
 		IJavaValue javaValue= (IJavaValue) expression.getValue();
 		if (javaValue != null) {
 			String typeName=null;
@@ -1422,7 +1422,7 @@
 			}
 		}
 		// Edit the snippet to make it easily viewable in one line
-		StringBuffer snippetBuffer = new StringBuffer();
+		StringBuilder snippetBuffer = new StringBuilder();
 		String snippet = expression.getExpressionText().trim();
 		snippetBuffer.append('"');
 		if (snippet.length() > 30){
@@ -1459,7 +1459,7 @@
 		if (firstBracket < 0) {
 			return typeName;
 		}
-		StringBuffer buffer= new StringBuffer(typeName);
+		StringBuilder buffer= new StringBuilder(typeName);
 		buffer.insert(firstBracket + 1, Integer.toString(arrayIndex));
 		return buffer.toString();
 	}
@@ -1493,7 +1493,7 @@
 			return null;
 		}
 
-		StringBuffer buff= new StringBuffer();
+		StringBuilder buff= new StringBuilder();
 		long longValue;
 		char sigValue = sig.charAt(0);
 		try {
@@ -1572,7 +1572,7 @@
 			if (suffix == null) {
 				return label;
 			}
-			StringBuffer buffer = new StringBuffer(label);
+			StringBuilder buffer = new StringBuilder(label);
 			buffer.append(suffix);
 			return buffer.toString();
 	    } catch (CoreException e) {
@@ -1603,7 +1603,7 @@
 		        }
 		    }
 		}
-		StringBuffer label= new StringBuffer(sourceName);
+		StringBuilder label= new StringBuilder(sourceName);
 		appendLineNumber(breakpoint, label);
 		appendHitCount(breakpoint, label);
 		appendSuspendPolicy(breakpoint,label);
@@ -1618,7 +1618,7 @@
 	}
 
 	protected String getExceptionBreakpointText(IJavaExceptionBreakpoint breakpoint) throws CoreException {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		String typeName = breakpoint.getTypeName();
 		if (typeName != null) {
 			buffer.append(getQualifiedName(typeName));
@@ -1657,7 +1657,7 @@
 	protected String getLineBreakpointText(IJavaLineBreakpoint breakpoint) throws CoreException {
 		String typeName= breakpoint.getTypeName();
 		IMember member= BreakpointUtils.getMember(breakpoint);
-		StringBuffer label= new StringBuffer();
+		StringBuilder label= new StringBuilder();
 		if (typeName != null) {
 			label.append(getQualifiedName(typeName));
 		}
@@ -1678,7 +1678,7 @@
 
 	protected String getClassPrepareBreakpointText(IJavaClassPrepareBreakpoint breakpoint) throws CoreException {
 		String typeName= breakpoint.getTypeName();
-		StringBuffer label = new StringBuffer();
+		StringBuilder label = new StringBuilder();
 		if (typeName != null) {
 			label.append(getQualifiedName(typeName));
 		}
@@ -1687,7 +1687,7 @@
 		return label.toString();
 	}
 
-	protected StringBuffer appendLineNumber(IJavaLineBreakpoint breakpoint, StringBuffer label) throws CoreException {
+	protected StringBuilder appendLineNumber(IJavaLineBreakpoint breakpoint, StringBuilder label) throws CoreException {
 		int lineNumber= breakpoint.getLineNumber();
 		if (lineNumber > 0) {
 			label.append(" ["); //$NON-NLS-1$
@@ -1700,7 +1700,7 @@
 		return label;
 	}
 
-	protected StringBuffer appendHitCount(IJavaBreakpoint breakpoint, StringBuffer label) throws CoreException {
+	protected StringBuilder appendHitCount(IJavaBreakpoint breakpoint, StringBuilder label) throws CoreException {
 		int hitCount= breakpoint.getHitCount();
 		if (hitCount > 0) {
 			label.append(" ["); //$NON-NLS-1$
@@ -1715,7 +1715,7 @@
 	protected String getJavaPatternBreakpointText(@SuppressWarnings("deprecation") IJavaPatternBreakpoint breakpoint) throws CoreException {
 		IResource resource= breakpoint.getMarker().getResource();
 		IMember member= BreakpointUtils.getMember(breakpoint);
-		StringBuffer label= new StringBuffer(resource.getName());
+		StringBuilder label= new StringBuilder(resource.getName());
 		appendLineNumber(breakpoint, label);
 		appendHitCount(breakpoint, label);
 		appendSuspendPolicy(breakpoint,label);
@@ -1731,7 +1731,7 @@
 
 	protected String getJavaTargetPatternBreakpointText(IJavaTargetPatternBreakpoint breakpoint) throws CoreException {
 		IMember member= BreakpointUtils.getMember(breakpoint);
-		StringBuffer label= new StringBuffer(breakpoint.getSourceName());
+		StringBuilder label= new StringBuilder(breakpoint.getSourceName());
 		appendLineNumber(breakpoint, label);
 		appendHitCount(breakpoint, label);
 		appendSuspendPolicy(breakpoint,label);
@@ -1748,7 +1748,7 @@
 	protected String getWatchpointText(IJavaWatchpoint watchpoint) throws CoreException {
 		String typeName= watchpoint.getTypeName();
 		IMember member= BreakpointUtils.getMember(watchpoint);
-		StringBuffer label= new StringBuffer();
+		StringBuilder label= new StringBuilder();
 		if (typeName != null) {
 			label.append(getQualifiedName(typeName));
 		}
@@ -1780,7 +1780,7 @@
 	protected String getMethodBreakpointText(IJavaMethodBreakpoint methodBreakpoint) throws CoreException {
 		String typeName= methodBreakpoint.getTypeName();
 		IMember member= BreakpointUtils.getMember(methodBreakpoint);
-		StringBuffer label= new StringBuffer();
+		StringBuilder label= new StringBuilder();
 		if (typeName != null) {
 			label.append(getQualifiedName(typeName));
 		}
@@ -1821,7 +1821,7 @@
 	protected String getStackFrameText(IStackFrame stackFrame) throws DebugException {
 		IJavaStackFrame frame= stackFrame.getAdapter(IJavaStackFrame.class);
 		if (frame != null) {
-			StringBuffer label= new StringBuffer();
+			StringBuilder label= new StringBuilder();
 
 			String dec= DebugUIMessages.JDIModelPresentation_unknown_declaring_type__4;
 			try {
@@ -1946,7 +1946,7 @@
 		}
 		// get the list of the parameters and generates their simple name
 		List<String> parameters= getNameList(qualifiedName.substring(parameterStart + 1, qualifiedName.length() - 1));
-		StringBuffer name= new StringBuffer(getSimpleName(qualifiedName.substring(0, parameterStart)));
+		StringBuilder name= new StringBuilder(getSimpleName(qualifiedName.substring(0, parameterStart)));
 		name.append('<');
 		Iterator<String> iterator= parameters.iterator();
 		if (iterator.hasNext()) {
@@ -2019,28 +2019,28 @@
 		public void computeDetail(IValue value, IJavaThread thread, IValueDetailListener listener) throws DebugException;
 	}
 
-	protected void appendSuspendPolicy(IJavaBreakpoint breakpoint, StringBuffer buffer) throws CoreException {
+	protected void appendSuspendPolicy(IJavaBreakpoint breakpoint, StringBuilder buffer) throws CoreException {
 		if (breakpoint.getSuspendPolicy() == IJavaBreakpoint.SUSPEND_VM) {
 			buffer.append(' ');
 			buffer.append(DebugUIMessages.JDIModelPresentation_Suspend_VM);
 		}
 	}
 
-	protected void appendThreadFilter(IJavaBreakpoint breakpoint, StringBuffer buffer) throws CoreException {
+	protected void appendThreadFilter(IJavaBreakpoint breakpoint, StringBuilder buffer) throws CoreException {
 		if (breakpoint.getThreadFilters().length != 0) {
 			buffer.append(' ');
 			buffer.append(DebugUIMessages.JDIModelPresentation_thread_filtered);
 		}
 	}
 
-	protected void appendConditional(IJavaLineBreakpoint breakpoint, StringBuffer buffer) throws CoreException {
+	protected void appendConditional(IJavaLineBreakpoint breakpoint, StringBuilder buffer) throws CoreException {
 		if (breakpoint.isConditionEnabled() && breakpoint.getCondition() != null) {
 			buffer.append(' ');
 			buffer.append(DebugUIMessages.JDIModelPresentation__conditional__2);
 		}
 	}
 
-	protected void appendInstanceFilter(IJavaBreakpoint breakpoint, StringBuffer buffer) throws CoreException {
+	protected void appendInstanceFilter(IJavaBreakpoint breakpoint, StringBuilder buffer) throws CoreException {
 		IJavaObject[] instances = breakpoint.getInstanceFilters();
 		for (int i = 0; i < instances.length; i++) {
 			String instanceText= instances[i].getValueString();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaBreakpointWorkbenchAdapterFactory.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaBreakpointWorkbenchAdapterFactory.java
index 8a0790a..a7339be 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaBreakpointWorkbenchAdapterFactory.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaBreakpointWorkbenchAdapterFactory.java
@@ -57,7 +57,7 @@
 					return null;
 				}
 				IJavaBreakpoint breakpoint = (IJavaBreakpoint) o;
-				StringBuffer label = new StringBuffer();
+				StringBuilder label = new StringBuilder();
 				try {
 					String type= breakpoint.getTypeName();
 					if (type != null) {
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 236d726..6b073d2 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
@@ -153,7 +153,7 @@
 	 * Returns HTML text for the given variable
 	 */
 	private static String getVariableText(IVariable variable) {
-	    StringBuffer buffer= new StringBuffer();
+	    StringBuilder buffer= new StringBuilder();
 		JDIModelPresentation modelPresentation = getModelPresentation();
 		buffer.append("<p><pre>"); //$NON-NLS-1$
 		String variableText= modelPresentation.getVariableText((IJavaVariable) variable);
@@ -172,7 +172,7 @@
 	 * values containing reserved characters are correctly displayed.
      */
     private static String replaceHTMLChars(String variableText) {
-        StringBuffer buffer= new StringBuffer(variableText.length());
+        StringBuilder buffer= new StringBuilder(variableText.length());
         char[] characters = variableText.toCharArray();
         for (int i = 0; i < characters.length; i++) {
             char character= characters[i];
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
index eea88e1..92e16cd 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugOptionsManager.java
@@ -461,7 +461,7 @@
 		if (list == null) {

 			return ""; //$NON-NLS-1$

 		}

-		StringBuffer buffer = new StringBuffer();

+		StringBuilder buffer = new StringBuilder();

 		for (int i = 0; i < list.length; i++) {

 			if (i > 0) {

 				buffer.append(',');

@@ -628,7 +628,7 @@
 	 */

 	@Override

 	public void breakpointHasCompilationErrors(final IJavaLineBreakpoint breakpoint, final Message[] errors) {

-		StringBuffer message= new StringBuffer();

+		StringBuilder message= new StringBuilder();

 		Message error;

 		for (int i=0, numErrors= errors.length; i < numErrors; i++) {

 			error= errors[i];

diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
index 1832c18..1fe1f98 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDetailFormattersManager.java
@@ -416,7 +416,7 @@
 			if (maxLength > 0){
 				int maxEntries = (maxLength / 3) + 1;
 				if (length > maxEntries) {
-					StringBuffer snippet = new StringBuffer();
+					StringBuilder snippet = new StringBuilder();
 					snippet.append("Object[] shorter = new Object["); //$NON-NLS-1$
 					snippet.append(maxEntries);
 					snippet.append("]; System.arraycopy(this, 0, shorter, 0, "); //$NON-NLS-1$
@@ -599,7 +599,7 @@
 		@Override
 		public void evaluationComplete(IEvaluationResult result) {
 			if (result.hasErrors()) {
-				StringBuffer error= new StringBuffer(DebugUIMessages.JavaDetailFormattersManager_Detail_formatter_error___1);
+				StringBuilder error= new StringBuilder(DebugUIMessages.JavaDetailFormattersManager_Detail_formatter_error___1);
 				DebugException exception= result.getException();
 				if (exception != null) {
 					Throwable throwable= exception.getStatus().getException();
@@ -607,7 +607,7 @@
 					if (throwable instanceof InvocationException) {
 						error.append(NLS.bind(DebugUIMessages.JavaDetailFormattersManager_An_exception_occurred___0__3, new String[] {((InvocationException) throwable).exception().referenceType().name()}));
 					} else if (throwable instanceof UnsupportedOperationException) {
-						error = new StringBuffer();
+						error = new StringBuilder();
 						error.append(DebugUIMessages.JavaDetailFormattersManager_7);
 					} else {
 						error.append(exception.getStatus().getMessage());
@@ -630,22 +630,22 @@
 
 		public void valueToString(final IJavaValue objectValue) throws DebugException {
 			String nonEvalResult = null;
-			StringBuffer result= null;
+			StringBuilder result= null;
 			if (objectValue.getSignature() == null) {
 				// no need to spawn evaluate for a null fValue
 				nonEvalResult = DebugUIMessages.JavaDetailFormattersManager_null;
 			} else if (objectValue instanceof IJavaPrimitiveValue) {
 				// no need to spawn evaluate for a primitive value
-				result = new StringBuffer();
+				result = new StringBuilder();
 				appendJDIPrimitiveValueString(result, objectValue);
 			} else if (fThread == null || !fThread.isSuspended()) {
 				// no thread available
-				result = new StringBuffer();
+				result = new StringBuilder();
 				result.append(DebugUIMessages.JavaDetailFormattersManager_no_suspended_threads);
 				appendJDIValueString(result, objectValue);
 			} else if (objectValue instanceof IJavaObject && STRING_SIGNATURE.equals(objectValue.getSignature())) {
 				// no need to spawn evaluate for a java.lang.String
-				result = new StringBuffer();
+				result = new StringBuilder();
 				appendJDIValueString(result, objectValue);
 			}
 			if (result != null) {
@@ -659,7 +659,7 @@
 			IEvaluationRunnable eval = new IEvaluationRunnable() {
 				@Override
 				public void run(IJavaThread thread, IProgressMonitor monitor) throws DebugException {
-					StringBuffer buf= new StringBuffer();
+					StringBuilder buf= new StringBuilder();
 					if (objectValue instanceof IJavaArray) {
 						appendArrayDetail(buf, (IJavaArray) objectValue);
 					} else if (objectValue instanceof IJavaObject) {
@@ -679,7 +679,7 @@
 		 * Arrays.asList().toString() to minimize toString() calls on remote target (i.e. one call to
 		 * List.toString() instead of one call per item in the array).
 		 */
-		protected void appendArrayDetail(StringBuffer result, IJavaArray arrayValue) throws DebugException {
+		protected void appendArrayDetail(StringBuilder result, IJavaArray arrayValue) throws DebugException {
 			result.append('[');
 			boolean partial = false;
 			IJavaValue[] arrayValues = null;
@@ -726,17 +726,17 @@
 			}
 		}
 
-		protected void appendJDIPrimitiveValueString(StringBuffer result, IJavaValue value) throws DebugException {
+		protected void appendJDIPrimitiveValueString(StringBuilder result, IJavaValue value) throws DebugException {
 			result.append(value.getValueString());
 		}
 
 
-		protected void appendJDIValueString(StringBuffer result, IJavaValue value) throws DebugException {
+		protected void appendJDIValueString(StringBuilder result, IJavaValue value) throws DebugException {
 			result.append(value.getValueString());
 		}
 
 
-		protected void appendObjectDetail(StringBuffer result, IJavaObject objectValue) throws DebugException {
+		protected void appendObjectDetail(StringBuilder result, IJavaObject objectValue) throws DebugException {
 			if(objectValue instanceof JDINullValue) {
 				appendJDIValueString(result, objectValue);
 				return;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
index 07c859d..bb4e4cb 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaLogicalStructuresPreferencePage.java
@@ -68,7 +68,7 @@
         @Override
 		public String getColumnText(Object element, int columnIndex) {
             JavaLogicalStructure logicalStructure= (JavaLogicalStructure) element;
-            StringBuffer buffer= new StringBuffer();
+            StringBuilder buffer= new StringBuilder();
             if (columnIndex == 0) {
                 String qualifiedName= logicalStructure.getQualifiedTypeName();
                 int index= qualifiedName.lastIndexOf('.') + 1;
@@ -401,7 +401,7 @@
 	 * @param structure the logical structure that was modified
 	 */
 	private void refreshCodeViewer(JavaLogicalStructure structure){
-		StringBuffer buffer= new StringBuffer();
+		StringBuilder buffer= new StringBuilder();
 	    if (structure != null){
 	    	String snippet= structure.getValue();
 	    	if (snippet != null) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ControlAccessibleListener.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ControlAccessibleListener.java
index 961d53d..fe40a33 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ControlAccessibleListener.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ControlAccessibleListener.java
@@ -29,7 +29,7 @@
 	public static void addListener(Control comp, String name) {
 		//strip mnemonic
 		String[] strs = name.split("&"); //$NON-NLS-1$
-		StringBuffer stripped = new StringBuffer();
+		StringBuilder stripped = new StringBuilder();
 		for (int i = 0; i < strs.length; i++) {
 			stripped.append(strs[i]);
 		}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EvaluateAction.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EvaluateAction.java
index 7e1f022..a191c14 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EvaluateAction.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/EvaluateAction.java
@@ -521,7 +521,7 @@
 	}
 
 	private String format(String message) {
-		StringBuffer result= new StringBuffer();
+		StringBuilder result= new StringBuilder();
 		int index= 0, pos;
 		while ((pos= message.indexOf('\n', index)) != -1) {
 			result.append("\t\t").append(message.substring(index, index= pos + 1)); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ExpressionInputDialog.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ExpressionInputDialog.java
index 6fd12d1..7308481 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ExpressionInputDialog.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ExpressionInputDialog.java
@@ -251,7 +251,7 @@
                 IValue value = variable.getValue();
                 if (!(value instanceof JDINullValue)) {
                     String currentValue= value.getValueString();
-                    StringBuffer buffer= new StringBuffer(currentValue.length());
+                    StringBuilder buffer= new StringBuilder(currentValue.length());
                     buffer.append('"'); // Surround value in quotes
                     char[] chars = currentValue.toCharArray();
                     for (int i = 0; i < chars.length; i++) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java
index 8fb2309..b0b582d 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/JavaObjectValueEditor.java
@@ -181,7 +181,7 @@
     			}
     			if (result.hasErrors()) {
     			    DebugException exception = result.getException();
-    			    StringBuffer buffer = new StringBuffer();
+    			    StringBuilder buffer = new StringBuilder();
     			    if (exception == null) {
         			    String[] messages = result.getErrorMessages();
         			    for (int i = 0; i < messages.length; i++) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java
index 8bbba84..f8dba72 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/actions/ToggleBreakpointAdapter.java
@@ -610,7 +610,7 @@
      * @since 3.4
      */
 	private static String pruneAnonymous(IType type) {
-    	StringBuffer buffer = new StringBuffer();
+    	StringBuilder buffer = new StringBuilder();
     	IJavaElement parent = type;
     	while(parent != null) {
     		if(parent.getElementType() == IJavaElement.TYPE){
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaLikeExtensionsResolver.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaLikeExtensionsResolver.java
index 87267b8..f411e96 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaLikeExtensionsResolver.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaLikeExtensionsResolver.java
@@ -25,7 +25,7 @@
 	@Override
 	public String resolveValue(IDynamicVariable variable, String argument) throws CoreException {
 		String[] javaLikeExtensions = JavaCore.getJavaLikeExtensions();
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		if (javaLikeExtensions.length > 1) {
 			buffer.append("("); //$NON-NLS-1$
 		}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
index 64b8b65..e437491 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/console/JavaStackTraceConsole.java
@@ -210,7 +210,7 @@
      */
     private String format(String trace) {
         StringTokenizer tokenizer = new StringTokenizer(trace, " \t\n\r\f", true); //$NON-NLS-1$
-        StringBuffer formattedTrace = new StringBuffer();
+        StringBuilder formattedTrace = new StringBuilder();
 
         boolean insideAt = false;
         boolean newLine = true;
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
index c67cdc3..8f295ec 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/InstalledJREsBlock.java
@@ -1135,7 +1135,7 @@
 	}
 
 
-	private StringBuffer appendVMAttributes(IVMInstall vmInstall, StringBuffer buf) {
+	private StringBuilder appendVMAttributes(IVMInstall vmInstall, StringBuilder buf) {
 		if (vmInstall != null) {
 			String str = vmInstall.getName();
 			buf.append('[').append(str.length()).append(']').append(str);
@@ -1157,7 +1157,7 @@
 	}
 
 	private String getEncodedVMInstalls() {
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		IVMInstall vmInstall = getCheckedJRE();
 
 		int nElements = fVMs.size();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java
index 2ea3ed8..e47b06e 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/LibraryLabelProvider.java
@@ -87,7 +87,7 @@
 			return ((LibraryStandin)element).getSystemLibraryPath().toOSString();
 		} else if (element instanceof SubElement) {
 			SubElement subElement= (SubElement) element;
-			StringBuffer text= new StringBuffer();
+			StringBuilder text= new StringBuilder();
 			if (subElement.getType() == SubElement.SOURCE_PATH) {
 				text.append(JREMessages.VMLibraryBlock_0);
 				IPath systemLibrarySourcePath= subElement.getParent().getSystemLibrarySourcePath();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMDetailsDialog.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMDetailsDialog.java
index 3b1c2b3..3203ed1 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMDetailsDialog.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/jres/VMDetailsDialog.java
@@ -83,7 +83,7 @@
 		} else {
 			String[] args = fVM.getVMArguments();
 			if (args != null) {
-				StringBuffer buf = new StringBuffer();
+				StringBuilder buf = new StringBuilder();
 				for (int i = 0; i < args.length; i++) {
 					buf.append(args[i]);
 					if (i < (args.length - 1)) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/ClasspathTooLongStatusHandler.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/ClasspathTooLongStatusHandler.java
new file mode 100644
index 0000000..a755cdc
--- /dev/null
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/ClasspathTooLongStatusHandler.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Cedric Chabanois and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Cedric Chabanois (cchabanois@gmail.com) - Launching command line exceeds the process creation command limit on *nix - https://bugs.eclipse.org/bugs/show_bug.cgi?id=385738
+ *******************************************************************************/
+package org.eclipse.jdt.internal.debug.ui.launcher;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.IStatusHandler;
+import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+
+/**
+ * Handle status when classpath is too long and that this could not be solved automatically.
+ *
+ * We ask the user if he wants to use classpath-only jar. We need confirmation from the user because it can have side effects
+ * (System.getProperty("java.class.path") will return a classpath with only one jar).
+ */
+public class ClasspathTooLongStatusHandler implements IStatusHandler {
+
+	@Override
+	public Object handleStatus(IStatus status, Object source) {
+		ILaunch launch = (ILaunch) source;
+		ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
+		boolean enableClasspathOnlyJar = askEnableClasspathOnlyJar();
+		if (enableClasspathOnlyJar && launchConfiguration != null) {
+			try {
+				ILaunchConfigurationWorkingCopy configurationWorkingCopy = launchConfiguration.getWorkingCopy();
+				configurationWorkingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, true);
+				configurationWorkingCopy.doSave();
+			} catch (CoreException e) {
+				JDIDebugUIPlugin.log(e);
+			}
+		}
+		return Boolean.valueOf(enableClasspathOnlyJar);
+	}
+
+	private boolean askEnableClasspathOnlyJar() {
+		final boolean[] result = new boolean[1];
+		JDIDebugUIPlugin.getStandardDisplay().syncExec(new Runnable() {
+			@Override
+			public void run() {
+				String title = LauncherMessages.ClasspathTooLongStatusHandler_0;
+				String message = LauncherMessages.ClasspathTooLongStatusHandler_1;
+				result[0] = (MessageDialog.openQuestion(JDIDebugUIPlugin.getActiveWorkbenchShell(), title, message));
+			}
+		});
+		return result[0];
+	}
+
+}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
index b2bfa90..10d9c95 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.java
@@ -48,6 +48,8 @@
 
 	public static String VMArgumentsBlock_0;
 
+	public static String VMArgumentsBlock_1;
+
 	public static String VMArgumentsBlock_VM_Arguments;
 	public static String VMArgumentsBlock_4;
 
@@ -180,6 +182,10 @@
 
 	public static String AppletSelectionDialog_Searching____1;
 
+	public static String ClasspathTooLongStatusHandler_0;
+
+	public static String ClasspathTooLongStatusHandler_1;
+
 	public static String ExecutionEnvironmentSelector_0;
 	public static String ExecutionEnvironmentSelector_1;
 
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
index 4cd96bd..faf071e 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/LauncherMessages.properties
@@ -25,6 +25,7 @@
 RuntimeClasspathAdvancedDialog_7=Va&riables...
 
 VMArgumentsBlock_0=Use the -&XstartOnFirstThread argument when launching with SWT
+VMArgumentsBlock_1=Use temporary jar to specify classpath (to avoid classpath length limitations)
 VMArgumentsBlock_VM_Arguments=VM Arguments
 
 JavaConnectTab__Allow_termination_of_remote_VM_6=&Allow termination of remote VM
@@ -177,6 +178,8 @@
 AbstractJavaMainTab_2=&Search...
 AbstractJavaMainTab_4=Project Selection
 AbstractJavaMainTab_3=Select a project to constrain your search.
+ClasspathTooLongStatusHandler_0=Java Application
+ClasspathTooLongStatusHandler_1=Cannot start the Java Virtual Machine because classpath is too long. Do you want to enable classpath-only jar for this launch configuration ?
 ExecutionEnvironmentSelector_0=Select Execution Environment
 ExecutionEnvironmentSelector_1=Choose an environment (? = any character, * = any string):
 ProjectClasspathArugumentSelector_0=Select Java Project
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/RuntimeClasspathEntryLabelProvider.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/RuntimeClasspathEntryLabelProvider.java
index f71cef4..562cced 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/RuntimeClasspathEntryLabelProvider.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/launcher/RuntimeClasspathEntryLabelProvider.java
@@ -142,7 +142,7 @@
 					return NLS.bind(LauncherMessages.RuntimeClasspathEntryLabelProvider_Invalid_path, new String[]{path.toOSString()});
 				}
 				String[] segments = path.segments();
-				StringBuffer displayPath = new StringBuffer();
+				StringBuilder displayPath = new StringBuilder();
 				if (segments.length > 0) {
 					displayPath.append(segments[segments.length - 1]);
 					displayPath.append(" - "); //$NON-NLS-1$
@@ -161,7 +161,7 @@
 			case IRuntimeClasspathEntry.VARIABLE:
 				path = entry.getPath();
 				IPath srcPath = entry.getSourceAttachmentPath();
-				StringBuffer buf = new StringBuffer(path.toString());
+				StringBuilder buf = new StringBuilder(path.toString());
 				if (srcPath != null) {
 					buf.append(" ["); //$NON-NLS-1$
 					buf.append(srcPath.toString());
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
index 5a589f2..2f1a348 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/JavaBreakpointPage.java
@@ -279,7 +279,7 @@
 		IJavaBreakpoint jb = getBreakpoint();
 		if (jb instanceof IJavaLineBreakpoint) {
 			IJavaLineBreakpoint breakpoint = (IJavaLineBreakpoint) jb;
-			StringBuffer lineNumber = new StringBuffer(4);
+			StringBuilder lineNumber = new StringBuilder(4);
 			try {
 				int lNumber = breakpoint.getLineNumber();
 				if (lNumber > 0) {
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/VMCapabilitiesPropertyPage.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/VMCapabilitiesPropertyPage.java
index 1e30b8c..18d9682 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/VMCapabilitiesPropertyPage.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/propertypages/VMCapabilitiesPropertyPage.java
@@ -153,7 +153,7 @@
 	private void createHeadingLabel(Composite parent, VirtualMachineImpl vm) {
 		Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 2, 2, GridData.HORIZONTAL_ALIGN_BEGINNING);
 		SWTFactory.createLabel(comp, PropertyPageMessages.VMCapabilitiesPropertyPage_1, fHeadingFont, 1);
-		StringBuffer buff = new StringBuffer(vm.name().trim());
+		StringBuilder buff = new StringBuilder(vm.name().trim());
 		buff = buff.append(" ").append(vm.version().trim()); //$NON-NLS-1$
 		Text text = SWTFactory.createText(comp, SWT.READ_ONLY, 1, buff.toString());
 		text.setBackground(parent.getBackground());
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/search/LaunchConfigurationQueryParticipant.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/search/LaunchConfigurationQueryParticipant.java
index ffa683f..c07fd74 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/search/LaunchConfigurationQueryParticipant.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/search/LaunchConfigurationQueryParticipant.java
@@ -147,7 +147,7 @@
 	 */
 	private String quotePattern(String pattern) {
 		StringTokenizer t = new StringTokenizer(pattern, ".?*$()", true); //$NON-NLS-1$
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		String token = null;
 		while (t.hasMoreTokens()) {
 			token = t.nextToken();
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetEditor.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetEditor.java
index dd9dd12..d8ee050 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetEditor.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/JavaSnippetEditor.java
@@ -767,7 +767,7 @@
 	}
 
 	protected void displayResult(IJavaValue result) {
-		StringBuffer resultString= new StringBuffer();
+		StringBuilder resultString= new StringBuilder();
 		try {
 			IJavaType type = result.getJavaType();
 			if (type != null) {
@@ -840,7 +840,7 @@
 		IDocument document = getSourceViewer().getDocument();
 		String delimiter = document.getLegalLineDelimiters()[0];
 
-		final StringBuffer errorString = new StringBuffer();
+		final StringBuilder errorString = new StringBuilder();
 		for (int i = 0; i < errors.length; i++) {
 			errorString.append(errors[i] + delimiter);
 		}
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
index e56af53..6b45684 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/snippeteditor/ScrapbookLauncher.java
@@ -226,7 +226,7 @@
 				wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, "org.eclipse.jdt.debug.ui.scrapbookSourcepathProvider"); //$NON-NLS-1$
 			}
 
-			StringBuffer urlsString = new StringBuffer();
+			StringBuilder urlsString = new StringBuilder();
 			for (int i = 0; i < urls.length; i++) {
 				urlsString.append(' ');
 				urlsString.append(urls[i]);
@@ -350,7 +350,7 @@
 		// NOT File.separatorChar
 		String urlDelimiter= "/"; //$NON-NLS-1$
 		String unencoded= file.toURL().toExternalForm();
-		StringBuffer encoded= new StringBuffer();
+		StringBuilder encoded= new StringBuilder();
 		StringTokenizer tokenizer= new StringTokenizer(unencoded, urlDelimiter);
 
 		encoded.append(tokenizer.nextToken()); //file:
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/WorkbenchAdapter.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/WorkbenchAdapter.java
index 93ada17..fcf8566 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/WorkbenchAdapter.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/sourcelookup/WorkbenchAdapter.java
@@ -91,7 +91,7 @@
 			IPackageFragmentRoot fragmentRoot = container.getPackageFragmentRoot();
 			IPath path = fragmentRoot.getPath();
 			if (path.segmentCount() > 0) {
-				StringBuffer buffer = new StringBuffer();
+				StringBuilder buffer = new StringBuilder();
 				buffer.append(path.lastSegment());
 				if (path.segmentCount() > 1) {
 					buffer.append(" - "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaStackFrameMementoProvider.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaStackFrameMementoProvider.java
index 504623e..2335630 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaStackFrameMementoProvider.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaStackFrameMementoProvider.java
@@ -30,7 +30,7 @@
 	@Override
 	protected String getElementName(Object element, IPresentationContext context) throws CoreException {
 		if (element instanceof IJavaStackFrame) {
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
 			IJavaStackFrame frame = (IJavaStackFrame) element;
 			buf.append(frame.getDeclaringTypeName());
 			buf.append("#"); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelProvider.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelProvider.java
index e2e7a64..ea522a7 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelProvider.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/variables/JavaVariableLabelProvider.java
@@ -142,7 +142,7 @@
 			if (value instanceof JDIObjectValue) {
 				long uniqueId = ((JDIObjectValue)value).getUniqueId();
 				if (uniqueId >= 0) {
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					buffer.append(uniqueId);
 					return buffer.toString();
 				}
@@ -161,7 +161,7 @@
 						if (count == -1) {
 							return DebugUIMessages.JavaVariableLabelProvider_0;
 						}
-						StringBuffer buffer = new StringBuffer();
+						StringBuilder buffer = new StringBuilder();
 						buffer.append(count);
 						return buffer.toString();
 					}
diff --git a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
index 51a0c46..dd9809c 100644
--- a/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.debug/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true
-Bundle-Version: 3.11.100.qualifier
+Bundle-Version: 3.11.200.qualifier
 Bundle-ClassPath: jdi.jar,
  jdimodel.jar,
  tools.jar
@@ -33,7 +33,7 @@
  org.eclipse.jdt.internal.debug.eval.ast.engine;x-friends:="org.eclipse.jdt.debug.ui",
  org.eclipse.jdt.internal.debug.eval.ast.instructions;x-friends:="org.eclipse.jdt.debug.ui"
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.9.0,4.0.0)",
+ org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)",
  org.eclipse.jdt.core;bundle-version="[3.8.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)"
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
index 4c1cae6..63d13d5 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java
@@ -167,7 +167,7 @@
 	 */
 	private void traceCaller(String snippet, IThread thread) {
 		if (JDIDebugOptions.DEBUG_AST_EVAL_THREAD_TRACE) {
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
 			buf.append(JDIDebugOptions.FORMAT.format(new Date()));
 			buf.append(" : Evaluation Request Trace - Expression: "); //$NON-NLS-1$
 			buf.append(snippet);
@@ -417,7 +417,7 @@
 			String recTypeName = "java.lang.Object"; //$NON-NLS-1$
 			String typeName = arrayType.getName();
 			if (componentType instanceof IJavaReferenceType) {
-				StringBuffer buf = new StringBuffer();
+				StringBuilder buf = new StringBuilder();
 				buf.append("java.lang.Object"); //$NON-NLS-1$
 				for (int i = 0; i < dimension; i++) {
 					buf.append("[]"); //$NON-NLS-1$
@@ -638,7 +638,7 @@
 		@Override
 		public void run() {
 			if (JDIDebugOptions.DEBUG_AST_EVAL) {
-				StringBuffer buf = new StringBuffer();
+				StringBuilder buf = new StringBuilder();
 				buf.append(JDIDebugOptions.FORMAT.format(new Date()));
 				buf.append(" : AST Evaluation"); //$NON-NLS-1$
 				buf.append("\n\tExpression: "); //$NON-NLS-1$
@@ -673,7 +673,7 @@
 				}
 				evaluationFinished(result);
 				if (JDIDebugOptions.DEBUG_AST_EVAL) {
-					StringBuffer buf = new StringBuffer();
+					StringBuilder buf = new StringBuilder();
 					buf.append("\tErrors: "); //$NON-NLS-1$
 					for (int i = 0; i < errors.length; i++) {
 						if (i > 0) {
@@ -768,7 +768,7 @@
 			result.setTerminated(er.fTerminated);
 			if (exception != null) {
 				if (JDIDebugOptions.DEBUG_AST_EVAL) {
-					StringBuffer buf = new StringBuffer();
+					StringBuilder buf = new StringBuilder();
 					buf.append("\tException: "); //$NON-NLS-1$
 					buf.append(exception.toString());
 					JDIDebugOptions.trace(buf.toString());
@@ -783,7 +783,7 @@
 				if (value != null) {
 					result.setValue(value);
 					if (JDIDebugOptions.DEBUG_AST_EVAL) {
-						StringBuffer buf = new StringBuffer();
+						StringBuilder buf = new StringBuilder();
 						buf.append("\tResult: "); //$NON-NLS-1$
 						buf.append(value);
 						JDIDebugOptions.trace(buf.toString());
@@ -794,7 +794,7 @@
 			}
 
 			if (JDIDebugOptions.DEBUG_AST_EVAL) {
-				StringBuffer buf = new StringBuffer();
+				StringBuilder buf = new StringBuilder();
 				buf.append("\tDuration: "); //$NON-NLS-1$
 				buf.append(end - start);
 				buf.append("ms"); //$NON-NLS-1$
@@ -822,7 +822,7 @@
 	 */
 	public static String replaceThisReferences(String snippet) {
 		// replace all occurrences of 'this' with 'array_this'
-		StringBuffer updatedSnippet = new StringBuffer();
+		StringBuilder updatedSnippet = new StringBuilder();
 		Matcher matcher = fgThisPattern.matcher(snippet);
 		int start = 0;
 		while (matcher.find()) {
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 0a293db..d3de485 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
@@ -250,9 +250,9 @@
 			}
 			return "java.lang.Object"; //$NON-NLS-1$
 		}
-		StringBuffer name;
+		StringBuilder name;
 		if (typeBinding.isArray()) {
-			name = new StringBuffer(getTypeName(typeBinding.getElementType()));
+			name = new StringBuilder(getTypeName(typeBinding.getElementType()));
 			int dimensions = typeBinding.getDimensions();
 			for (int i = 0; i < dimensions; i++) {
 				name.append("[]"); //$NON-NLS-1$
@@ -260,7 +260,7 @@
 			return name.toString();
 		}
 		//try it the old way
-		name = new StringBuffer(Signature.getTypeErasure(typeBinding.getName()));
+		name = new StringBuilder(Signature.getTypeErasure(typeBinding.getName()));
 		IPackageBinding packageBinding = typeBinding.getPackage();
 		typeBinding = typeBinding.getDeclaringClass();
 		while (typeBinding != null) {
@@ -4397,7 +4397,7 @@
 			return tokenString;
 		}
 		ignore = true;
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append(token, 0, start);
 		loop: for (int i = start; i < max; i++) {
 			char currentChar = token[i];
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 9f4cb10..6fe6902 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
@@ -39,7 +39,7 @@
 
 	private boolean fIsInStaticMethod;
 
-	private StringBuffer fSource;
+	private StringBuilder fSource;
 
 	private int fRunMethodStartOffset;
 	private int fRunMethodLength;
@@ -114,8 +114,8 @@
 		return methodName;
 	}
 
-	private StringBuffer buildRunMethod(ReferenceType type) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildRunMethod(ReferenceType type) {
+		StringBuilder source = new StringBuilder();
 
 		if (isInStaticMethod()) {
 			source.append("static "); //$NON-NLS-1$
@@ -144,8 +144,8 @@
 		return source;
 	}
 
-	private StringBuffer buildTypeDeclaration(ReferenceType referenceType,
-			StringBuffer buffer, String nestedTypeName) {
+	private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
+			StringBuilder buffer, String nestedTypeName) {
 
 		Field thisField = null;
 
@@ -158,7 +158,7 @@
 			}
 		}
 
-		StringBuffer source = buildTypeDeclaration(referenceType, buffer,
+		StringBuilder source = buildTypeDeclaration(referenceType, buffer,
 				nestedTypeName, thisField != null);
 
 		if (thisField == null) {
@@ -183,10 +183,10 @@
 		return source;
 	}
 
-	private StringBuffer buildTypeDeclaration(ReferenceType referenceType,
-			StringBuffer buffer, String nestedTypeName,
+	private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
+			StringBuilder buffer, String nestedTypeName,
 			boolean hasEnclosingInstance) {
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 
 		String typeName = referenceType.name();
 
@@ -291,7 +291,7 @@
 					try {
 						interfaces = classType.interfaces();
 					} catch (ClassNotPreparedException e) {
-						return new StringBuffer();
+						return new StringBuilder();
 					}
 					if (interfaces.size() != 0) {
 						source.append("implements "); //$NON-NLS-1$
@@ -373,8 +373,8 @@
 		return source;
 	}
 
-	private StringBuffer buildFieldDeclaration(Field field) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildFieldDeclaration(Field field) {
+		StringBuilder source = new StringBuilder();
 
 		if (field.isFinal()) {
 			source.append("final "); //$NON-NLS-1$
@@ -398,8 +398,8 @@
 		return source;
 	}
 
-	private StringBuffer buildMethodDeclaration(Method method) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildMethodDeclaration(Method method) {
+		StringBuilder source = new StringBuilder();
 
 		if (method.isFinal()) {
 			source.append("final "); //$NON-NLS-1$
@@ -586,7 +586,7 @@
 		return fIsInStaticMethod;
 	}
 
-	public StringBuffer getSource() {
+	public StringBuilder getSource() {
 		return fSource;
 	}
 
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
index 9c68780..ba9200f 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java
@@ -103,7 +103,7 @@
 				break;
 			}
 		}
-		StringBuffer wordBuffer = new StringBuffer();
+		StringBuilder wordBuffer = new StringBuilder();
 		// if semicolon missing at the end
 		if (lastSemilcolonIndex != chars.length-1)
 			semicolonIndex = lastSemilcolonIndex;
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 5a65c6b..7bb603c 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
@@ -138,7 +138,7 @@
 	private IType fType;
 	private int fLine;
 
-	private StringBuffer fSource;
+	private StringBuilder fSource;
 
 	private String fLastTypeName;
 
@@ -257,8 +257,8 @@
 		return fError;
 	}
 
-	private StringBuffer buildRunMethod(List<BodyDeclaration> bodyDeclarations) {
-		StringBuffer buffer = new StringBuffer();
+	private StringBuilder buildRunMethod(List<BodyDeclaration> bodyDeclarations) {
+		StringBuilder buffer = new StringBuilder();
 
 		if (fCreateInAStaticMethod) {
 			buffer.append("static "); //$NON-NLS-1$
@@ -302,7 +302,7 @@
 	 * @param buffer
 	 * @since 3.8.0
 	 */
-	void adddTypeParameters(StringBuffer buffer) {
+	void adddTypeParameters(StringBuilder buffer) {
 		if (isSourceLevelGreaterOrEqual(1, 5)) {
 			Collection<String> activeTypeParameters = (fMatchingTypeParameters != null ? fMatchingTypeParameters : fTypeParameterStack.peek()).values();
 			if (!activeTypeParameters.isEmpty()) {
@@ -359,8 +359,8 @@
 		return false;
 	}
 
-	private StringBuffer buildTypeBody(StringBuffer buffer, List<BodyDeclaration> list) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildTypeBody(StringBuilder buffer, List<BodyDeclaration> list) {
+		StringBuilder source = new StringBuilder();
 
 		source.append('{').append('\n');
 
@@ -374,9 +374,9 @@
 		return source;
 	}
 
-	private StringBuffer buildEnumBody(StringBuffer buffer,
+	private StringBuilder buildEnumBody(StringBuilder buffer,
 			List<EnumConstantDeclaration> constantDeclarations, List<BodyDeclaration> bodyDeclarations) {
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 
 		source.append('{').append('\n');
 		if (constantDeclarations.isEmpty()) {
@@ -416,8 +416,8 @@
 	 *            the list of {@link BodyDeclaration}s
 	 * @return the new source buffer
 	 */
-	private StringBuffer buildBody(StringBuffer buffer, List<BodyDeclaration> list) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildBody(StringBuilder buffer, List<BodyDeclaration> list) {
+		StringBuilder source = new StringBuilder();
 		if (buffer != null) {
 			fSnippetStartPosition += source.length();
 			source.append(buffer.toString());
@@ -445,8 +445,8 @@
 		return source;
 	}
 
-	private StringBuffer buildFieldDeclaration(FieldDeclaration fieldDeclaration) {
-		StringBuffer source = new StringBuffer();
+	private StringBuilder buildFieldDeclaration(FieldDeclaration fieldDeclaration) {
+		StringBuilder source = new StringBuilder();
 
 		source.append(Flags.toString(fieldDeclaration.getModifiers()));
 		source.append(' ');
@@ -475,9 +475,9 @@
 		return source;
 	}
 
-	private StringBuffer buildMethodDeclaration(
+	private StringBuilder buildMethodDeclaration(
 			MethodDeclaration methodDeclaration) {
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 		int modifiers = methodDeclaration.getModifiers();
 		source.append(Flags.toString(modifiers));
 		source.append(' ');
@@ -547,7 +547,7 @@
 		return source;
 	}
 
-	private void appendExtraDimensions(StringBuffer source, int extraDimension) {
+	private void appendExtraDimensions(StringBuilder source, int extraDimension) {
 		if (extraDimension > 0) {
 			source.append(' ');
 			for (int i = 0; i < extraDimension; i++) {
@@ -556,9 +556,9 @@
 		}
 	}
 
-	private StringBuffer buildEnumDeclaration(StringBuffer buffer,
+	private StringBuilder buildEnumDeclaration(StringBuilder buffer,
 			EnumDeclaration enumDeclaration) {
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 		source.append(Flags.toString(enumDeclaration.getModifiers()));
 		source.append(" enum "); //$NON-NLS-1$
 
@@ -583,10 +583,10 @@
 		return source;
 	}
 
-	private StringBuffer buildTypeDeclaration(StringBuffer buffer,
+	private StringBuilder buildTypeDeclaration(StringBuilder buffer,
 			TypeDeclaration typeDeclaration) {
 
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 		source.append(Flags.toString(typeDeclaration.getModifiers()));
 		if (typeDeclaration.isInterface()) {
 			source.append(" interface "); //$NON-NLS-1$
@@ -658,9 +658,9 @@
 		return source;
 	}
 
-	private StringBuffer buildCompilationUnit(StringBuffer buffer,
+	private StringBuilder buildCompilationUnit(StringBuilder buffer,
 			CompilationUnit compilationUnit) {
-		StringBuffer source = new StringBuffer();
+		StringBuilder source = new StringBuilder();
 
 		PackageDeclaration packageDeclaration = compilationUnit.getPackage();
 		if (packageDeclaration != null) {
@@ -808,7 +808,7 @@
 					+ qualifiedType.getName().getIdentifier();
 		} else if (type.isParameterizedType()) {
 			ParameterizedType parameterizedType = (ParameterizedType) type;
-			StringBuffer buff = new StringBuffer(
+			StringBuilder buff = new StringBuilder(
 					getTypeName(parameterizedType.getType()));
 			Iterator<Type> iter = parameterizedType.typeArguments().iterator();
 			if (iter.hasNext() && isSourceLevelGreaterOrEqual(1, 5)) {
@@ -823,7 +823,7 @@
 			return buff.toString();
 		} else if (type.isWildcardType()) {
 			WildcardType wildcardType = (WildcardType) type;
-			StringBuffer buff = new StringBuffer("?"); //$NON-NLS-1$
+			StringBuilder buff = new StringBuilder("?"); //$NON-NLS-1$
 			Type bound = wildcardType.getBound();
 			if (bound != null) {
 				buff.append(wildcardType.isUpperBound() ? " extends " : " super "); //$NON-NLS-1$ //$NON-NLS-2$
@@ -881,7 +881,7 @@
 				List<BodyDeclaration> bodyDeclarations = anonymousClassDeclaration
 						.bodyDeclarations();
 
-				StringBuffer source = buildTypeBody(fSource, bodyDeclarations);
+				StringBuilder source = buildTypeBody(fSource, bodyDeclarations);
 
 				ASTNode parent = node.getParent();
 				while (!(parent instanceof MethodDeclaration
@@ -890,7 +890,7 @@
 					parent = parent.getParent();
 				}
 
-				fSource = new StringBuffer();
+				fSource = new StringBuilder();
 
 				if (parent instanceof Initializer) {
 					buildAnonymousEvalMethod(true, bodyDeclarations,
@@ -954,7 +954,7 @@
 	 * @since 3.7
 	 */
 	void buildAnonymousEvalMethod(boolean isstatic, List<BodyDeclaration> bodydecls,
-			String typename, StringBuffer body) {
+			String typename, StringBuilder body) {
 		if (isstatic) {
 			fSource.append("static "); //$NON-NLS-1$
 		}
@@ -1033,7 +1033,7 @@
 
 		if (rightTypeFound()) {
 
-			StringBuffer source = buildEnumDeclaration(fSource, node);
+			StringBuilder source = buildEnumDeclaration(fSource, node);
 
 			if (node.isLocalTypeDeclaration()) {
 				// enclose in a method if necessary
@@ -1044,7 +1044,7 @@
 				}
 				MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) parent;
 
-				fSource = new StringBuffer();
+				fSource = new StringBuilder();
 
 				if (Flags.isStatic(enclosingMethodDeclaration.getModifiers())) {
 					fSource.append("static "); //$NON-NLS-1$
@@ -1097,7 +1097,7 @@
 
 		if (rightTypeFound()) {
 
-			StringBuffer source = buildTypeDeclaration(fSource, node);
+			StringBuilder source = buildTypeDeclaration(fSource, node);
 
 			if (node.isLocalTypeDeclaration()) {
 				// enclose in a method if nessecary
@@ -1108,7 +1108,7 @@
 				}
 				MethodDeclaration enclosingMethodDeclaration = (MethodDeclaration) parent;
 
-				fSource = new StringBuffer();
+				fSource = new StringBuilder();
 
 				if (Flags.isStatic(enclosingMethodDeclaration.getModifiers())) {
 					fSource.append("static "); //$NON-NLS-1$
@@ -2127,7 +2127,7 @@
 	 * @param typeParameters
 	 *            the list of {@link TypeParameter}s to add
 	 */
-	private void appendTypeParameters(StringBuffer source, List<TypeParameter> typeParameters) {
+	private void appendTypeParameters(StringBuilder source, List<TypeParameter> typeParameters) {
 		if (!typeParameters.isEmpty() && isSourceLevelGreaterOrEqual(1, 5)) {
 			source.append('<');
 			Iterator<TypeParameter> iter = typeParameters.iterator();
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/LocalVariableCreation.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/LocalVariableCreation.java
index 5c5491a..12865d5 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/LocalVariableCreation.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/instructions/LocalVariableCreation.java
@@ -19,6 +19,7 @@
 import org.eclipse.jdt.internal.debug.core.model.JDIType;
 import org.eclipse.osgi.util.NLS;
 
+import com.sun.jdi.VMDisconnectedException;
 import com.sun.jdi.VirtualMachine;
 
 public class LocalVariableCreation extends CompoundInstruction {
@@ -90,7 +91,7 @@
 				debugTarget
 						.requestFailed(
 								InstructionsEvaluationMessages.LocalVariableCreation_Execution_failed___VM_disconnected__1,
-								null);
+								new VMDisconnectedException());
 			}
 			type = JDIType.createType(debugTarget, PrimitiveTypeImpl.create(
 					(VirtualMachineImpl) vm, fTypeSignature));
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ArrayReferenceImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ArrayReferenceImpl.java
index 090eaf3..7bf9606 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ArrayReferenceImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ArrayReferenceImpl.java
@@ -414,7 +414,7 @@
 	@Override
 	public String toString() {
 		try {
-			StringBuffer buf = new StringBuffer(type().name());
+			StringBuilder buf = new StringBuilder(type().name());
 			// Insert length of string between (last) square braces.
 			buf.insert(buf.length() - 1, length());
 			// Append space and idString.
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/MirrorImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/MirrorImpl.java
index 1fa24d6..19aab80 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/MirrorImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/MirrorImpl.java
@@ -192,7 +192,7 @@
 				.getReply(commandPacket);
 		long recieved = System.currentTimeMillis();
 		if (JDIDebugOptions.DEBUG_JDI_REQUEST_TIMES) {
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
 			buf.append(JDIDebugOptions.FORMAT.format(new Date(sent)));
 			buf.append(" JDI Request: "); //$NON-NLS-1$
 			buf.append(commandPacket.toString());
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/SourceDebugExtensionParser.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/SourceDebugExtensionParser.java
index 07895fd..1c6e339 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/SourceDebugExtensionParser.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/SourceDebugExtensionParser.java
@@ -553,7 +553,7 @@
 
 	private String getNonAsteriskString(Lexer lexer)
 			throws AbsentInformationException {
-		StringBuffer string = new StringBuffer();
+		StringBuilder string = new StringBuilder();
 		int lexemType = lexer.lexemType();
 		while (lexemType != Lexer.CR) {
 			string.append(lexer.lexem());
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/TypeImpl.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/TypeImpl.java
index edcd732..253c616 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/TypeImpl.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/TypeImpl.java
@@ -132,7 +132,7 @@
 		 * JNI signature examples: int[][] -> [[I long[] -> [J java.lang.String
 		 * -> Ljava/lang/String; java.lang.String[] -> [Ljava/lang/String;
 		 */
-		StringBuffer signature = new StringBuffer();
+		StringBuilder signature = new StringBuilder();
 
 		int firstBrace = qualifiedName.indexOf('[');
 		if (firstBrace < 0) {
@@ -220,7 +220,7 @@
 		if (signature.indexOf('[') < 0) {
 			return signature;
 		}
-		StringBuffer name = new StringBuffer();
+		StringBuilder name = new StringBuilder();
 		String type = signature.substring(signature.lastIndexOf('[') + 1);
 		if (type.length() == 1 && isPrimitiveSignature(type)) {
 			name.append(getPrimitiveSignatureToName(type.charAt(0)));
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VerboseWriter.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VerboseWriter.java
index f2c0aed..4fd40b2 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VerboseWriter.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VerboseWriter.java
@@ -31,8 +31,8 @@
 
 	/** PrintWriter that is written to. */
 	private PrintWriter fOutput;
-	/** Buffer for output: one StringBuffer entry per line. */
-	private List<StringBuffer> fLineBuffer;
+	/** Buffer for output: one StringBuilder entry per line. */
+	private List<StringBuilder> fLineBuffer;
 	/** Position from where buffer is written to. */
 	private int fPosition;
 	/** True if the current line has not yet been written to. */
@@ -46,7 +46,7 @@
 		fOutput = out;
 		fLineBuffer = new ArrayList<>();
 		fPosition = 0;
-		fLineBuffer.add(new StringBuffer());
+		fLineBuffer.add(new StringBuilder());
 	}
 
 	/**
@@ -529,14 +529,14 @@
 				fOutput.println(new String(fLineBuffer.get(i)));
 
 			// The last line should be printed without an extra newline
-			StringBuffer lastLine = fLineBuffer.get(bufSize - 1);
+			StringBuilder lastLine = fLineBuffer.get(bufSize - 1);
 			if (lastLine.length() > 0)
 				fOutput.print(new String(lastLine));
 
 			fOutput.flush();
 			fLineBuffer.clear();
 			fPosition = 0;
-			fLineBuffer.add(new StringBuffer());
+			fLineBuffer.add(new StringBuilder());
 		}
 	}
 
@@ -575,7 +575,7 @@
 	 */
 	public void markLn() {
 		if (++fPosition == fLineBuffer.size()) {
-			fLineBuffer.add(new StringBuffer());
+			fLineBuffer.add(new StringBuilder());
 		}
 
 		fNewLine = true;
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java
index 103383c..29bf54a 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java
@@ -337,7 +337,7 @@
 	 */
 	@Override
 	public String toString() {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append('[');
 		buffer.append(getId());
 		buffer.append("] "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpReplyPacket.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpReplyPacket.java
index 90f333b..fd70046 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpReplyPacket.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpReplyPacket.java
@@ -174,7 +174,7 @@
 	 */
 	@Override
 	public String toString() {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append("["); //$NON-NLS-1$
 		buffer.append(getId());
 		buffer.append("] "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpString.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpString.java
index 8b1af64..27f7682 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpString.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpString.java
@@ -30,7 +30,7 @@
 		byte utfBytes[] = new byte[utfSize];
 		in.readFully(utfBytes);
 		/* Guess at buffer size */
-		StringBuffer strBuffer = new StringBuffer(utfSize / 3 * 2);
+		StringBuilder strBuffer = new StringBuilder(utfSize / 3 * 2);
 		for (int i = 0; i < utfSize;) {
 			int a = utfBytes[i] & 0xFF;
 			if ((a >> 4) < 12) {
diff --git a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/VerbosePacketStream.java b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/VerbosePacketStream.java
index d5c133b..a83728d 100644
--- a/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/VerbosePacketStream.java
+++ b/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/spy/VerbosePacketStream.java
@@ -2463,7 +2463,7 @@
 		byte utfBytes[] = new byte[utfSize];
 		in.readFully(utfBytes);
 		/* Guess at buffer size */
-		StringBuffer strBuffer = new StringBuffer(utfSize / 3 * 2);
+		StringBuilder strBuffer = new StringBuilder(utfSize / 3 * 2);
 		for (int i = 0; i < utfSize;) {
 			int a = utfBytes[i] & 0xFF;
 			if ((a >> 4) < 12) {
@@ -2792,7 +2792,7 @@
 	protected void println(String description, String value) {
 		printDescription(description);
 		print('\"');
-		StringBuffer val = new StringBuffer();
+		StringBuilder val = new StringBuilder();
 		int pos = 0, lastPos = 0;
 		while ((pos = value.indexOf('\n', lastPos)) != -1) {
 			pos++;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
index 7b3a7a2..ab23633 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
@@ -104,7 +104,7 @@
 		}
 		if (JDIDebugOptions.DEBUG_JDI_EVENTS) {
 			EventIterator eventIter = eventSet.eventIterator();
-			StringBuffer buf = new StringBuffer("JDI Event Set: {\n"); //$NON-NLS-1$
+			StringBuilder buf = new StringBuilder("JDI Event Set: {\n"); //$NON-NLS-1$
 			while (eventIter.hasNext()) {
 				buf.append(eventIter.next());
 				if (eventIter.hasNext()) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
index 574aab6..8cc7821 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpoint.java
@@ -994,7 +994,7 @@
 	}
 
 	protected String getMarkerMessage(int hitCount, int suspendPolicy) {
-		StringBuffer buff = new StringBuffer();
+		StringBuilder buff = new StringBuilder();
 		if (hitCount > 0) {
 			buff.append(MessageFormat
 					.format(JDIDebugBreakpointMessages.JavaBreakpoint___Hit_Count___0___1,
@@ -1434,7 +1434,7 @@
 	 * @throws CoreException
 	 */
 	private void writeBreakpointListeners() throws CoreException {
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		Iterator<String> iterator = fBreakpointListenerIds.iterator();
 		while (iterator.hasNext()) {
 			buf.append(iterator.next());
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpointImportParticipant.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpointImportParticipant.java
index 7acaeaa..d8d4cc3 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpointImportParticipant.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaBreakpointImportParticipant.java
@@ -135,7 +135,7 @@
 		 * @return the fully qualified name of the enclosing type
 		 */
 		private String getTypeName(ASTNode node) {
-			return getTypeName(node, new StringBuffer());
+			return getTypeName(node, new StringBuilder());
 		}
 
 		/**
@@ -147,7 +147,7 @@
 		 *            the buffer to write the name into
 		 * @return the fully qualified name of the parent
 		 */
-		private String getTypeName(ASTNode node, StringBuffer buffer) {
+		private String getTypeName(ASTNode node, StringBuilder buffer) {
 			switch (node.getNodeType()) {
 			case ASTNode.COMPILATION_UNIT: {
 				CompilationUnit unit = (CompilationUnit) node;
@@ -341,7 +341,7 @@
 						}
 					}
 				} else {
-					StringBuffer buffer = new StringBuffer();
+					StringBuilder buffer = new StringBuilder();
 					buffer.append("<init>"); //$NON-NLS-1$
 					collectSyntheticParam(node, rparams);
 					buffer.append(Signature.createMethodSignature(
@@ -423,7 +423,7 @@
 				return;
 			}
 			ASTNode parent = method.getParent();
-			StringBuffer name = new StringBuffer();
+			StringBuilder name = new StringBuilder();
 			while (parent != null) {
 				parent = parent.getParent();
 				if (parent instanceof AbstractTypeDeclaration) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
index b355a70..414803f 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaExceptionBreakpoint.java
@@ -194,7 +194,7 @@
 		if (manager == null) {
 			target.requestFailed(
 					JDIDebugBreakpointMessages.JavaExceptionBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 			return null;
 		}
 
@@ -599,7 +599,7 @@
 			return ""; //$NON-NLS-1$
 		}
 		Set<String> set = new HashSet<>(list.length);
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		for (int i = 0; i < list.length; i++) {
 			if (i > 0 && i < list.length) {
 				buffer.append(',');
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaLineBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaLineBreakpoint.java
index 44b4e2c..4a37db8 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaLineBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaLineBreakpoint.java
@@ -332,7 +332,7 @@
 		}
 		target.requestFailed(
 				JDIDebugBreakpointMessages.JavaLineBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
-				null);
+				new VMDisconnectedException());
 		return null;
 	}
 
@@ -508,7 +508,7 @@
 
 	protected String getMarkerMessage(boolean conditionEnabled,
 			String condition, int hitCount, int suspendPolicy, int lineNumber) {
-		StringBuffer message = new StringBuffer(super.getMarkerMessage(
+		StringBuilder message = new StringBuilder(super.getMarkerMessage(
 				hitCount, suspendPolicy));
 		if (lineNumber != -1) {
 			message.append(MessageFormat
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
index ba3ea73..1c33186 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaMethodBreakpoint.java
@@ -339,7 +339,7 @@
 		}
 		target.requestFailed(
 				JDIDebugBreakpointMessages.JavaMethodBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
-				null);
+				new VMDisconnectedException());
 		return null;
 	}
 
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaPatternBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaPatternBreakpoint.java
index c4d6976..08e4960 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaPatternBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaPatternBreakpoint.java
@@ -207,7 +207,7 @@
 		if (vm == null) {
 			target.requestFailed(
 					JDIDebugBreakpointMessages.JavaPatternBreakpoint_Unable_to_add_breakpoint___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 		}
 		List<ReferenceType> classes = null;
 		try {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaStratumLineBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaStratumLineBreakpoint.java
index 03807f3..5b22a82 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaStratumLineBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaStratumLineBreakpoint.java
@@ -417,7 +417,7 @@
 		if (vm == null) {
 			target.requestFailed(
 					JDIDebugBreakpointMessages.JavaPatternBreakpoint_Unable_to_add_breakpoint___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 		}
 		List<ReferenceType> classes = null;
 		try {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaTargetPatternBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaTargetPatternBreakpoint.java
index e6e470b..56f0663 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaTargetPatternBreakpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaTargetPatternBreakpoint.java
@@ -125,7 +125,7 @@
 		} else {
 			target.requestFailed(
 					JDIDebugBreakpointMessages.JavaTargetPatternBreakpoint_Unable_to_add_breakpoint___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 		}
 	}
 
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
index bbf34a3..c2cd43d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/JavaWatchpoint.java
@@ -239,7 +239,7 @@
 		if (manager == null) {
 			target.requestFailed(
 					JDIDebugBreakpointMessages.JavaWatchpoint_Unable_to_create_breakpoint_request___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 		}
 		try {
 			if (access) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
index bdf9089..18b6566 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java
@@ -191,7 +191,7 @@
 		}
 		BufferedReader reader = null;
 		try {
-			StringBuffer buffer = new StringBuffer();
+			StringBuilder buffer = new StringBuilder();
 			char[] part = new char[2048];
 			int read = 0;
 			reader = new BufferedReader(new InputStreamReader(is,
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
index 040360f..f32a064 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/JavaHotCodeReplaceManager.java
@@ -76,6 +76,7 @@
 import com.ibm.icu.text.MessageFormat;
 import com.sun.jdi.IncompatibleThreadStateException;
 import com.sun.jdi.ReferenceType;
+import com.sun.jdi.VMDisconnectedException;
 import com.sun.jdi.VirtualMachine;
 
 /**
@@ -553,7 +554,7 @@
 			if (vm == null) {
 				target.requestFailed(
 						JDIDebugHCRMessages.JavaHotCodeReplaceManager_Hot_code_replace_failed___VM_disconnected__1,
-						null);
+						new VMDisconnectedException());
 			}
 			int result = org.eclipse.jdi.hcr.VirtualMachine.RELOAD_FAILURE;
 			try {
@@ -600,7 +601,7 @@
 				if (vm == null) {
 					target.requestFailed(
 							JDIDebugHCRMessages.JavaHotCodeReplaceManager_Hot_code_replace_failed___VM_disconnected__2,
-							null);
+							new VMDisconnectedException());
 				}
 				vm.redefineClasses(typesToBytes);
 			} catch (UnsupportedOperationException exception) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDIAllInstancesValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDIAllInstancesValue.java
index f9506a0..d508df7 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDIAllInstancesValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JDIAllInstancesValue.java
@@ -295,7 +295,7 @@
 	 *         pane
 	 */
 	public String getDetailString() {
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		Object[] elements = getInstances();
 		if (elements.length == 0) {
 			buf.append(LogicalStructuresMessages.JDIAllInstancesValue_10);
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 2bbb232..9f5466b 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
@@ -179,7 +179,7 @@
 		 */
 		private void log(String[] messages) {
 			if (isContributed()) {
-				StringBuffer log = new StringBuffer();
+				StringBuilder log = new StringBuilder();
 				for (String message : messages) {
 					log.append(message).append('\n');
 				}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructures.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructures.java
index 772369a..6ec1002 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructures.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaLogicalStructures.java
@@ -204,7 +204,7 @@
 	 * Save the user defined logical structures in the preference store.
 	 */
 	public static void saveUserDefinedJavaLogicalStructures() {
-		StringBuffer logicalStructuresString = new StringBuffer();
+		StringBuilder logicalStructuresString = new StringBuilder();
 		for (Iterator<JavaLogicalStructure> iter = fUserDefinedJavaLogicalStructures.iterator(); iter
 				.hasNext();) {
 			JavaLogicalStructure logicalStructure = iter
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaStructureErrorValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaStructureErrorValue.java
index 47a091b..417775d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaStructureErrorValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/logicalstructures/JavaStructureErrorValue.java
@@ -115,7 +115,7 @@
 	public IVariable[] getVariables() throws DebugException {
 		IVariable[] variables = new IVariable[fMessages.length];
 		for (int i = 0; i < variables.length; i++) {
-			StringBuffer varName = new StringBuffer();
+			StringBuilder varName = new StringBuilder();
 			if (variables.length > 1) {
 				varName.append(
 						LogicalStructuresMessages.JavaStructureErrorValue_0)
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayEntryVariable.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayEntryVariable.java
index b9eb162..f0c9959 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayEntryVariable.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayEntryVariable.java
@@ -166,7 +166,7 @@
 		if (lastLeft < 0) {
 			return typeName;
 		}
-		StringBuffer buffer = new StringBuffer(typeName);
+		StringBuilder buffer = new StringBuilder(typeName);
 		buffer.replace(lastLeft, lastLeft + 2, ""); //$NON-NLS-1$
 		return buffer.toString();
 	}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayValue.java
index 3e8659a..6b83ff7 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIArrayValue.java
@@ -202,7 +202,7 @@
 	@Override
 	public IVariable getVariable(int offset) throws DebugException {
 		if (offset >= getLength()) {
-			requestFailed(JDIDebugModelMessages.JDIArrayValue_6, null);
+			requestFailed(JDIDebugModelMessages.JDIArrayValue_6, new IndexOutOfBoundsException(Integer.toString(offset)));
 		}
 		return new JDIArrayEntryVariable(getJavaDebugTarget(),
 				getArrayReference(), offset, fLogicalParent);
@@ -217,10 +217,10 @@
 	public IVariable[] getVariables(int offset, int length)
 			throws DebugException {
 		if (offset >= getLength()) {
-			requestFailed(JDIDebugModelMessages.JDIArrayValue_6, null);
+			requestFailed(JDIDebugModelMessages.JDIArrayValue_6, new IndexOutOfBoundsException(Integer.toString(offset)));
 		}
 		if ((offset + length - 1) >= getLength()) {
-			requestFailed(JDIDebugModelMessages.JDIArrayValue_8, null);
+			requestFailed(JDIDebugModelMessages.JDIArrayValue_8, new IndexOutOfBoundsException(Integer.toString(offset + length - 1)));
 		}
 		IVariable[] variables = new IVariable[length];
 		int index = offset;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
index ab1ea40..2f28909 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java
@@ -1250,7 +1250,7 @@
 		if (manager == null || !isAvailable()) {
 			requestFailed(
 					JDIDebugModelMessages.JDIDebugTarget_Unable_to_create_class_prepare_request___VM_disconnected__2,
-					null);
+					new VMDisconnectedException());
 		}
 		ClassPrepareRequest req = null;
 		try {
@@ -2022,7 +2022,7 @@
 			if (vm == null) {
 				requestFailed(
 						JDIDebugModelMessages.JDIDebugTarget_Unable_to_retrieve_types___VM_disconnected__4,
-						null);
+						new VMDisconnectedException());
 			}
 			List<ReferenceType> classes = vm.classesByName(name);
 			if (classes.size() == 0) {
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 13fa3f3..34c62a8 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
@@ -17,6 +17,7 @@
 
 import com.ibm.icu.text.MessageFormat;
 import com.sun.jdi.InvalidTypeException;
+import com.sun.jdi.VMDisconnectedException;
 import com.sun.jdi.Value;
 import com.sun.jdi.VirtualMachine;
 
@@ -55,7 +56,7 @@
 		if (vm == null) {
 			requestFailed(
 					JDIDebugModelMessages.JDIModificationVariable_Unable_to_generate_value___VM_disconnected__1,
-					null);
+					new VMDisconnectedException());
 		}
 		String signature = getJavaType().getSignature();
 		Value vmValue = null;
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDINullValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDINullValue.java
index 198e5af..97dacc8 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDINullValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDINullValue.java
@@ -187,7 +187,7 @@
 	 */
 	private IJavaValue npe(String selector, String signature)
 			throws DebugException {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append(selector);
 		String[] parameterTypes = Signature.getParameterTypes(signature);
 		buffer.append('(');
@@ -201,7 +201,7 @@
 		buffer.append(')');
 		requestFailed(MessageFormat.format(
 				JDIDebugModelMessages.JDINullValue_0,
-				buffer.toString()), null);
+				buffer.toString()), new NullPointerException());
 		return null;
 	}
 
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceListValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceListValue.java
index 06de5b5..02ce58e 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceListValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceListValue.java
@@ -215,7 +215,7 @@
 	 *         pane
 	 */
 	public String getDetailString() {
-		StringBuffer buf = new StringBuffer();
+		StringBuilder buf = new StringBuilder();
 		Object[] elements = getReferences();
 		if (elements.length == 0) {
 			buf.append(JDIDebugModelMessages.JDIReferenceListValue_2);
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceType.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceType.java
index 6dc2a16..4e4740e 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceType.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIReferenceType.java
@@ -290,7 +290,7 @@
 			}
 		}
 		String signature = type.signature();
-		StringBuffer res = new StringBuffer(getTypeName(signature));
+		StringBuilder res = new StringBuilder(getTypeName(signature));
 		String genericSignature = type.genericSignature();
 		if (genericSignature != null) {
 			String[] typeParameters = Signature
@@ -321,7 +321,7 @@
 			arrayDimension++;
 		}
 		int parameterStart = genericTypeSignature.indexOf('<');
-		StringBuffer name = new StringBuffer();
+		StringBuilder name = new StringBuilder();
 		if (parameterStart < 0) {
 			name.append(genericTypeSignature.substring(arrayDimension + 1,
 					genericTypeSignature.length() - 1).replace('/', '.'));
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 01e85ab..4f08b2d 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
@@ -2527,7 +2527,7 @@
 			if (manager == null) {
 				requestFailed(
 						JDIDebugModelMessages.JDIThread_Unable_to_create_step_request___VM_disconnected__1,
-						null);
+						new VMDisconnectedException());
 			}
 			try {
 				StepRequest request = manager.createStepRequest(fThread,
@@ -3347,7 +3347,7 @@
 			if (manager == null) {
 				requestFailed(
 						JDIDebugModelMessages.JDIThread_Unable_to_create_step_request___VM_disconnected__2,
-						null);
+						new VMDisconnectedException());
 			}
 			int num = getFramesToDrop();
 			if (num > 0) {
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
index c81761a..b1cfcae 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIValue.java
@@ -137,7 +137,7 @@
 			}
 		}
 		if (fValue instanceof ObjectReference) {
-			StringBuffer name = new StringBuffer();
+			StringBuilder name = new StringBuilder();
 			if (fValue instanceof ClassObjectReference) {
 				name.append('(');
 				name.append(((ClassObjectReference) fValue).reflectedType());
diff --git a/org.eclipse.jdt.debug/pom.xml b/org.eclipse.jdt.debug/pom.xml
index a2cafc8..21b69bb 100644
--- a/org.eclipse.jdt.debug/pom.xml
+++ b/org.eclipse.jdt.debug/pom.xml
@@ -18,6 +18,6 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.debug</artifactId>
-  <version>3.11.100-SNAPSHOT</version>
+  <version>3.11.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 </project>
diff --git a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
index 3a1794b..1775cb1 100644
--- a/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF
@@ -2,15 +2,15 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.launching.macosx; singleton:=true
-Bundle-Version: 3.4.100.qualifier
+Bundle-Version: 3.4.200.qualifier
 Bundle-Activator: org.eclipse.jdt.internal.launching.macosx.MacOSXLaunchingPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
-Require-Bundle: org.eclipse.debug.core;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.5.0,4.0.0)",
+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.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.5.0,4.0.0)"
+ org.eclipse.jdt.launching;bundle-version="[3.11.0,4.0.0)"
 Eclipse-LazyStart: true
 Eclipse-PlatformFilter: (osgi.os=macosx)
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java
index 1f80965..837177d 100644
--- a/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java
+++ b/org.eclipse.jdt.launching.macosx/macosx/org/eclipse/jdt/internal/launching/macosx/MacOSXVMInstall.java
@@ -49,7 +49,7 @@
                 MacOSXVMInstallType installType= (MacOSXVMInstallType) getVMInstallType();
                 String vmVersion= installType.getVMVersion(installLocation, executable);
                 // strip off extra info
-                StringBuffer version= new StringBuffer();
+                StringBuilder version= new StringBuilder();
                 for (int i= 0; i < vmVersion.length(); i++) {
                     char ch= vmVersion.charAt(i);
                     if (Character.isDigit(ch) || ch == '.') {
diff --git a/org.eclipse.jdt.launching.macosx/pom.xml b/org.eclipse.jdt.launching.macosx/pom.xml
index 82df647..001f73b 100644
--- a/org.eclipse.jdt.launching.macosx/pom.xml
+++ b/org.eclipse.jdt.launching.macosx/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.launching.macosx</artifactId>
-  <version>3.4.100-SNAPSHOT</version>
+  <version>3.4.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
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 1a347f4..378cb9e 100644
--- a/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching.ui.macosx/META-INF/MANIFEST.MF
@@ -2,13 +2,13 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.launching.ui.macosx;singleton:=true
-Bundle-Version: 1.2.100.qualifier
+Bundle-Version: 1.2.200.qualifier
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Bundle-Vendor: %providerName
 Eclipse-PlatformFilter: (osgi.os=macosx)
-Require-Bundle: org.eclipse.jdt.launching;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.5.0,4.0.0)",
+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.jface;bundle-version="[3.5.0,4.0.0)",
diff --git a/org.eclipse.jdt.launching.ui.macosx/pom.xml b/org.eclipse.jdt.launching.ui.macosx/pom.xml
index d0cc751..b106b24 100644
--- a/org.eclipse.jdt.launching.ui.macosx/pom.xml
+++ b/org.eclipse.jdt.launching.ui.macosx/pom.xml
@@ -18,7 +18,7 @@
   </parent>
   <groupId>org.eclipse.jdt</groupId>
   <artifactId>org.eclipse.jdt.launching.ui.macosx</artifactId>
-  <version>1.2.100-SNAPSHOT</version>
+  <version>1.2.200-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
diff --git a/org.eclipse.jdt.launching.ui.macosx/src/org/eclipse/jdt/internal/ui/macbundler/BundleBuilder.java b/org.eclipse.jdt.launching.ui.macosx/src/org/eclipse/jdt/internal/ui/macbundler/BundleBuilder.java
index 0e57c8a..f2a7382 100644
--- a/org.eclipse.jdt.launching.ui.macosx/src/org/eclipse/jdt/internal/ui/macbundler/BundleBuilder.java
+++ b/org.eclipse.jdt.launching.ui.macosx/src/org/eclipse/jdt/internal/ui/macbundler/BundleBuilder.java
@@ -156,7 +156,7 @@
 		int[] id= new int[] { 0 };
 		ResourceInfo[] ris= fBundleDescription.getResources(true);
 		if (ris.length > 0) {
-			StringBuffer cp= new StringBuffer();
+			StringBuilder cp= new StringBuilder();
 			for (int i= 0; i < ris.length; i++) {
 				ResourceInfo ri= ris[i];
 				String e= processClasspathEntry(java_dir, ri.fPath, id);
diff --git a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
index 535e170..1b7c4a2 100644
--- a/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.launching/META-INF/MANIFEST.MF
@@ -16,8 +16,8 @@
  org.eclipse.jdt.launching.sourcelookup.containers
 Require-Bundle: org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.jdt.core;bundle-version="[3.15.0,4.0.0)",
- org.eclipse.debug.core;bundle-version="[3.9.0,4.0.0)",
- org.eclipse.jdt.debug;bundle-version="[3.7.100,4.0.0)",
+ 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.core.variables;bundle-version="[3.2.0,4.0.0)",
  org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
  org.eclipse.osgi;bundle-version="[3.8.0,4.0.0)",
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ClasspathShortener.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ClasspathShortener.java
new file mode 100644
index 0000000..a4a1be6
--- /dev/null
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ClasspathShortener.java
@@ -0,0 +1,481 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Cedric Chabanois and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Cedric Chabanois (cchabanois@gmail.com) - Launching command line exceeds the process creation command limit on *nix - https://bugs.eclipse.org/bugs/show_bug.cgi?id=385738
+ *     IBM Corporation - Launching command line exceeds the process creation command limit on Windows - https://bugs.eclipse.org/bugs/show_bug.cgi?id=327193
+ *******************************************************************************/
+package org.eclipse.jdt.internal.launching;
+
+import static org.eclipse.jdt.internal.launching.LaunchingPlugin.LAUNCH_TEMP_FILE_PREFIX;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.jar.Attributes;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.URIUtil;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.IStatusHandler;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMInstall2;
+
+/**
+ * Shorten the classpath/modulepath if necessary.
+ *
+ * Depending on the java version, os and launch configuration, the classpath argument will be replaced by an argument file, a classpath-only jar or
+ * env variable. The modulepath is replaced by an argument file if necessary.
+ *
+ */
+public class ClasspathShortener {
+	private static final String CLASSPATH_ENV_VAR_PREFIX = "CLASSPATH="; //$NON-NLS-1$
+	public static final int ARG_MAX_LINUX = 2097152;
+	public static final int ARG_MAX_WINDOWS = 32767;
+	public static final int ARG_MAX_MACOS = 262144;
+	public static final int MAX_ARG_STRLEN_LINUX = 131072;
+	private final String os;
+	private final String javaVersion;
+	private final ILaunch launch;
+	private final List<String> cmdLine;
+	private int lastJavaArgumentIndex;
+	private String[] envp;
+	private File processTempFilesDir;
+	private final List<File> processTempFiles = new ArrayList<>();
+
+	/**
+	 *
+	 * @param vmInstall
+	 *            the vm installation
+	 * @param launch
+	 *            the launch
+	 * @param cmdLine
+	 *            the command line (java executable + VM arguments + program arguments)
+	 * @param lastJavaArgumentIndex
+	 *            the index of the last java argument in cmdLine (next arguments if any are program arguments)
+	 * @param workingDir
+	 *            the working dir to use for the launched VM or null
+	 * @param envp
+	 *            array of strings, each element of which has environment variable settings in the format name=value, or null if the subprocess should
+	 *            inherit the environment of the current process.
+	 */
+	public ClasspathShortener(IVMInstall vmInstall, ILaunch launch, String[] cmdLine, int lastJavaArgumentIndex, File workingDir, String[] envp) {
+		this(Platform.getOS(), getJavaVersion(vmInstall), launch, cmdLine, lastJavaArgumentIndex, workingDir, envp);
+	}
+
+	protected ClasspathShortener(String os, String javaVersion, ILaunch launch, String[] cmdLine, int lastJavaArgumentIndex, File workingDir, String[] envp) {
+		Assert.isNotNull(os);
+		Assert.isNotNull(javaVersion);
+		Assert.isNotNull(launch);
+		Assert.isNotNull(cmdLine);
+		this.os = os;
+		this.javaVersion = javaVersion;
+		this.launch = launch;
+		this.cmdLine = new ArrayList<>(Arrays.asList(cmdLine));
+		this.lastJavaArgumentIndex = lastJavaArgumentIndex;
+		this.envp = envp == null ? null : Arrays.copyOf(envp, envp.length);
+		this.processTempFilesDir = workingDir != null ? workingDir : Paths.get(".").toAbsolutePath().normalize().toFile(); //$NON-NLS-1$
+	}
+
+	/**
+	 * The directory to use to create temp files needed when shortening the classpath. By default, the working directory is used
+	 *
+	 * The java.io.tmpdir should not be used on MacOs (does not work for classpath-only jars)
+	 *
+	 * @param processTempFilesDir
+	 */
+	public void setProcessTempFilesDir(File processTempFilesDir) {
+		this.processTempFilesDir = processTempFilesDir;
+	}
+
+	public File getProcessTempFilesDir() {
+		return processTempFilesDir;
+	}
+
+	/**
+	 * Get the new envp. May have been modified to shorten the classpath
+	 *
+	 * @return environment variables in the format name=value or null
+	 */
+	public String[] getEnvp() {
+		return envp;
+	}
+
+	/**
+	 * Get the new command line. Modified if command line or classpath argument were too long
+	 *
+	 * @return the command line (java executable + VM arguments + program arguments)
+	 */
+	public String[] getCmdLine() {
+		return cmdLine.toArray(new String[cmdLine.size()]);
+	}
+
+	/**
+	 * The files that were created while shortening the path. They can be deleted once the process is terminated
+	 *
+	 * @return created files
+	 */
+	public List<File> getProcessTempFiles() {
+		return new ArrayList<>(processTempFiles);
+	}
+
+	/**
+	 * Shorten the command line if necessary. Each OS has different limits for command line length or command line argument length. And depending on
+	 * the OS, JVM version and launch configuration, we shorten the classpath using an argument file, a classpath-only jar or env variable.
+	 *
+	 * If we need to use a classpath-only jar to shorten the classpath, we ask confirmation from the user because it can have side effects
+	 * (System.getProperty("java.class.path") will return a classpath with only one jar). If
+	 * {@link IJavaLaunchConfigurationConstants#ATTR_USE_CLASSPATH_ONLY_JAR} is set, a classpath-only jar is used (without asking confirmation).
+	 *
+	 * @return true if command line has been shortened or false if it was not necessary or not possible. Use {@link #getCmdLine()} and
+	 *         {@link #getEnvp()} to get the new command line/environment.
+	 */
+	public boolean shortenCommandLineIfNecessary() {
+		// '|' used on purpose (not short-circuiting)
+		return shortenClasspathIfNecessary() | shortenModulePathIfNecessary();
+	}
+
+	private int getClasspathArgumentIndex() {
+		for (int i = 0; i <= lastJavaArgumentIndex; i++) {
+			String element = cmdLine.get(i);
+			if ("-cp".equals(element) || "-classpath".equals(element) || "--class-path".equals(element)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+				return i + 1;
+			}
+		}
+		return -1;
+	}
+
+	private int getModulepathArgumentIndex() {
+		for (int i = 0; i <= lastJavaArgumentIndex; i++) {
+			String element = cmdLine.get(i);
+			if ("-p".equals(element) || "--module-path".equals(element)) { //$NON-NLS-1$ //$NON-NLS-2$
+				return i + 1;
+			}
+		}
+		return -1;
+	}
+
+	private boolean shortenModulePathIfNecessary() {
+		int modulePathArgumentIndex = getModulepathArgumentIndex();
+		if (modulePathArgumentIndex == -1) {
+			return false;
+		}
+		try {
+			String modulePath = cmdLine.get(modulePathArgumentIndex);
+			if (getCommandLineLength() <= getMaxCommandLineLength() && modulePath.length() <= getMaxArgLength()) {
+				return false;
+			}
+			if (isArgumentFileSupported()) {
+				shortenModulePathUsingModulePathArgumentFile(modulePathArgumentIndex);
+				return true;
+			}
+		} catch (CoreException e) {
+			LaunchingPlugin.log(e.getStatus());
+		}
+		return false;
+	}
+
+	private boolean shortenClasspathIfNecessary() {
+		int classpathArgumentIndex = getClasspathArgumentIndex();
+		if (classpathArgumentIndex == -1) {
+			return false;
+		}
+		try {
+			boolean forceUseClasspathOnlyJar = getLaunchConfigurationUseClasspathOnlyJarAttribute();
+			if (forceUseClasspathOnlyJar) {
+				shortenClasspathUsingClasspathOnlyJar(classpathArgumentIndex);
+				return true;
+			}
+			String classpath = cmdLine.get(classpathArgumentIndex);
+			if (getCommandLineLength() <= getMaxCommandLineLength() && classpath.length() <= getMaxArgLength()) {
+				return false;
+			}
+			if (isArgumentFileSupported()) {
+				shortenClasspathUsingClasspathArgumentFile(classpathArgumentIndex);
+				return true;
+			}
+			if (os.equals(Platform.OS_WIN32)) {
+				shortenClasspathUsingClasspathEnvVariable(classpathArgumentIndex);
+				return true;
+			} else if (handleClasspathTooLongStatus()) {
+				shortenClasspathUsingClasspathOnlyJar(classpathArgumentIndex);
+				return true;
+			}
+		} catch (CoreException e) {
+			LaunchingPlugin.log(e.getStatus());
+		}
+		return false;
+	}
+
+	protected boolean getLaunchConfigurationUseClasspathOnlyJarAttribute() throws CoreException {
+		ILaunchConfiguration launchConfiguration = launch.getLaunchConfiguration();
+		if (launchConfiguration == null) {
+			return false;
+		}
+		return launchConfiguration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_CLASSPATH_ONLY_JAR, false);
+	}
+
+	public static String getJavaVersion(IVMInstall vmInstall) {
+		if (vmInstall instanceof IVMInstall2) {
+			IVMInstall2 install = (IVMInstall2) vmInstall;
+			return install.getJavaVersion();
+		}
+		return null;
+	}
+
+	private boolean isArgumentFileSupported() {
+		return JavaCore.compareJavaVersions(javaVersion, JavaCore.VERSION_9) >= 0;
+	}
+
+	private int getCommandLineLength() {
+		return cmdLine.stream().map(argument -> argument.length() + 1).reduce((a, b) -> a + b).get();
+	}
+
+	private int getEnvironmentLength() {
+		if (envp == null) {
+			return 0;
+		}
+		return Arrays.stream(envp).map(element -> element.length() + 1).reduce((a, b) -> a + b).orElse(0);
+	}
+
+	protected int getMaxCommandLineLength() {
+		// for Posix systems, ARG_MAX is the maximum length of argument to the exec functions including environment data.
+		// POSIX suggests to subtract 2048 additionally so that the process may safely modify its environment.
+		// see https://www.in-ulm.de/~mascheck/various/argmax/
+		switch (os) {
+			case Platform.OS_LINUX:
+				// ARG_MAX will be 1/4 of the stack size. 2097152 by default
+				return ARG_MAX_LINUX - getEnvironmentLength() - 2048;
+			case Platform.OS_MACOSX:
+				// on MacOs, ARG_MAX is 262144
+				return ARG_MAX_MACOS - getEnvironmentLength() - 2048;
+			case Platform.OS_WIN32:
+				// On Windows, the maximum length of the command line is 32,768 characters, including the Unicode terminating null character.
+				// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
+				return ARG_MAX_WINDOWS - 2048;
+			default:
+				return Integer.MAX_VALUE;
+		}
+	}
+
+	protected int getMaxArgLength() {
+		if (os.equals(Platform.OS_LINUX)) {
+			// On Linux, MAX_ARG_STRLEN (kernel >= 2.6.23) is the maximum length of a command line argument (or environment variable). Its value
+			// cannot be changed without recompiling the kernel.
+			return MAX_ARG_STRLEN_LINUX - 2048;
+		}
+		return Integer.MAX_VALUE;
+	}
+
+	private void shortenClasspathUsingClasspathArgumentFile(int classpathArgumentIndex) throws CoreException {
+		String classpath = cmdLine.get(classpathArgumentIndex);
+		File file = createClassPathArgumentFile(classpath);
+		removeCmdLineArgs(classpathArgumentIndex - 1, 2);
+		addCmdLineArgs(classpathArgumentIndex - 1, '@' + file.getAbsolutePath());
+		addProcessTempFile(file);
+	}
+
+	private void shortenModulePathUsingModulePathArgumentFile(int modulePathArgumentIndex) throws CoreException {
+		String modulePath = cmdLine.get(modulePathArgumentIndex);
+		File file = createModulePathArgumentFile(modulePath);
+		removeCmdLineArgs(modulePathArgumentIndex - 1, 2);
+		addCmdLineArgs(modulePathArgumentIndex - 1, '@' + file.getAbsolutePath());
+		addProcessTempFile(file);
+	}
+
+	private void shortenClasspathUsingClasspathOnlyJar(int classpathArgumentIndex) throws CoreException {
+		String classpath = cmdLine.get(classpathArgumentIndex);
+		File classpathOnlyJar = createClasspathOnlyJar(classpath);
+		removeCmdLineArgs(classpathArgumentIndex, 1);
+		addCmdLineArgs(classpathArgumentIndex, classpathOnlyJar.getAbsolutePath());
+		addProcessTempFile(classpathOnlyJar);
+	}
+
+	protected void addProcessTempFile(File file) {
+		processTempFiles.add(file);
+	}
+
+	protected boolean handleClasspathTooLongStatus() throws CoreException {
+		IStatus status = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_CLASSPATH_TOO_LONG, "", null); //$NON-NLS-1$
+		IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status);
+		if (handler == null) {
+			return false;
+		}
+		Object result = handler.handleStatus(status, launch);
+		if (!(result instanceof Boolean)) {
+			return false;
+		}
+		return (boolean) result;
+	}
+
+	private File createClasspathOnlyJar(String classpath) throws CoreException {
+		try {
+			String timeStamp = getLaunchTimeStamp();
+			File jarFile = new File(processTempFilesDir, String.format(LAUNCH_TEMP_FILE_PREFIX
+					+ "%s-classpathOnly-%s.jar", getLaunchConfigurationName(), timeStamp)); //$NON-NLS-1$
+			URI workingDirUri = processTempFilesDir.toURI();
+			StringBuilder manifestClasspath = new StringBuilder();
+			String[] classpathArray = getClasspathAsArray(classpath);
+			for (int i = 0; i < classpathArray.length; i++) {
+				if (i != 0) {
+					manifestClasspath.append(' ');
+				}
+				File file = new File(classpathArray[i]);
+				String relativePath = URIUtil.makeRelative(file.toURI(), workingDirUri).toString();
+				manifestClasspath.append(relativePath);
+			}
+			Manifest manifest = new Manifest();
+			manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); //$NON-NLS-1$
+			manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, manifestClasspath.toString());
+			try (JarOutputStream target = new JarOutputStream(new FileOutputStream(jarFile), manifest)) {
+			}
+			return jarFile;
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IStatus.ERROR, "Cannot create classpath only jar", e)); // $NON-NLS-1$ //$NON-NLS-1$
+		}
+	}
+
+	private String[] getClasspathAsArray(String classpath) {
+		return classpath.split("" + getPathSeparatorChar()); //$NON-NLS-1$
+	}
+
+	protected char getPathSeparatorChar() {
+		char separator = ':';
+		if (os.equals(Platform.OS_WIN32)) {
+			separator = ';';
+		}
+		return separator;
+	}
+
+	protected String getLaunchConfigurationName() {
+		return launch.getLaunchConfiguration().getName();
+	}
+
+	private File createClassPathArgumentFile(String classpath) throws CoreException {
+		try {
+			String timeStamp = getLaunchTimeStamp();
+			File classPathFile = new File(processTempFilesDir, String.format(LAUNCH_TEMP_FILE_PREFIX
+					+ "%s-classpath-arg-%s.txt", getLaunchConfigurationName(), timeStamp)); //$NON-NLS-1$
+
+			byte[] bytes = ("-classpath " + classpath).getBytes(StandardCharsets.UTF_8); //$NON-NLS-1$
+
+			Files.write(classPathFile.toPath(), bytes);
+			return classPathFile;
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IStatus.ERROR, "Cannot create classpath argument file", e)); //$NON-NLS-1$
+		}
+	}
+
+	private File createModulePathArgumentFile(String modulePath) throws CoreException {
+		try {
+			String timeStamp = getLaunchTimeStamp();
+			File modulePathFile = new File(processTempFilesDir, String.format(LAUNCH_TEMP_FILE_PREFIX
+					+ "%s-module-path-arg-%s.txt", getLaunchConfigurationName(), timeStamp)); //$NON-NLS-1$
+
+			byte[] bytes = ("--module-path " + modulePath).getBytes(StandardCharsets.UTF_8); //$NON-NLS-1$
+
+			Files.write(modulePathFile.toPath(), bytes);
+			return modulePathFile;
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IStatus.ERROR, "Cannot create module-path argument file", e)); //$NON-NLS-1$
+		}
+	}
+
+	protected String getLaunchTimeStamp() {
+		String timeStamp = launch.getAttribute(DebugPlugin.ATTR_LAUNCH_TIMESTAMP);
+		if (timeStamp == null) {
+			timeStamp = Long.toString(System.currentTimeMillis());
+		}
+		return timeStamp;
+	}
+
+	private String[] getEnvpFromNativeEnvironment() {
+		Map<String, String> nativeEnvironment = getNativeEnvironment();
+		String[] envp = new String[nativeEnvironment.size()];
+		int idx = 0;
+		for (Entry<String, String> entry : nativeEnvironment.entrySet()) {
+			String value = entry.getValue();
+			if (value == null) {
+				value = ""; //$NON-NLS-1$
+			}
+			String key = entry.getKey();
+			envp[idx] = key + '=' + value;
+			idx++;
+		}
+		return envp;
+	}
+
+	protected Map<String, String> getNativeEnvironment() {
+		return DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment();
+	}
+
+	private void shortenClasspathUsingClasspathEnvVariable(int classpathArgumentIndex) {
+		String classpath = cmdLine.get(classpathArgumentIndex);
+		if (envp == null) {
+			envp = getEnvpFromNativeEnvironment();
+		}
+		String classpathEnvVar = CLASSPATH_ENV_VAR_PREFIX + classpath;
+		int index = getEnvClasspathIndex(envp);
+		if (index < 0) {
+			envp = Arrays.copyOf(envp, envp.length + 1);
+			envp[envp.length - 1] = classpathEnvVar;
+		} else {
+			envp[index] = classpathEnvVar;
+		}
+		removeCmdLineArgs(classpathArgumentIndex - 1, 2);
+	}
+
+	private void removeCmdLineArgs(int index, int length) {
+		for (int i = 0; i < length; i++) {
+			cmdLine.remove(index);
+			lastJavaArgumentIndex--;
+		}
+	}
+
+	private void addCmdLineArgs(int index, String... newArgs) {
+		cmdLine.addAll(index, Arrays.asList(newArgs));
+		lastJavaArgumentIndex += newArgs.length;
+	}
+
+	/**
+	 * Returns the index in the given array for the CLASSPATH variable
+	 *
+	 * @param env
+	 *            the environment array or <code>null</code>
+	 * @return -1 or the index of the CLASSPATH variable
+	 */
+	private int getEnvClasspathIndex(String[] env) {
+		if (env != null) {
+			for (int i = 0; i < env.length; i++) {
+				if (env[i].regionMatches(true, 0, CLASSPATH_ENV_VAR_PREFIX, 0, 10)) {
+					return i;
+				}
+			}
+		}
+		return -1;
+	}
+
+}
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 12c0424..25860c0 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
@@ -38,7 +38,7 @@
 
 	@Override
 	public String toString() {
-		StringBuffer buf= new StringBuffer();
+		StringBuilder buf= new StringBuilder();
 		for (int i= 0; i < fParts.length; i++) {
 			buf.append(fParts[i].length());
 			buf.append(',');
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java
index 9090022..a50f070 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaAppletLaunchConfigurationDelegate.java
@@ -108,7 +108,7 @@
 		File tempFile = new File(dir, name + System.currentTimeMillis() + ".html"); //$NON-NLS-1$
 		try (FileOutputStream stream = new FileOutputStream(tempFile)) {
 			String encoding = getLaunchManager().getEncoding(configuration);
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
 			buf.append("<html>\n"); //$NON-NLS-1$
 			buf.append("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + encoding + "\"/>\n"); //$NON-NLS-1$ //$NON-NLS-2$
 			buf.append("<body>\n"); //$NON-NLS-1$
@@ -185,7 +185,7 @@
 			return text;
 		}
 
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		while (current > -1) {
 			buffer.append(text.substring(previous, current));
 			buffer.append(s);
@@ -346,7 +346,7 @@
 	 */
 	@Override
 	public String getVMArguments(ILaunchConfiguration configuration) throws CoreException {
-		StringBuffer arguments = new StringBuffer(super.getVMArguments(configuration));
+		StringBuilder arguments = new StringBuilder(super.getVMArguments(configuration));
 		File workingDir = verifyWorkingDirectory(configuration);
 		String javaPolicyFile = getJavaPolicyFile(workingDir);
 		arguments.append(" "); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaLaunchableTester.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaLaunchableTester.java
index 471965f..30cd679 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaLaunchableTester.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/JavaLaunchableTester.java
@@ -404,7 +404,7 @@
 
 	private boolean findAnnotation(IScanner scanner, String annotationName) throws InvalidInputException {
 		String simpleName= Signature.getSimpleName(annotationName);
-		StringBuffer buf= new StringBuffer();
+		StringBuilder buf= new StringBuilder();
 		int tok= scanner.getNextToken();
 		while (tok != ITerminalSymbols.TokenNameEOF) {
 			if (tok == ITerminalSymbols.TokenNameAT) {
@@ -421,7 +421,7 @@
 		return false;
 	}
 
-	private int readName(IScanner scanner, StringBuffer buf) throws InvalidInputException {
+	private int readName(IScanner scanner, StringBuilder buf) throws InvalidInputException {
 		int tok= scanner.getNextToken();
 		while (tok == ITerminalSymbols.TokenNameIdentifier) {
 			buf.append(scanner.getCurrentTokenSource());
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
index bdc2ee4..c37dfe7 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPlugin.java
@@ -22,6 +22,7 @@
 import java.io.OutputStream;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
@@ -104,6 +105,17 @@
 	public static final String DEBUG_FLAG = "org.eclipse.jdt.launching/debug"; //$NON-NLS-1$
 
 	/**
+	 * list of temp files for the launch (separated by the path separator char). Files must start with {@link #LAUNCH_TEMP_FILE_PREFIX} and will be
+	 * deleted once the process is terminated
+	 */
+	public static final String ATTR_LAUNCH_TEMP_FILES = "tempFiles"; //$NON-NLS-1$
+
+	/**
+	 * prefix for temp files
+	 */
+	public static final String LAUNCH_TEMP_FILE_PREFIX = ".temp-"; //$NON-NLS-1$
+
+	/**
 	 * The {@link DebugTrace} object to print to OSGi tracing
 	 * @since 3.8
 	 */
@@ -1178,11 +1190,33 @@
 				Object source = event.getSource();
 				if (source instanceof IDebugTarget || source instanceof IProcess) {
 					ArchiveSourceLocation.closeArchives();
+					IProcess process;
+					if (source instanceof IProcess) {
+						process = (IProcess) source;
+					} else {
+						process = ((IDebugTarget) source).getProcess();
+					}
+					if (process != null) {
+						deleteProcessTempFiles(process);
+					}
 				}
 			}
 		}
 	}
 
+	private void deleteProcessTempFiles(IProcess process) {
+		String tempFiles = process.getAttribute(ATTR_LAUNCH_TEMP_FILES);
+		if (tempFiles == null) {
+			return;
+		}
+		// we only delete files starting with LAUNCH_TEMP_FILE_PREFIX²
+		Arrays.stream(tempFiles.split(File.pathSeparator)).map(path -> new File(path)).filter(file -> isValidProcessTempFile(file)).forEach(file -> file.delete());
+	}
+
+	private boolean isValidProcessTempFile(File file) {
+		return file.getName().startsWith(LAUNCH_TEMP_FILE_PREFIX);
+	}
+
 	/**
 	 * Returns a shared XML parser.
 	 *
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPreferenceInitializer.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPreferenceInitializer.java
index 35c1e3c..44dc489 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPreferenceInitializer.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/LaunchingPreferenceInitializer.java
@@ -58,7 +58,7 @@
 		String val = dnode.get(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, (String)null);
 		if(val != null && !"".equals(val)) { //$NON-NLS-1$
 			String[] filters = val.split(","); //$NON-NLS-1$
-			StringBuffer buff = new StringBuffer();
+			StringBuilder buff = new StringBuilder();
 			boolean found = false;
 			for (int i = 0; i < filters.length; i++) {
 				if(launchFilter.equals(val)) {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/MacInstalledJREs.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/MacInstalledJREs.java
index 07a339c..3edee50 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/MacInstalledJREs.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/MacInstalledJREs.java
@@ -178,7 +178,7 @@
 								File loc = new File((String)home);
 								//10.8.2+ can have more than one of the same VM, which will have the same name
 								//augment it with the version to make it easier to distinguish
-								StringBuffer namebuff = new StringBuffer(name.toString());
+								StringBuilder namebuff = new StringBuilder(name.toString());
 								namebuff.append(" [").append(ver).append("]");  //$NON-NLS-1$//$NON-NLS-2$
 								MacVMStandin vm = new MacVMStandin(mactype, loc, namebuff.toString(), ver, computeId(map, ver));
 								vm.setJavadocLocation(mactype.getDefaultJavadocLocation(loc));
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ProjectClasspathVariableResolver.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ProjectClasspathVariableResolver.java
index 5083692..77bf1c0 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ProjectClasspathVariableResolver.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/ProjectClasspathVariableResolver.java
@@ -64,7 +64,7 @@
 				}
 			}
 			entries = collect.toArray(new IRuntimeClasspathEntry[collect.size()]);
-			StringBuffer buffer = new StringBuffer();
+			StringBuilder buffer = new StringBuilder();
 			for (int i = 0; i < entries.length; i++) {
 				if (i > 0) {
 					buffer.append(File.pathSeparatorChar);
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
index 2272091..de59c7b 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketAttachConnector.java
@@ -184,7 +184,7 @@
 				name = configuration.getName();
 			}
 		}
-		StringBuffer buffer = new StringBuffer(name);
+		StringBuilder buffer = new StringBuilder(name);
 		if(!"".equals(name)) { //$NON-NLS-1$
 			buffer.append(' ');
 		}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnectorProcess.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnectorProcess.java
index 622628e..cd90f76 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnectorProcess.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/SocketListenConnectorProcess.java
@@ -405,7 +405,7 @@
 					name = configuration.getName();
 				}
 			}
-			StringBuffer buffer = new StringBuffer(name);
+			StringBuilder buffer = new StringBuilder(name);
 			if (fConnectionLimit != 1) {
 				// if we're accepting multiple incoming connections,
 				// append the time when each connection was accepted
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java
index fb9f643..6b08810 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/Standard11xVMRunner.java
@@ -15,6 +15,7 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -83,9 +84,7 @@
 			combinedPath[offset] = classPath[i];
 			offset++;
 		}
-		int cpidx = -1;
 		if (combinedPath.length > 0) {
-			cpidx = arguments.size();
 			arguments.add("-classpath"); //$NON-NLS-1$
 			arguments.add(convertClassPath(combinedPath));
 		}
@@ -94,12 +93,7 @@
 		String[] programArgs= config.getProgramArguments();
 
 		String[] envp = prependJREPath(config.getEnvironment());
-		String[] newenvp = checkClasspath(arguments, classPath, envp);
-		if(newenvp != null) {
-			envp = newenvp;
-			arguments.remove(cpidx);
-			arguments.remove(cpidx);
-		}
+		int lastVMArgumentIndex = arguments.size() - 1;
 		addArguments(programArgs, arguments);
 
 		String[] cmdLine= new String[arguments.size()];
@@ -109,12 +103,17 @@
 		if (monitor.isCanceled()) {
 			return;
 		}
+		File workingDir = getWorkingDir(config);
+		ClasspathShortener classpathShortener = new ClasspathShortener(fVMInstance, launch, cmdLine, lastVMArgumentIndex, workingDir, envp);
+		if (classpathShortener.shortenCommandLineIfNecessary()) {
+			cmdLine = classpathShortener.getCmdLine();
+			envp = classpathShortener.getEnvp();
+		}
 
 		subMonitor.worked(1);
 		subMonitor.subTask(LaunchingMessages.StandardVMRunner_Starting_virtual_machine____3);
 
 		Process p= null;
-		File workingDir = getWorkingDir(config);
 		String[] newCmdLine = validateCommandLine(launch.getLaunchConfiguration(), cmdLine);
 		if(newCmdLine != null) {
 			cmdLine = newCmdLine;
@@ -138,6 +137,10 @@
 		if(workingDir != null) {
 			process.setAttribute(DebugPlugin.ATTR_WORKING_DIRECTORY, workingDir.getAbsolutePath());
 		}
+		if (!classpathShortener.getProcessTempFiles().isEmpty()) {
+			String tempFiles = classpathShortener.getProcessTempFiles().stream().map(file -> file.getAbsolutePath()).collect(Collectors.joining(File.pathSeparator));
+			process.setAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES, tempFiles);
+		}
 		subMonitor.worked(1);
 	}
 }
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVM.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVM.java
index 35312a3..9166158 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVM.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVM.java
@@ -56,7 +56,7 @@
             if (executable != null) {
                 String vmVersion = installType.getVMVersion(installLocation, executable);
                 // strip off extra info
-                StringBuffer version = new StringBuffer();
+                StringBuilder version = new StringBuilder();
                 for (int i = 0; i < vmVersion.length(); i++) {
                     char ch = vmVersion.charAt(i);
                     if (Character.isDigit(ch) || ch == '.') {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
index 99b1e5e..caa4d05 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMDebugger.java
@@ -21,6 +21,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
@@ -217,9 +218,7 @@
 		}
 
 		String[] cp= config.getClassPath();
-		int cpidx = -1;
 		if (cp.length > 0) {
-			cpidx = arguments.size();
 			arguments.add("-classpath"); //$NON-NLS-1$
 			arguments.add(convertClassPath(cp));
 		}
@@ -239,7 +238,7 @@
 		} else {
 			arguments.add(config.getClassToLaunch());
 		}
-
+		int lastVMArgumentIndex = arguments.size() - 1;
 		/*
 		 * String[] cp= config.getClassPath(); int cpidx = -1; if (cp.length > 0) { cpidx = arguments.size(); arguments.add("-classpath");
 		 * //$NON-NLS-1$ arguments.add(convertClassPath(cp)); }
@@ -253,13 +252,6 @@
 		//format: <jdk path>/jre/bin
 		String[] envp = prependJREPath(config.getEnvironment(), new Path(program));
 
-		String[] newenvp = checkClasspath(arguments, cp, envp);
-		if(newenvp != null) {
-			envp = newenvp;
-			arguments.remove(cpidx);
-			arguments.remove(cpidx);
-		}
-
 		String[] cmdLine= new String[arguments.size()];
 		arguments.toArray(cmdLine);
 
@@ -267,6 +259,12 @@
 		if (monitor.isCanceled()) {
 			return;
 		}
+		File workingDir = getWorkingDir(config);
+		ClasspathShortener classpathShortener = new ClasspathShortener(fVMInstance, launch, cmdLine, lastVMArgumentIndex, workingDir, envp);
+		if (classpathShortener.shortenCommandLineIfNecessary()) {
+			cmdLine = classpathShortener.getCmdLine();
+			envp = classpathShortener.getEnvp();
+		}
 
 		subMonitor.worked(1);
 		subMonitor.subTask(LaunchingMessages.StandardVMDebugger_Starting_virtual_machine____4);
@@ -288,7 +286,6 @@
 
 				connector.startListening(map);
 
-				File workingDir = getWorkingDir(config);
 				String[] newCmdLine = validateCommandLine(launch.getLaunchConfiguration(), cmdLine);
 				if(newCmdLine != null) {
 					cmdLine = newCmdLine;
@@ -314,7 +311,7 @@
 				}
 				if(envp != null) {
 					Arrays.sort(envp);
-					StringBuffer buff = new StringBuffer();
+					StringBuilder buff = new StringBuilder();
 					for (int i = 0; i < envp.length; i++) {
 						buff.append(envp[i]);
 						if(i < envp.length-1) {
@@ -323,6 +320,10 @@
 					}
 					process.setAttribute(DebugPlugin.ATTR_ENVIRONMENT, buff.toString());
 				}
+				if (!classpathShortener.getProcessTempFiles().isEmpty()) {
+					String tempFiles = classpathShortener.getProcessTempFiles().stream().map(file -> file.getAbsolutePath()).collect(Collectors.joining(File.pathSeparator));
+					process.setAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES, tempFiles);
+				}
 				subMonitor.worked(1);
 				subMonitor.subTask(LaunchingMessages.StandardVMDebugger_Establishing_debug_connection____5);
 				int retryCount = 0;
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 af3dd37..47060d2 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
@@ -20,6 +20,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.stream.Collectors;
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -303,7 +304,7 @@
 
 	protected String convertClassPath(String[] cp) {
 		int pathCount= 0;
-		StringBuffer buf= new StringBuffer();
+		StringBuilder buf= new StringBuilder();
 		if (cp.length == 0) {
 			return "";    //$NON-NLS-1$
 		}
@@ -380,9 +381,7 @@
 			arguments.add(convertClassPath(mp));
 		}
 		String[] cp = config.getClassPath();
-		int cpidx = -1;
 		if (cp.length > 0) {
-			cpidx = arguments.size();
 			arguments.add("-classpath"); //$NON-NLS-1$
 			arguments.add(convertClassPath(cp));
 		}
@@ -395,26 +394,18 @@
 			}
 
 		}
-
 		if (isModular(config, fVMInstance)) {
 			arguments.add("-m"); //$NON-NLS-1$
 			arguments.add(config.getModuleDescription() + "/" + config.getClassToLaunch()); //$NON-NLS-1$
 		} else {
 			arguments.add(config.getClassToLaunch());
 		}
-
+		int lastVMArgumentIndex = arguments.size() - 1;
 		String[] programArgs= config.getProgramArguments();
 		addArguments(programArgs, arguments);
 
 		String[] envp = prependJREPath(config.getEnvironment());
 
-		String[] newenvp = checkClasspath(arguments, cp, envp);
-		if(newenvp != null) {
-			envp = newenvp;
-			arguments.remove(cpidx);
-			arguments.remove(cpidx);
-		}
-
 		String[] cmdLine= new String[arguments.size()];
 		arguments.toArray(cmdLine);
 
@@ -424,10 +415,15 @@
 		if (monitor.isCanceled()) {
 			return;
 		}
+		File workingDir = getWorkingDir(config);
+		ClasspathShortener classpathShortener = new ClasspathShortener(fVMInstance, launch, cmdLine, lastVMArgumentIndex, workingDir, envp);
+		if (classpathShortener.shortenCommandLineIfNecessary()) {
+			cmdLine = classpathShortener.getCmdLine();
+			envp = classpathShortener.getEnvp();
+		}
 
 		subMonitor.subTask(LaunchingMessages.StandardVMRunner_Starting_virtual_machine____3);
 		Process p= null;
-		File workingDir = getWorkingDir(config);
 		String[] newCmdLine = validateCommandLine(launch.getLaunchConfiguration(), cmdLine);
 		if(newCmdLine != null) {
 			cmdLine = newCmdLine;
@@ -453,7 +449,7 @@
 		}
 		if(envp != null) {
 			Arrays.sort(envp);
-			StringBuffer buff = new StringBuffer();
+			StringBuilder buff = new StringBuilder();
 			for (int i = 0; i < envp.length; i++) {
 				buff.append(envp[i]);
 				if(i < envp.length-1) {
@@ -462,6 +458,10 @@
 			}
 			process.setAttribute(DebugPlugin.ATTR_ENVIRONMENT, buff.toString());
 		}
+		if (!classpathShortener.getProcessTempFiles().isEmpty()) {
+			String tempFiles = classpathShortener.getProcessTempFiles().stream().map(file -> file.getAbsolutePath()).collect(Collectors.joining(File.pathSeparator));
+			process.setAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES, tempFiles);
+		}
 		subMonitor.worked(1);
 		subMonitor.done();
 	}
@@ -484,71 +484,6 @@
 	}
 
 	/**
-	 * Checks to see if the command / classpath needs to be shortened for Windows. Returns the modified
-	 * environment or <code>null</code> if no changes are needed.
-	 *
-	 * @param args the raw arguments from the runner
-	 * @param cp the raw classpath from the runner configuration
-	 * @param env the current environment
-	 * @return the modified environment or <code>null</code> if no changes were made
-	 * @sine 3.6.200
-	 */
-	String[] checkClasspath(List<String> args, String[] cp, String[] env) {
-		if(Platform.getOS().equals(Platform.OS_WIN32)) {
-			//count the complete command length
-			int size = 0;
-			for (String arg : args) {
-				if(arg != null) {
-					size += arg.length();
-				}
-			}
-			//greater than 32767 is a no-go
-			//see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
-			if(size > 32767) {
-				StringBuffer newcp = new StringBuffer("CLASSPATH="); //$NON-NLS-1$
-				for (int i = 0; i < cp.length; i++) {
-					newcp.append(cp[i]);
-					newcp.append(File.pathSeparatorChar);
-				}
-				String[] newenvp = null;
-				int index = -1;
-				if(env == null) {
-					Map<String, String> nenv = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment();
-					Entry<String, String> entry = null;
-					newenvp = new String[nenv.size()];
-					int idx = 0;
-					for (Iterator<Entry<String, String>> i = nenv.entrySet().iterator(); i.hasNext();) {
-						entry = i.next();
-						String value = entry.getValue();
-						if(value == null) {
-							value = ""; //$NON-NLS-1$
-						}
-						String key = entry.getKey();
-						if(key.equalsIgnoreCase("CLASSPATH")) { //$NON-NLS-1$
-							index = idx;
-						}
-						newenvp[idx] = key+'='+value;
-						idx++;
-					}
-				}
-				else {
-					newenvp = env;
-					index = getCPIndex(newenvp);
-				}
-				if(index < 0) {
-					String[] newenv = new String[newenvp.length+1];
-					System.arraycopy(newenvp, 0, newenv, 0, newenvp.length);
-					newenv[newenvp.length] = newcp.toString();
-					return newenv;
-				}
-				newenvp[index] = newcp.toString();
-				return newenvp;
-			}
-		}
-		return null;
-	}
-
-	/**
 	 * Prepends the correct java version variable state to the environment path for Mac VMs
 	 *
 	 * @param env the current array of environment variables to run with
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
index ffabb5b..16e04d6 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/StandardVMType.java
@@ -371,7 +371,7 @@
 		if (extension != null) {
 			IPath srcPath = new Path(libLocation.getPath());
 			srcPath = srcPath.removeLastSegments(1);
-			StringBuffer buf = new StringBuffer();
+			StringBuilder buf = new StringBuilder();
 			buf.append(prefix);
 			buf.append("-src."); //$NON-NLS-1$
 			buf.append(extension);
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/VMDefinitionsContainer.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/VMDefinitionsContainer.java
index 8f48cf3..21cccc5 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/VMDefinitionsContainer.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/internal/launching/VMDefinitionsContainer.java
@@ -342,7 +342,7 @@
 		} else {
 			String[] vmArgs = vm.getVMArguments();
 			if (vmArgs != null && vmArgs.length > 0) {
-				StringBuffer buffer = new StringBuffer();
+				StringBuilder buffer = new StringBuilder();
 				for (int i = 0; i < vmArgs.length; i++) {
 					buffer.append(vmArgs[i] + " "); //$NON-NLS-1$
 				}
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
index a97cc4d..d02870a 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractJavaLaunchConfigurationDelegate.java
@@ -594,7 +594,7 @@
 			// if a library path is already specified, do not override
 			String[] javaLibraryPath = getJavaLibraryPath(configuration);
 			if (javaLibraryPath != null && javaLibraryPath.length > 0) {
-				StringBuffer path = new StringBuffer(args);
+				StringBuilder path = new StringBuilder(args);
 				path.append(" -Djava.library.path="); //$NON-NLS-1$
 				path.append("\""); //$NON-NLS-1$
 				for (int i = 0; i < javaLibraryPath.length; i++) {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMInstall.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMInstall.java
index ddaa77a..e319715 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMInstall.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMInstall.java
@@ -298,7 +298,7 @@
 		if (vmArgs == null) {
 			setVMArgs(null);
 		} else {
-		    StringBuffer buf = new StringBuffer();
+		    StringBuilder buf = new StringBuilder();
 		    for (int i = 0; i < vmArgs.length; i++) {
 	            String string = vmArgs[i];
 	            buf.append(string);
@@ -486,7 +486,7 @@
 	 * @return preference store key
 	 */
 	private String getSystemPropertyKey(String property) {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append(PREF_VM_INSTALL_SYSTEM_PROPERTY);
 		buffer.append("."); //$NON-NLS-1$
 		buffer.append(getVMInstallType().getId());
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMRunner.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMRunner.java
index de281cd..0adccbc 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMRunner.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/AbstractVMRunner.java
@@ -142,7 +142,7 @@
 	 * @return a single space-delimited string
 	 */
 	protected String getCmdLineAsString(String[] cmdLine) {
-		StringBuffer buff= new StringBuffer();
+		StringBuilder buff= new StringBuilder();
 		for (int i = 0, numStrings= cmdLine.length; i < numStrings; i++) {
 			buff.append(cmdLine[i]);
 			buff.append(' ');
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
index 5e910b6..873e5c6 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/IJavaLaunchConfigurationConstants.java
@@ -369,8 +369,12 @@
 	public static final String ATTR_EXCLUDE_TEST_CODE = LaunchingPlugin.getUniqueIdentifier() + ".ATTR_EXCLUDE_TEST_CODE"; //$NON-NLS-1$
 
 	/**
-	 * Status code indicating a launch configuration does not
-	 * specify a project when a project is required.
+	 * @since 3.11
+	 */
+	public static final String ATTR_USE_CLASSPATH_ONLY_JAR = LaunchingPlugin.getUniqueIdentifier() + ".ATTR_USE_CLASSPATH_ONLY_JAR"; //$NON-NLS-1$
+
+	/**
+	 * Status code indicating a launch configuration does not specify a project when a project is required.
 	 */
 	public static final int ERR_UNSPECIFIED_PROJECT = 100;
 
@@ -540,6 +544,11 @@
 	public static final int ERR_PROJECT_CLOSED = 124;
 
 	/**
+	 * @since 3.11
+	 */
+	public static final int ERR_CLASSPATH_TOO_LONG = 125;
+
+	/**
 	 * Status code indicating an unexpected internal error.
 	 */
 	public static final int ERR_INTERNAL_ERROR = 150;
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
index 90c1942..54a94ce 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/JavaRuntime.java
@@ -3134,7 +3134,7 @@
 	 * @since 3.1
 	 */
 	public static IClasspathAttribute newLibraryPathsAttribute(String[] paths) {
-		StringBuffer value = new StringBuffer();
+		StringBuilder value = new StringBuilder();
 		for (int i = 0; i < paths.length; i++) {
 			value.append(paths[i]);
 			if (i < (paths.length - 1)) {
diff --git a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/environments/ExecutionEnvironmentDescription.java b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/environments/ExecutionEnvironmentDescription.java
index eb08641..42a77a4 100644
--- a/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/environments/ExecutionEnvironmentDescription.java
+++ b/org.eclipse.jdt.launching/launching/org/eclipse/jdt/launching/environments/ExecutionEnvironmentDescription.java
@@ -298,7 +298,7 @@
 	 * @return VM arguments or <code>null</code> if none
 	 */
 	public String getVMArguments() {
-		StringBuffer arguments = new StringBuffer();
+		StringBuilder arguments = new StringBuilder();
 		Iterator<Entry<String, String>> entries = fProperties.entrySet().iterator();
 		while (entries.hasNext()) {
 			Entry<String, String> entry = entries.next();
@@ -427,11 +427,11 @@
 	private String resolveHome(String value) {
 		int start = 0;
 		int index = value.indexOf(VAR_EE_HOME, start);
-		StringBuffer replaced = null;
+		StringBuilder replaced = null;
 		String eeHome = getProperty(EE_HOME);
 		while (index >= 0) {
 			if (replaced == null) {
-				replaced = new StringBuffer();
+				replaced = new StringBuilder();
 			}
 			replaced.append(value.substring(start, index));
 			replaced.append(eeHome);
@@ -513,7 +513,7 @@
 					value = makePathAbsolute(value, root);
 
 					List<Character> wildcards = new ArrayList<>();
-					StringBuffer keyBuffer = new StringBuffer();
+					StringBuilder keyBuffer = new StringBuilder();
 				    char [] chars = key.toCharArray();
 				    // Convert lib location to a regex, replace wildcards with grouped equivalents, keep track of used wildcards, allow '\' and '/' to be used, escape special chars
 					for (int j = 0; j < chars.length; j++) {
@@ -531,7 +531,7 @@
 					}
 
 					int currentWild = 0;
-					StringBuffer valueBuffer = new StringBuffer();
+					StringBuilder valueBuffer = new StringBuilder();
 					chars = value.toCharArray();
 					// Convert src location to a regex, replace wildcards with their group number, allow '\' and '/' to be used, escape special chars
 					for (int j = 0; j < chars.length; j++) {
diff --git a/org.eclipse.jdt.launching/support/org/eclipse/jdt/internal/launching/support/LegacySystemProperties.java b/org.eclipse.jdt.launching/support/org/eclipse/jdt/internal/launching/support/LegacySystemProperties.java
index 2f03ffa..61e9079 100644
--- a/org.eclipse.jdt.launching/support/org/eclipse/jdt/internal/launching/support/LegacySystemProperties.java
+++ b/org.eclipse.jdt.launching/support/org/eclipse/jdt/internal/launching/support/LegacySystemProperties.java
@@ -19,7 +19,7 @@
 public class LegacySystemProperties {
 
 	public static void main(String[] args) {
-		StringBuffer buffer = new StringBuffer();
+		StringBuilder buffer = new StringBuilder();
 		buffer.append("<systemProperties>\n");    //$NON-NLS-1$
 		for (int i = 0; i < args.length; i++) {
 			String name = args[i];