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

# Conflicts:
#	org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
#	org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
#	org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
#	org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
#	org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
#	org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java

Change-Id: I284c23829a6de8131b7ca33af8f27bfc95ab4574
diff --git a/org.eclipse.jdt.compiler.apt.tests/.classpath b/org.eclipse.jdt.compiler.apt.tests/.classpath
index 3592a95..8102373 100644
--- a/org.eclipse.jdt.compiler.apt.tests/.classpath
+++ b/org.eclipse.jdt.compiler.apt.tests/.classpath
@@ -16,7 +16,7 @@
 		</attributes>
 	</classpathentry>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
-	<classpathentry kind="lib" path="java10/java10api.jar"/>
+	<classpathentry kind="lib" path="lib/java10api.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF
index cd2f132..f08a46a 100644
--- a/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.compiler.apt.tests/META-INF/MANIFEST.MF
@@ -19,6 +19,6 @@
  org.eclipse.jdt.compiler.apt.tests.processors.visitors
 Import-Package: org.eclipse.jdt.internal.compiler.tool;resolution:=optional
 Eclipse-BundleShape: dir
-Bundle-ClassPath: java10/java10api.jar,
+Bundle-ClassPath: lib/java10api.jar,
  .
 Automatic-Module-Name: org.eclipse.jdt.compiler.apt.tests
diff --git a/org.eclipse.jdt.compiler.apt.tests/build.properties b/org.eclipse.jdt.compiler.apt.tests/build.properties
index e872602..e9a85cc 100644
--- a/org.eclipse.jdt.compiler.apt.tests/build.properties
+++ b/org.eclipse.jdt.compiler.apt.tests/build.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2006, 2018 BEA Systems Inc. and others
+# Copyright (c) 2006, 2019 BEA Systems Inc. and others
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -23,9 +23,8 @@
                test.xml,\
                META-INF/,\
                resources/,\
-               java10/,\
                lib/,\
                .
 src.includes = about.html
 compilerArg=-proc:none
-jars.extra.classpath = java10/java10api.jar
+jars.extra.classpath = lib/java10api.jar
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index 363e26f..e18d62e 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/java10/java10api.jar b/org.eclipse.jdt.compiler.apt.tests/lib/java10api.jar
similarity index 100%
rename from org.eclipse.jdt.compiler.apt.tests/java10/java10api.jar
rename to org.eclipse.jdt.compiler.apt.tests/lib/java10api.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
index 8b8bccf..4d83445 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/META-INF/services/javax.annotation.processing.Processor
@@ -1,3 +1,4 @@
 org.eclipse.jdt.compiler.apt.tests.processors.elements.Java8ElementProcessor

 org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor

-org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor
\ No newline at end of file
+org.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor

+org.eclipse.jdt.compiler.apt.tests.processors.elements.Java12ElementProcessor
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java
new file mode 100644
index 0000000..8fcd6b1
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java12ElementProcessor.java
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.compiler.apt.tests.processors.elements;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+
+import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
+
+/**
+ * A processor that explores the java 9 specific elements and validates the lambda and 
+ * type annotated elements. To enable this processor, add 
+ * -Aorg.eclipse.jdt.compiler.apt.tests.processors.elements.Java11ElementProcessor to the command line.
+ * @since 3.14
+ */
+@SupportedAnnotationTypes("*")
+public class Java12ElementProcessor extends BaseProcessor {
+	boolean reportSuccessAlready = true;
+	RoundEnvironment roundEnv = null;
+	Messager _messager = null;
+	Filer _filer = null;
+	boolean isBinaryMode = false;
+	@Override
+	public synchronized void init(ProcessingEnvironment processingEnv) {
+		super.init(processingEnv);
+		_elementUtils = processingEnv.getElementUtils();
+		_messager = processingEnv.getMessager();
+		_filer = processingEnv.getFiler();
+	}
+	// Always return false from this processor, because it supports "*".
+	// The return value does not signify success or failure!
+	@Override
+	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+		if (roundEnv.processingOver()) {
+			return false;
+		}
+		
+		this.roundEnv = roundEnv;
+		Map<String, String> options = processingEnv.getOptions();
+		if (!options.containsKey(this.getClass().getName())) {
+			// Disable this processor unless we are intentionally performing the test.
+			return false;
+		} else {
+			try {
+				if (options.containsKey("binary")) {
+					this.isBinaryMode = true;
+				}
+				if (!invokeTestMethods(options)) {
+					testAll();
+				}
+				if (this.reportSuccessAlready) {
+					super.reportSuccess();
+				}
+			} catch (AssertionFailedError e) {
+				super.reportError(getExceptionStackTrace(e));
+			} catch (Throwable e) {
+				e.printStackTrace();
+			}
+		}
+		return false;
+	}
+
+	private boolean invokeTestMethods(Map<String, String> options) throws Throwable {
+		Method testMethod = null;
+		Set<String> keys = options.keySet();
+		boolean testsFound = false;
+		for (String option : keys) {
+			if (option.startsWith("test")) {
+				try {
+					testMethod = this.getClass().getDeclaredMethod(option, new Class[0]);
+					if (testMethod != null) {
+						testsFound = true;
+						testMethod.invoke(this,  new Object[0]);
+					}
+				} catch (InvocationTargetException e) {
+					throw e.getCause();
+				} catch (Exception e) {
+					super.reportError(getExceptionStackTrace(e));
+				}
+			}
+		}
+		return testsFound;
+	}
+
+	public void testAll() throws AssertionFailedError, IOException {
+		testRootElements1();
+	}
+
+	public void testRootElements1() throws IOException {
+		Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+		List<String> types = new ArrayList<>();
+		List<String> modules = new ArrayList<>();
+		ModuleElement mod1 = null, mod2 = null, mod3 = null;
+		for (Element element : rootElements) {
+			Element root = getRoot(element);
+			String modName = null;
+			ModuleElement mod = null;
+			if (element instanceof ModuleElement) {
+				mod = (ModuleElement) element;
+				modName = mod.getQualifiedName().toString();
+				if (!modules.contains(modName) && !modName.equals("java.base"))
+					modules.add(modName);
+				assertNull("module should not have an enclosing element", root);
+			} else {
+				if (element instanceof TypeElement) {
+					types.add(((TypeElement) element).getQualifiedName().toString());
+				}
+				assertTrue("Should be a module element", (root instanceof ModuleElement));
+				mod = (ModuleElement) root;
+				modName = mod.getQualifiedName().toString();
+				assertFalse("should be a named module", mod.isUnnamed());
+				String string = mod.getQualifiedName().toString();
+				if (!modules.contains(string) && !modName.equals("java.base"))
+					modules.add(string);
+			}
+			if (modName.equals("module.main")) {
+				mod1 = mod;
+			} else if (modName.equals("module.readable.one")) {
+				mod2 = mod;
+			} else if (modName.equals("module.readable.two")) {
+				mod3 = mod;
+			} 
+		}
+		Collections.sort(types, (x, y) -> x.compareTo(y)); //unused as of now
+		Collections.sort(modules, (x, y) -> x.compareTo(y));
+		assertEquals("incorrect no of modules in root elements", 3, modules.size());
+		assertEquals("incorrect modules among root elements", "[module.main, module.readable.one, module.readable.two]", modules.toString());
+		assertNotNull("module should not be null", mod1);
+		assertNotNull("module should not be null", mod2);
+		assertNotNull("module should not be null", mod3);
+		assertEquals("Incorrect enclosed packages", "[lang.MOD.same, ]", getElementsAsString(mod3.getEnclosedElements()));
+		assertEquals("Incorrect enclosed packages", "[lang.MOD.same, ]", getElementsAsString(mod2.getEnclosedElements()));
+		assertEquals("Incorrect enclosed packages", "[lang.MOD, ]", getElementsAsString(mod1.getEnclosedElements()));
+	}
+
+	public void testRootElements2() throws IOException {
+		Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+		List<String> types = new ArrayList<>();
+		List<String> modules = new ArrayList<>();
+		ModuleElement mod1 = null, mod2 = null, mod3 = null;
+		for (Element element : rootElements) {
+			Element root = getRoot(element);
+			String modName = null;
+			ModuleElement mod = null;
+			if (element instanceof ModuleElement) {
+				mod = (ModuleElement) element;
+				modName = mod.getQualifiedName().toString();
+				if (!modules.contains(modName) && !modName.equals("java.base"))
+					modules.add(modName);
+				assertNull("module should not have an enclosing element", root);
+			} else {
+				if (element instanceof TypeElement) {
+					types.add(((TypeElement) element).getQualifiedName().toString());
+				}
+				assertTrue("Should be a module element", (root instanceof ModuleElement));
+				mod = (ModuleElement) root;
+				modName = mod.getQualifiedName().toString();
+				assertFalse("should be a named module", mod.isUnnamed());
+				String string = mod.getQualifiedName().toString();
+				if (!modules.contains(string) && !modName.equals("java.base"))
+					modules.add(string);
+			}
+			if (modName.equals("module.main")) {
+				mod1 = mod;
+			} else if (modName.equals("module.readable.one")) {
+				mod2 = mod;
+			} else if (modName.equals("module.readable.two")) {
+				mod3 = mod;
+			} 
+		}
+		Collections.sort(types, (x, y) -> x.compareTo(y)); //unused as of now
+		Collections.sort(modules, (x, y) -> x.compareTo(y));
+		assertEquals("incorrect no of modules in root elements", this.isBinaryMode ? 2 : 3, modules.size());
+		assertEquals("incorrect modules among root elements", "[module.main, module.readable.one" + 
+							(this.isBinaryMode ? "" : ", module.readable.two") + "]", modules.toString());
+		assertNotNull("module should not be null", mod1);
+		assertEquals("Incorrect enclosed packages", "[my.mod, ]", getElementsAsString(mod1.getEnclosedElements()));
+		assertEquals("Incorrect enclosed packages", "[my.mod.same, ]", getElementsAsString(mod2.getEnclosedElements()));
+		assertNotNull("module should not be null", mod2);
+		if (!this.isBinaryMode) {
+			assertNotNull("module should not be null", mod3);
+			assertEquals("Incorrect enclosed packages", "[]", getElementsAsString(mod3.getEnclosedElements()));
+		}
+	}
+	private Element getRoot(Element elem) {
+		Element enclosingElement = elem.getEnclosingElement();
+		while (enclosingElement != null) {
+			if (enclosingElement instanceof ModuleElement) {
+				return enclosingElement;
+			}
+			enclosingElement = enclosingElement.getEnclosingElement();
+		}
+		return enclosingElement;
+	}
+
+	@Override
+	public void reportError(String msg) {
+		throw new AssertionFailedError(msg);
+	}
+	private String getExceptionStackTrace(Throwable t) {
+		StringBuffer buf = new StringBuffer(t.getMessage());
+		StackTraceElement[] traces = t.getStackTrace();
+		for (int i = 0; i < traces.length; i++) {
+			StackTraceElement trace = traces[i];
+			buf.append("\n\tat " + trace);
+			if (i == 12)
+				break; // Don't dump all stacks
+		}
+		return buf.toString();
+	}
+	protected String getElementsAsString(List<? extends Element> list) {
+		StringBuilder builder = new StringBuilder("[");
+		for (Element element : list) {
+			if (element instanceof PackageElement) {
+				builder.append(((PackageElement) element).getQualifiedName());
+			} else if (element instanceof ModuleElement) {
+				builder.append(((ModuleElement) element).getQualifiedName());
+			} else if (element instanceof TypeElement) {
+				builder.append(((TypeElement) element).getQualifiedName());
+			}  else {
+				builder.append(element.getSimpleName());
+			}
+			builder.append(", ");
+		}
+		builder.append("]");
+		return builder.toString();
+	}
+	public void assertModifiers(Set<Modifier> modifiers, String[] expected) {
+		assertEquals("Incorrect no of modifiers", modifiers.size(), expected.length);
+		Set<String> actual = new HashSet<String>(expected.length);
+		for (Modifier modifier : modifiers) {
+			actual.add(modifier.toString());
+		}
+		for(int i = 0, length = expected.length; i < length; i++) {
+			boolean result = actual.remove(expected[i]);
+			if (!result) reportError("Modifier not present :" + expected[i]);
+		}
+		if (!actual.isEmpty()) {
+			reportError("Unexpected modifiers present:" + actual.toString());
+		}
+	}
+	public void assertTrue(String msg, boolean value) {
+		if (!value) reportError(msg);
+	}
+	public void assertFalse(String msg, boolean value) {
+		if (value) reportError(msg);
+	}
+	public void assertSame(String msg, Object obj1, Object obj2) {
+		if (obj1 != obj2) {
+			reportError(msg + ", should be " + obj1.toString() + " but " + obj2.toString());
+		}
+	}
+	public void assertNotSame(String msg, Object obj1, Object obj2) {
+		if (obj1 == obj2) {
+			reportError(msg + ", " + obj1.toString() + " should not be same as " + obj2.toString());
+		}
+	}
+	public void assertNotNull(String msg, Object obj) {
+		if (obj == null) {
+			reportError(msg);
+		}
+	}
+	public void assertNull(String msg, Object obj) {
+		if (obj != null) {
+			reportError(msg);
+		}
+	}
+    public void assertEquals(String message, Object expected, Object actual) {
+        if (equalsRegardingNull(expected, actual)) {
+            return;
+        } else {
+        	reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+        }
+    }
+
+    public void assertEquals(String message, Object expected, Object alternateExpected, Object actual) {
+        if (equalsRegardingNull(expected, actual) || equalsRegardingNull(alternateExpected, actual)) {
+            return;
+        } else {
+        	reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+        }
+    }
+    
+    static boolean equalsRegardingNull(Object expected, Object actual) {
+        if (expected == null) {
+            return actual == null;
+        }
+        return expected.equals(actual);
+    }
+    
+	public void assertEquals(String msg, int expected, int actual) {
+		if (expected != actual) {
+			StringBuffer buf = new StringBuffer();
+			buf.append(msg);
+			buf.append(", expected " + expected + " but was " + actual);
+			reportError(buf.toString());
+		}
+	}
+	public void assertEquals(Object expected, Object actual) {
+		if (expected != actual) {
+			
+		}
+	}
+	private class AssertionFailedError extends Error {
+		private static final long serialVersionUID = 1L;
+
+		public AssertionFailedError(String msg) {
+			super(msg);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java
new file mode 100644
index 0000000..c11e8d9
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/lang/MOD/Main.java
@@ -0,0 +1,8 @@
+package lang.MOD;
+
+class MyClass { static int meth(lang.MOD.same.SomeType arg) { return arg.value; } }
+
+public class Main {
+    public static void main(String argv[]) {
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java
new file mode 100644
index 0000000..fd0dc7b
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.main/module-info.java
@@ -0,0 +1,5 @@
+module module.main {
+    requires module.readable.one;
+    requires module.readable.two;
+    exports lang.MOD;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java
new file mode 100644
index 0000000..f7b1468
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/lang/MOD/same/SomeType.java
@@ -0,0 +1,7 @@
+package lang.MOD.same;
+
+public class SomeType {
+    public static class NestedClass {
+    }
+    public static int value = 1;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java
new file mode 100644
index 0000000..c0dc959
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.one/module-info.java
@@ -0,0 +1,3 @@
+module module.readable.one {
+    exports lang.MOD.same to module.main;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java
new file mode 100644
index 0000000..33a9835
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/lang/MOD/same/SomeType.java
@@ -0,0 +1,4 @@
+package lang.MOD.same;
+
+public class SomeType {
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java
new file mode 100644
index 0000000..df9b457
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules2/module.readable.two/module-info.java
@@ -0,0 +1,2 @@
+module module.readable.two {
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java
new file mode 100644
index 0000000..b755208
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/module-info.java
@@ -0,0 +1,5 @@
+module module.main {
+    requires module.readable.one;
+    requires module.readable.two;
+    exports my.mod;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java
new file mode 100644
index 0000000..b60ff76
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.main/my/mod/Main.java
@@ -0,0 +1,10 @@
+package my.mod;
+
+import java.io.PrintStream;
+
+class MyClass { static int meth(my.mod.same.SomeType arg) { return arg.value; } }
+
+public class Main {
+    public static void main(String argv[]) {
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java
new file mode 100644
index 0000000..75fa2b7
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/module-info.java
@@ -0,0 +1,3 @@
+module module.readable.one {
+    exports my.mod.same to module.main;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java
new file mode 100644
index 0000000..8315b02
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.one/my/mod/same/SomeType.java
@@ -0,0 +1,7 @@
+package my.mod.same;
+
+public class SomeType {
+    public static class NestedClass {
+    }
+    public static int value = 1;
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java
new file mode 100644
index 0000000..df9b457
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/modules3/module.readable.two/module-info.java
@@ -0,0 +1,2 @@
+module module.readable.two {
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
index 9491959..413a63d 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
@@ -36,6 +36,7 @@
 		suite.addTestSuite(Java8ElementsTests.class);
 		suite.addTestSuite(Java9ElementsTests.class);
 		suite.addTestSuite(Java11ElementsTests.class);
+		suite.addTestSuite(Java12ElementsTests.class);
 		suite.addTestSuite(AnnotationProcessorTests.class);
 		return suite;
 	}
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
index 576b5f5..75bad93 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
@@ -122,11 +122,11 @@
 	}
 
 	public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor,
-			File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) {
+			File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) throws IOException {
 		compileInModuleMode(compiler, options, processor, targetFolder, listener, multiModule, true);
 	}
 	public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor,
-			File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule, boolean processBinariesAgain) {
+			File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule, boolean processBinariesAgain) throws IOException {
 		StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset());
 		Iterable<? extends File> location = manager.getLocation(StandardLocation.CLASS_PATH);
 		// create new list containing inputfile
@@ -145,7 +145,7 @@
 		copyOptions.add(_tmpBinFolderName);
 		copyOptions.add("-s");
 		copyOptions.add(_tmpGenFolderName);
-		addModuleProcessorPath(copyOptions, getSrcFolderName(), multiModule);
+		addModuleProcessorPath(copyOptions, targetFolder.getAbsolutePath(), multiModule);
 		copyOptions.add("-XprintRounds");
 		CompilationTask task = compiler.getTask(printWriter, manager, listener, copyOptions, null, units);
 		Boolean result = task.call();
@@ -154,6 +154,8 @@
 			String errorOutput = stringWriter.getBuffer().toString();
 			System.err.println("Compilation failed: " + errorOutput);
 	 		junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
+		} else {
+			junit.framework.TestCase.assertEquals("succeeded", System.getProperty(processor));
 		}
 		if (!processBinariesAgain) {
 			return;
@@ -164,6 +166,7 @@
 			System.clearProperty(processor);
 			copyOptions = new ArrayList<>();
 			copyOptions.addAll(options);
+			copyOptions.add("-Abinary");
 			copyOptions.add("-cp");
 			copyOptions.add(_jls8ProcessorJarPath + File.pathSeparator + _tmpGenFolderName);
 			copyOptions.add("--processor-module-path");
@@ -257,6 +260,7 @@
 			System.clearProperty(processor);
 			copyOptions = new ArrayList<>();
 			copyOptions.addAll(options);
+			copyOptions.add("-Abinary");
 			copyOptions.add("-cp");
 			copyOptions.add(_tmpBinFolderName + File.pathSeparator + _jls8ProcessorJarPath + File.pathSeparator + _tmpGenFolderName);
 			copyOptions.add("-processorpath");
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java
new file mode 100644
index 0000000..24f27a7
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java12ElementsTests.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.compiler.apt.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+
+import junit.framework.TestCase;
+
+public class Java12ElementsTests extends TestCase {
+	private static final String MODULE_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java12ElementProcessor";
+
+	public void testRootElements1Javac() throws IOException {
+		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+		internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements1", null, "modules2");
+	}
+	public void testRootElements1() throws IOException {
+		JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+		internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements1", null, "modules2");
+	}
+	public void testRootElements2Javac() throws IOException {
+		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+		internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements2", null, "modules3");
+	}
+	public void testRootElements2() throws IOException {
+		JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+		internalTestWithBinary(compiler, MODULE_PROC, "12", "testRootElements2", null, "modules3");
+	}
+
+	protected void internalTestWithBinary(JavaCompiler compiler, String processor, String compliance, String testMethod, String testClass, String resourceArea) throws IOException {
+		if (!canRunJava12()) {
+			return;
+		}
+		System.clearProperty(processor);
+		File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "mod_locations", resourceArea);
+		if (testClass == null || testClass.equals("")) {
+			BatchTestUtils.copyResources("mod_locations/" + resourceArea, targetFolder);
+		} else {
+			BatchTestUtils.copyResource("mod_locations/" + resourceArea + "/" + testClass, targetFolder);
+		}
+		
+
+		List<String> options = new ArrayList<String>();
+		options.add("-A" + processor);
+		options.add("-A" + testMethod);
+		options.add("-processor");
+		options.add(processor);
+		// Javac 1.8 doesn't (yet?) support the -1.8 option
+		if (compiler instanceof EclipseCompiler) {
+			options.add("-" + compliance);
+		} else {
+			options.add("-source");
+			options.add(compliance);
+		}
+		BatchTestUtils.compileInModuleMode(compiler, options, processor, targetFolder, null, true);
+		// If it succeeded, the processor will have set this property to "succeeded";
+		// if not, it will set it to an error value.
+		assertEquals("succeeded", System.getProperty(processor));
+	}
+	public boolean canRunJava12() {
+		try {
+			SourceVersion.valueOf("RELEASE_12");
+		} catch(IllegalArgumentException iae) {
+			return false;
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	@Override
+	protected void setUp() throws Exception {
+		super.setUp();
+		BatchTestUtils.init();
+	}
+
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	@Override
+	protected void tearDown() throws Exception {
+		super.tearDown();
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
index 185dfd8..00afab4 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *    IBM Corporation - initial API and implementation
  *    IBM Corporation - Fix for bug 328575
@@ -34,6 +38,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
@@ -235,6 +240,11 @@
 						throw new IllegalArgumentException("Top-level type binding could not be converted to element: " + typeBinding); //$NON-NLS-1$
 					}
 					elements.add(element);
+					ModuleBinding binding = typeBinding.module();
+					if (binding != null) {
+						Element m = _factory.newElement(binding);
+						elements.add(m);
+					}
 				}
 			}
 			_rootElements = elements;
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
index adda859..e6e473e 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2018 IBM Corporation and others.
+ * Copyright (c) 2018, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     
@@ -90,8 +94,18 @@
 		for (PackageBinding p : packs) {
 			if (p == null)
 				continue;
-			if (!p.hasCompilationUnit(true))
+			if (p instanceof SplitPackageBinding) {
+				// select from incarnations the unique package containing CUs, if any:
+				for (PackageBinding incarnation : ((SplitPackageBinding) p).incarnations) {
+					if (incarnation.enclosingModule == module && incarnation.hasCompilationUnit(true)) {
+						unique.add(getModulesPackageBinding(p));
+					}
+				}
 				continue;
+			} else {
+				if (!p.hasCompilationUnit(true))
+					continue;
+			}
 			unique.add(getModulesPackageBinding(p));
 		}
 		if (module.isUnnamed()) {
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
index b23b9f4..a34fbbf 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/util/JrtFileSystem.java
@@ -92,12 +92,8 @@
 			}
 
 			@Override
-			public FileVisitResult visitModule(Path mod) throws IOException {
-				String name = mod.getFileName().toString();
-				if (name.endsWith("/")) { //$NON-NLS-1$
-					name = name.substring(0, name.length() - 1);
-				}
-				JrtFileSystem.this.modulePathMap.put(name, mod);
+			public FileVisitResult visitModule(Path path, String name) throws IOException {
+				JrtFileSystem.this.modulePathMap.put(name, path);
 				return FileVisitResult.CONTINUE;
 			}
 		}, JRTUtil.NOTIFY_MODULES);
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
index 4b3d38a..b942161 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompiler.java
@@ -119,9 +119,10 @@
 			eclipseCompiler2.fileManager = this.getStandardFileManager(someDiagnosticListener, null, null);
 		}
 
-		eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
-		eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
-		eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
+		String latest = CompilerOptions.getLatestVersion();
+		eclipseCompiler2.options.put(CompilerOptions.OPTION_Compliance, latest);
+		eclipseCompiler2.options.put(CompilerOptions.OPTION_Source, latest);
+		eclipseCompiler2.options.put(CompilerOptions.OPTION_TargetPlatform, latest);
 
 		ArrayList<String> allOptions = new ArrayList<>();
 		if (options != null) {
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
index 05fcedb..cd80ce6 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseFileManager.java
@@ -1365,10 +1365,10 @@
 			// FIXME: same for module source path?
 			Map<String, String> options = new HashMap<>();
 			// FIXME: Find a way to get the options from the EclipseCompiler and pass it to the parser.
-			// FIXME: need to be the latest and not hardcoded value
-			options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
-			options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
-			options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
+			String latest = CompilerOptions.getLatestVersion();
+			options.put(CompilerOptions.OPTION_Compliance, latest);
+			options.put(CompilerOptions.OPTION_Source, latest);
+			options.put(CompilerOptions.OPTION_TargetPlatform, latest);
 			CompilerOptions compilerOptions = new CompilerOptions(options);
 			ProblemReporter problemReporter = 
 					new ProblemReporter(
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
index 57e6bd9..a140e15 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/JrtFileSystem.java
@@ -92,12 +92,8 @@
 			}
 
 			@Override
-			public FileVisitResult visitModule(Path mod) throws IOException {
-				String name = mod.getFileName().toString();
-				if (name.endsWith("/")) { //$NON-NLS-1$
-					name = name.substring(0, name.length() - 1);
-				}
-				JrtFileSystem.this.modulePathMap.put(name, mod);
+			public FileVisitResult visitModule(Path path, String name) throws IOException {
+				JrtFileSystem.this.modulePathMap.put(name, path);
 				return FileVisitResult.CONTINUE;
 			}
 		}, JRTUtil.NOTIFY_MODULES);
diff --git a/org.eclipse.jdt.core.internal.tools/.classpath b/org.eclipse.jdt.core.internal.tools/.classpath
index 01836c4..ea3258e 100644
--- a/org.eclipse.jdt.core.internal.tools/.classpath
+++ b/org.eclipse.jdt.core.internal.tools/.classpath
@@ -3,5 +3,6 @@
 	<classpathentry kind="src" path="src"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.jdt.core"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java
new file mode 100644
index 0000000..82ed5c2
--- /dev/null
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/disassembler/Disassembler.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.internal.tools.disassembler;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.jdt.core.ToolFactory;
+import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
+import org.eclipse.jdt.core.util.ClassFormatException;
+import org.eclipse.jdt.internal.compiler.util.Util;
+
+public class Disassembler {
+
+	public static void main(String[] args) throws IOException, ClassFormatException {
+		if (args.length != 1) {
+			System.out.println("Usage: Disassembler <path to a .class file>"); //$NON-NLS-1$
+			return;
+		}
+		ClassFileBytesDisassembler disassembler = ToolFactory.createDefaultClassFileBytesDisassembler();
+		byte[] classFileBytes = Util.getFileByteContent(new File(args[0]));
+		System.out.println(disassembler.disassemble(classFileBytes, System.getProperty("line.separator"), org.eclipse.jdt.core.util.ClassFileBytesDisassembler.SYSTEM)); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java
index b86075d..ca8ae6c 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/CodePointsBuilder.java
@@ -1,3 +1,20 @@
+/*******************************************************************************

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

+ *

+ * This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License 2.0

+ * which accompanies this distribution, and is available at

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

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ * This is an implementation of an early-draft specification developed under the Java

+ * Community Process (JCP) and is made available for testing and evaluation purposes

+ * only. The code is not compatible with any specification of the JCP.

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

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

 package org.eclipse.jdt.core.internal.tools.unicode;

 

 import java.text.DecimalFormat;

diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java
index e2fa003..599cdfa 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/Environment.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 public abstract class Environment {
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java
index ad189dd..904e32b 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/FileEncoder.java
@@ -1,3 +1,20 @@
+/*******************************************************************************

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

+ *

+ * This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License 2.0

+ * which accompanies this distribution, and is available at

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

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ * This is an implementation of an early-draft specification developed under the Java

+ * Community Process (JCP) and is made available for testing and evaluation purposes

+ * only. The code is not compatible with any specification of the JCP.

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

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

 package org.eclipse.jdt.core.internal.tools.unicode;

 

 import java.io.DataOutputStream;

diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java
index 8ed6e75..dc29b00 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierPartResources.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 import java.io.IOException;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java
index d60b983..6e070a6 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/GenerateIdentifierStartResources.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 import java.io.IOException;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java
index 1abf835..399d962 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/PartEnvironment.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 import java.util.HashSet;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java
index ec6b50a..bde56b3 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/StartEnvironment.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 import java.util.HashSet;
diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java
index 870d3eb..df2b2bb 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/TableBuilder.java
@@ -1,3 +1,20 @@
+/*******************************************************************************

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

+ *

+ * This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License 2.0

+ * which accompanies this distribution, and is available at

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

+ *

+ * SPDX-License-Identifier: EPL-2.0

+ *

+ * This is an implementation of an early-draft specification developed under the Java

+ * Community Process (JCP) and is made available for testing and evaluation purposes

+ * only. The code is not compatible with any specification of the JCP.

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

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

 package org.eclipse.jdt.core.internal.tools.unicode;

 

 import java.io.File;

diff --git a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java
index 4d26774..626272a 100644
--- a/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java
+++ b/org.eclipse.jdt.core.internal.tools/src/org/eclipse/jdt/core/internal/tools/unicode/UnicodeResourceGenerator.java
@@ -1,3 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
 package org.eclipse.jdt.core.internal.tools.unicode;
 
 import java.io.IOException;
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index dd39971..424ffdc 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -137,6 +137,37 @@
 			<tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,11</tycho.surefire.argLine>
 		</properties>
 	</profile>
+	<profile>
+		<id>test-on-javase-12</id>
+		<build>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-toolchains-plugin</artifactId>
+					<version>1.1</version>
+					<executions>
+						<execution>
+							<phase>validate</phase>
+							<goals>
+								<goal>toolchain</goal>
+							</goals>
+						</execution>
+					</executions>
+					<configuration>
+						<toolchains>
+							<jdk>
+								<id>JavaSE-12</id>
+							</jdk>
+						</toolchains>
+					</configuration>
+				</plugin>
+			</plugins>
+		</build>
+		<properties>
+			<!-- Overridden in https://ci.eclipse.org/jdt/job/eclipse.jdt.core-run.javac-12/configure  -->
+			<tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,12</tycho.surefire.argLine>
+		</properties>
+	</profile>
   </profiles>
 
 </project>
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
index 4fb966b..13dadab 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/ComplianceDiagnoseTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Jesper S Moller - realigned with bug 399695
@@ -27,7 +31,7 @@
 // Static initializer to specify tests subset using TESTS_* static variables
 // All specified tests which does not belong to the class are skipped...
 static {
-//	TESTS_NAMES = new String[] { "test0061" };
+//	TESTS_NAMES = new String[] { "testBug531714" };
 //	TESTS_NUMBERS = new int[] { 50 };
 //	TESTS_RANGE = new int[] { 21, 50 };
 }
@@ -1250,12 +1254,22 @@
 	};
 
 	String expected13ProblemLog =
-		"----------\n" +
-		"1. ERROR in X.java (at line 3)\n" +
-		"	for(Object o : switch){\n" +
-		"	           ^\n" +
-		"Syntax error, insert \"; ; ) Statement\" to complete BlockStatements\n" +
-		"----------\n";
+			"----------\n" + 
+			"1. ERROR in X.java (at line 3)\n" + 
+			"	for(Object o : switch){\n" + 
+			"	             ^\n" + 
+			"Syntax error on token \":\", delete this token\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 3)\n" + 
+			"	for(Object o : switch){\n" + 
+			"	             ^\n" + 
+			"Syntax error, insert \": Expression )\" to complete EnhancedForStatementHeader\n" +  // FIXME: bogus suggestion, this rule is compliance 1.5
+			"----------\n" + 
+			"3. ERROR in X.java (at line 3)\n" + 
+			"	for(Object o : switch){\n" + 
+			"	             ^\n" + 
+			"Syntax error, insert \"Statement\" to complete BlockStatements\n" + 
+			"----------\n";
 	String expected14ProblemLog =
 		expected13ProblemLog;
 
@@ -3510,4 +3524,107 @@
 		"Type arguments are not allowed here\n" + 
 		"----------\n");
 }
+public void testBug531714_001() {
+	if (this.complianceLevel >= ClassFileConstants.JDK12)
+		return;
+	String[] testFiles = 			new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	static int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> i * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default -> 3;\n" +
+			"		};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.print(twice(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 3)\n" + 
+			"	int tw = switch (i) {\n" + 
+			"			case 0 -> i * 0;\n" + 
+			"			case 1 -> 2;\n" + 
+			"			default -> 3;\n" + 
+			"		};\n" + 
+			"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+			"The preview feature Switch Expressions is only available with source level 12 and above\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 4)\n" + 
+			"	case 0 -> i * 0;\n" + 
+			"	^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 5)\n" + 
+			"	case 1 -> 2;\n" + 
+			"	^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n" + 
+			"4. ERROR in X.java (at line 6)\n" + 
+			"	default -> 3;\n" + 
+			"	^^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n";
+
+	runComplianceParserTest(
+		testFiles,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog
+	);
+}
+public void testBug531714_002() {
+	if (this.complianceLevel >= ClassFileConstants.JDK12)
+		return;
+	String[] testFiles = new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	static int twice(int i) {\n" +
+			"		switch (i) {\n" +
+			"			case 0 -> i * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default -> 3;\n" +
+			"		}\n" +
+			"		return 0;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.print(twice(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 4)\n" + 
+			"	case 0 -> i * 0;\n" + 
+			"	^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 5)\n" + 
+			"	case 1 -> 2;\n" + 
+			"	^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 6)\n" + 
+			"	default -> 3;\n" + 
+			"	^^^^^^^\n" + 
+			"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+			"----------\n";
+
+	runComplianceParserTest(
+		testFiles,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog,
+		expectedProblemLog
+	);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java
index a12ef9f..2c24809 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/JavadocCompletionParserTest.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -183,11 +187,16 @@
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE
 		};
-	} else if(this.complianceLevel > ClassFileConstants.JDK1_4) {
+	} else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) {
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
 			TAG_CODE, TAG_LITERAL
 		};
+	} else if(this.complianceLevel >= ClassFileConstants.JDK12) {
+		additionalTags = new char[][] {
+			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
+			TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY
+		};
 	}
 	allTagsFinal = this.complianceLevel > ClassFileConstants.JDK1_8 ? allTagsJava9Plus  : allTags;
 	if (additionalTags != null) {
@@ -279,11 +288,16 @@
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE
 		};
-	} else if (this.complianceLevel > ClassFileConstants.JDK1_4) {
+	} else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) {
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
 			TAG_CODE, TAG_LITERAL
 		};
+	} else if(this.complianceLevel >= ClassFileConstants.JDK12) {
+		additionalTags = new char[][] {
+			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
+			TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY
+		};
 	}
 	if (additionalTags != null) {
 		int length = allTags.length;
@@ -422,7 +436,9 @@
 		" */\n" +
 		"public class Test {}\n";
 	verifyCompletionInJavadoc(source, "@s");
-	verifyCompletionOnJavadocTag("s".toCharArray(), new char[][] { TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD }, false);
+	char[][] expectedTags = {TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD};
+	char[][] expectedTags12Plus = {TAG_SEE, TAG_SINCE, TAG_SERIAL, TAG_SERIAL_DATA, TAG_SERIAL_FIELD,TAG_SYSTEM_PROPERTY};		
+	verifyCompletionOnJavadocTag("s".toCharArray(),this.complianceLevel >= ClassFileConstants.JDK12 ? expectedTags12Plus : expectedTags, false);
 	CompletionOnJavadocTag completionTag = (CompletionOnJavadocTag) this.javadoc.getCompletionNode();
 	assertEquals("Invalid tag start position", 24, completionTag.tagSourceStart);
 	assertEquals("Invalid tag end position", 28, completionTag.tagSourceEnd+1);
@@ -500,12 +516,16 @@
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE
 		};
-	}
-	else if (this.complianceLevel > ClassFileConstants.JDK1_4) {
+	}else if (this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) {
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
 			TAG_CODE, TAG_LITERAL
 		};
+	}else if (this.complianceLevel >= ClassFileConstants.JDK12) {
+		additionalTags = new char[][] {
+			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
+			TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY
+		};
 	}
 	if (additionalTags != null) {
 		int length = allTags.length;
@@ -575,12 +595,18 @@
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE
 		};
 	}
-	else if (this.complianceLevel > ClassFileConstants.JDK1_4) {
+	else if(this.complianceLevel > ClassFileConstants.JDK1_4 && this.complianceLevel < ClassFileConstants.JDK12) {
 		additionalTags = new char[][] {
 			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
 			TAG_CODE, TAG_LITERAL
 		};
+	} else if(this.complianceLevel >= ClassFileConstants.JDK12) {
+		additionalTags = new char[][] {
+			TAG_INHERITDOC, TAG_LINKPLAIN, TAG_VALUE,
+			TAG_CODE, TAG_LITERAL, TAG_SYSTEM_PROPERTY
+		};
 	}
+
 	if (additionalTags != null) {
 		int length = allTags.length;
 		int add = additionalTags.length;
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java
new file mode 100644
index 0000000..d3f097f
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/SelectionParserTest12.java
@@ -0,0 +1,1074 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.parser;
+
+import org.eclipse.jdt.core.JavaModelException;
+
+import junit.framework.Test;
+
+public class SelectionParserTest12 extends AbstractSelectionTest {
+static {
+//		TESTS_NUMBERS = new int[] { 1 };
+//		TESTS_NAMES = new String[] { "test005" };
+}
+public static Test suite() {
+	return buildMinimalComplianceTestSuite(SelectionParserTest12.class, F_12);
+}
+
+public SelectionParserTest12(String testName) {
+	super(testName);
+}
+/*
+ * Multi constant case statement with ':', selection node is the string constant
+ */
+public void test001() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "ONE";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "ONE";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  static final String ONE;\n" + 
+					"  static final String TWO;\n" + 
+					"  static final String THREE;\n" + 
+					"  <clinit>() {\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(String num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:ONE> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "ONE";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with ':', selection node is the first enum constant
+ */
+public void test002() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "ONE";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "ONE";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  enum Num {\n" + 
+					"    ONE(),\n" + 
+					"    TWO(),\n" + 
+					"    THREE(),\n" + 
+					"    <clinit>() {\n" + 
+					"    }\n" + 
+					"    Num() {\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(Num num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:ONE> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "ONE";
+	String testName = "X.java";
+
+	int selectionStart = string.indexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with ':', selection node is the second string constant
+ */
+public void test003() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "TWO";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "TWO";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  static final String ONE;\n" + 
+					"  static final String TWO;\n" + 
+					"  static final String THREE;\n" + 
+					"  <clinit>() {\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(String num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:TWO> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "TWO";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with ':', selection node is the second enum constant
+ */
+public void test004() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "TWO";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "TWO";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  enum Num {\n" + 
+					"    ONE(),\n" + 
+					"    TWO(),\n" + 
+					"    THREE(),\n" + 
+					"    <clinit>() {\n" + 
+					"    }\n" + 
+					"    Num() {\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(Num num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:TWO> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "TWO";
+	String testName = "X.java";
+
+	int selectionStart = string.indexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection node is the string constant
+ */
+public void test005() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"    }" +
+	"  }\n" +
+	"}";
+	/*
+	 * Note: The completion parser ignores the -> that follows and we end up creating
+	 * the CaseStatement without maring it as an Expression, hence the ':' instead of the '->'
+	 */
+	String selection = "ONE";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+	String selectionIdentifier = "ONE";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  static final String ONE;\n" + 
+					"  static final String TWO;\n" + 
+					"  static final String THREE;\n" + 
+					"  <clinit>() {\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(String num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:ONE> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "ONE";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection node is the first enum constant
+ */
+public void test006() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break; // illegal, but should be ignored and shouldn't matter\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "ONE";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "ONE";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  enum Num {\n" + 
+					"    ONE(),\n" + 
+					"    TWO(),\n" + 
+					"    THREE(),\n" + 
+					"    <clinit>() {\n" + 
+					"    }\n" + 
+					"    Num() {\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(Num num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:ONE> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "ONE";
+	String testName = "X.java";
+
+	int selectionStart = string.indexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection node is the second string constant
+ */
+public void test007() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "TWO";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "TWO";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  static final String ONE;\n" + 
+					"  static final String TWO;\n" + 
+					"  static final String THREE;\n" + 
+					"  <clinit>() {\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(String num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:TWO> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "TWO";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = string.lastIndexOf(selection) + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection node is the second enum constant
+ */
+public void test008() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "TWO";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "TWO";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+					"  enum Num {\n" + 
+					"    ONE(),\n" + 
+					"    TWO(),\n" + 
+					"    THREE(),\n" + 
+					"    <clinit>() {\n" + 
+					"    }\n" + 
+					"    Num() {\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"  public X() {\n" + 
+					"  }\n" + 
+					"  public static void foo(Num num) {\n" + 
+					"    {\n" + 
+					"      switch (num) {\n" + 
+					"      case <SelectOnName:TWO> :\n" + 
+					"      }\n" + 
+					"    }\n" + 
+					"  }\n" + 
+					"}\n";
+	String expectedReplacedSource = "TWO";
+	String testName = "X.java";
+
+	int selectionStart = string.indexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a reference in the case block
+ * which same as the switch's expression
+ */
+public void test009() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num_);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  enum Num {\n" + 
+			"    ONE(),\n" + 
+			"    TWO(),\n" + 
+			"    THREE(),\n" + 
+			"    <clinit>() {\n" + 
+			"    }\n" + 
+			"    Num() {\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(Num num_) {\n" + 
+			"    {\n" + 
+			"      <SelectOnName:num_>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a reference in the case block
+ * which is referencing a local variable defined in the case block
+ */
+public void test010() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE -> {\n" +
+	"		 int i_j = 0;" +
+	"		 System.out.println(i_j);\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "i_j";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "i_j";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  enum Num {\n" + 
+			"    ONE(),\n" + 
+			"    TWO(),\n" + 
+			"    THREE(),\n" + 
+			"    <clinit>() {\n" + 
+			"    }\n" + 
+			"    Num() {\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(Num num_) {\n" + 
+			"    {\n" + 
+			"      {\n" + 
+			"        int i_j;\n" + 
+			"        <SelectOnName:i_j>;\n" + 
+			"      }\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "i_j";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type enum in switch expression
+ */
+public void test011() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE -> {\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  enum Num {\n" + 
+			"    ONE(),\n" + 
+			"    TWO(),\n" + 
+			"    THREE(),\n" + 
+			"    <clinit>() {\n" + 
+			"    }\n" + 
+			"    Num() {\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(Num num_) {\n" + 
+			"    <SelectOnName:num_>;\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test012() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 switch (num_ + 1) {\n" +
+	"	   case 1, 2, 3 -> {\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(int num_) {\n" + 
+			"    <SelectOnName:num_>;\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test013() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> (num_ + 1);\n" +
+	"      default -> 0;\n" + 
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(int num_) {\n" + 
+			"    int i;\n" + 
+			"    {\n" + 
+			"      <SelectOnName:num_>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test014() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> 0;\n" +
+	"      default -> (num_ + 1);\n" + 
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(int num_) {\n" + 
+			"    int i;\n" + 
+			"    {\n" + 
+			"      <SelectOnName:num_>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test015() throws JavaModelException {
+	String string =  "public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> 0;\n" +
+	"      default -> (num_ + 1);\n" + 
+	"    }" +
+	"  }\n" +
+	"}";
+
+	String selection = "num_";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "num_";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public static void foo(int num_) {\n" + 
+			"    int i;\n" + 
+			"    {\n" + 
+			"      <SelectOnName:num_>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "num_";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test016() throws JavaModelException {
+	String string =  "public class X {\n" + 
+			"	public void bar(int s) {\n" + 
+			"		int i_j = switch (s) {\n" + 
+			"			case 1, 2, 3 -> (s+1);\n" +
+			"			default -> i_j;\n" + 
+			"		};\n" + 
+			"	}\n" + 
+			"}\n";
+
+	String selection = "i_j";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "i_j";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public void bar(int s) {\n" + 
+			"    int i_j;\n" + 
+			"    {\n" + 
+			"      <SelectOnName:i_j>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "i_j";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test017() throws JavaModelException {
+	String string =  "public class X {\n" + 
+			"	public void bar(int s) {\n" + 
+			"		int i_j = switch (s) {\n" + 
+			"			case 1, 2, 3 -> (s+1);\n" +
+			"			default -> (1+i_j);\n" + 
+			"		};\n" + 
+			"	}\n" + 
+			"}\n";
+
+	String selection = "i_j";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "i_j";
+	String expectedUnitDisplayString =
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  public void bar(int s) {\n" + 
+			"    int i_j;\n" + 
+			"    {\n" + 
+			"      <SelectOnName:i_j>;\n" + 
+			"    }\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "i_j";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test018() throws JavaModelException {
+	String string =  "import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			case 1 -> this::n_1; \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}";
+
+	String selection = "n_1";
+	String selectKey = "<SelectionOnReferenceExpressionName:this::";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "n_1";
+	String expectedUnitDisplayString =
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {\n" + 
+			"}\n" + 
+			"interface IN1 extends IN0 {\n" + 
+			"}\n" + 
+			"interface IN2 extends IN0 {\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  IN1 n_1() {\n" + 
+			"  }\n" + 
+			"  IN2 n_2() {\n" + 
+			"  }\n" + 
+			"  <M>void m(Supplier<M> m2) {\n" + 
+			"  }\n" + 
+			"  void testSw(int i) {\n" + 
+			"    m(switch (i) {\n" + 
+			"case 1 ->\n" + 
+			" <SelectionOnReferenceExpressionName:this::n_1>;\n" + 
+			"default ->\n" + 
+			" this::n_2;\n" + 
+			"});\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "this::n_1";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test019() throws JavaModelException {
+	String string =  "import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			case 2 -> () -> n_1(); \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}";
+
+	String selection = "n_1";
+	String selectKey = "<SelectOnMessageSend:";
+	String expectedSelection = selectKey + selection + "()>";
+
+	String selectionIdentifier = "n_1";
+	String expectedUnitDisplayString =
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {\n" + 
+			"}\n" + 
+			"interface IN1 extends IN0 {\n" + 
+			"}\n" + 
+			"interface IN2 extends IN0 {\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  IN1 n_1() {\n" + 
+			"  }\n" + 
+			"  IN2 n_2() {\n" + 
+			"  }\n" + 
+			"  <M>void m(Supplier<M> m2) {\n" + 
+			"  }\n" + 
+			"  void testSw(int i) {\n" + 
+			"    m(switch (i) {\n" + 
+			"case 2 ->\n" + 
+			" () -> <SelectOnMessageSend:n_1()>;\n" + 
+			"default ->\n" + 
+			" this::n_2;\n" + 
+			"});\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "n_1()";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test020() throws JavaModelException {
+	String string =  "import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}";
+
+	String selection = "n_2";
+	String selectKey = "<SelectionOnReferenceExpressionName:this::";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "n_2";
+	String expectedUnitDisplayString =
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {\n" + 
+			"}\n" + 
+			"interface IN1 extends IN0 {\n" + 
+			"}\n" + 
+			"interface IN2 extends IN0 {\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  IN1 n_1() {\n" + 
+			"  }\n" + 
+			"  IN2 n_2() {\n" + 
+			"  }\n" + 
+			"  <M>void m(Supplier<M> m2) {\n" + 
+			"  }\n" + 
+			"  void testSw(int i) {\n" + 
+			"    m(switch (i) {\n" + 
+			"default ->\n" + 
+			" <SelectionOnReferenceExpressionName:this::n_2>;\n" + 
+			"});\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "this::n_2";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test021() throws JavaModelException {
+	String string =  "import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1(int ijk) { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int ijk) { \n" + 
+			"		m(switch(ijk) { \n" + 
+			"			default -> () -> n_1(ijk); }); \n" + 
+			"	}\n" + 
+			"}";
+
+	String selection = "n_1";
+	String selectKey = "<SelectOnMessageSend:";
+	String expectedSelection = selectKey + selection + "(ijk)>";
+
+	String selectionIdentifier = "n_1";
+	String expectedUnitDisplayString =
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {\n" + 
+			"}\n" + 
+			"interface IN1 extends IN0 {\n" + 
+			"}\n" + 
+			"interface IN2 extends IN0 {\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  IN1 n_1(int ijk) {\n" + 
+			"  }\n" + 
+			"  IN2 n_2() {\n" + 
+			"  }\n" + 
+			"  <M>void m(Supplier<M> m2) {\n" + 
+			"  }\n" + 
+			"  void testSw(int ijk) {\n" + 
+			"    m(switch (ijk) {\n" + 
+			"default ->\n" + 
+			" () -> <SelectOnMessageSend:n_1(ijk)>;\n" + 
+			"});\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "n_1(ijk)";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+public void test022() throws JavaModelException {
+	String string =  "import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1(int ijk) { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int ijk) { \n" + 
+			"		m(switch(ijk) { \n" + 
+			"			default -> () -> n_1(ijk); }); \n" + 
+			"	}\n" + 
+			"}";
+
+	String selection = "ijk";
+	String selectKey = "<SelectOnName:";
+	String expectedSelection = selectKey + selection + ">";
+
+	String selectionIdentifier = "ijk";
+	String expectedUnitDisplayString =
+			"import org.eclipse.jdt.annotation.*;\n" + 
+			"import java.util.function.*;\n" + 
+			"interface IN0 {\n" + 
+			"}\n" + 
+			"interface IN1 extends IN0 {\n" + 
+			"}\n" + 
+			"interface IN2 extends IN0 {\n" + 
+			"}\n" + 
+			"public class X {\n" + 
+			"  public X() {\n" + 
+			"  }\n" + 
+			"  IN1 n_1(int ijk) {\n" + 
+			"  }\n" + 
+			"  IN2 n_2() {\n" + 
+			"  }\n" + 
+			"  <M>void m(Supplier<M> m2) {\n" + 
+			"  }\n" + 
+			"  void testSw(int ijk) {\n" + 
+			"    m(switch (ijk) {\n" + 
+			"default ->\n" + 
+			" () -> n_1(<SelectOnName:ijk>);\n" + 
+			"});\n" + 
+			"  }\n" + 
+			"}\n";
+	String expectedReplacedSource = "ijk";
+	String testName = "X.java";
+
+	int selectionStart = string.lastIndexOf(selection);
+	int selectionEnd = selectionStart + selection.length() - 1;
+
+	checkMethodParse(string.toCharArray(), selectionStart, selectionEnd, expectedSelection, expectedUnitDisplayString,
+			selectionIdentifier, expectedReplacedSource, testName);
+}
+}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java
index 65287ab..8699a67 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/TestAll.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -153,6 +153,7 @@
 		tests_10.add(CompletionParserTest18.class);
 		tests_10.add(SelectionParserTest18.class);
 		tests_10.add(SelectionParserTest9.class);
+		tests_10.add(SelectionParserTest10.class);
 		tests_10.add(ModuleDeclarationSyntaxTest.class);
 		tests_10.add(JEP286ReservedWordTest.class);
 		// Reset forgotten subsets tests
@@ -173,6 +174,7 @@
 		tests_11.add(CompletionParserTest18.class);
 		tests_11.add(SelectionParserTest18.class);
 		tests_11.add(SelectionParserTest9.class);
+		tests_11.add(SelectionParserTest10.class);
 		tests_11.add(ModuleDeclarationSyntaxTest.class);
 		tests_11.add(JEP286ReservedWordTest.class);
 		// Reset forgotten subsets tests
@@ -183,6 +185,28 @@
 		TestCase.RUN_ONLY_ID = null;
 		all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11), tests_11));
 	}
+	if ((possibleComplianceLevels & AbstractCompilerTest.F_12) != 0) {
+		ArrayList tests_12 = (ArrayList)testClasses.clone();
+		tests_12.addAll(TEST_CLASSES_1_5);
+		tests_12.add(ParserTest1_7.class);
+		tests_12.add(LambdaExpressionSyntaxTest.class);
+		tests_12.add(ReferenceExpressionSyntaxTest.class);
+		tests_12.add(TypeAnnotationSyntaxTest.class);
+		tests_12.add(CompletionParserTest18.class);
+		tests_12.add(SelectionParserTest18.class);
+		tests_12.add(SelectionParserTest9.class);
+		tests_12.add(SelectionParserTest10.class);
+		tests_12.add(SelectionParserTest12.class);
+		tests_12.add(ModuleDeclarationSyntaxTest.class);
+		tests_12.add(JEP286ReservedWordTest.class);
+		// Reset forgotten subsets tests
+		TestCase.TESTS_PREFIX = null;
+		TestCase.TESTS_NAMES = null;
+		TestCase.TESTS_NUMBERS= null;
+		TestCase.TESTS_RANGE = null;
+		TestCase.RUN_ONLY_ID = null;
+		all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12), tests_12));
+	}
 	return all;
 }
 public static Test suite() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
index c0e95a3..b6dcf42 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractComparableTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
@@ -110,6 +114,29 @@
 	}
 	
 	protected String intersection(String... types) {
+		// From JDK 12, Comparable gets two new super interfaces, namely Constable and ConstantDesc.
+		// The idea is to append Comparable with &Constable&ConstantDesc automatically.
+		if (isJRE12Plus) {
+			int index = -1;
+			for(int i = 0; i < types.length; i++) {
+				if (types[i].startsWith("Comparable") && !types[i].endsWith("ConstantDesc")) {
+					if ((types.length <= i+1) || !types[i+1].startsWith("CharSequence")) {
+						index = i;
+						break;
+					}
+				}
+			}
+			if (index >= 0) {
+				index++;
+				String[] temp = new String[types.length + 2];
+				System.arraycopy(types, 0, temp, 0, index);
+				temp[index] = "Constable";
+				temp[index+1] = "ConstantDesc";
+				if (index < types.length)
+ 					System.arraycopy(types, index, temp, index+2, types.length - index);
+				types = temp;
+			}
+		}
 		if (this.complianceLevel >= ClassFileConstants.JDK1_8)
 			return String.join(" & ", types);
 		return String.join("&", types);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
index bdbc45a..a608343 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java
@@ -6,6 +6,10 @@
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -298,6 +302,8 @@
 			return JavaCore.VERSION_10;
 		} else if(rawVersion.startsWith("11")) {
 			return JavaCore.VERSION_11;
+		} else if(rawVersion.startsWith("12")) {
+			return JavaCore.VERSION_12;
 		} else {
 			throw new RuntimeException("unknown javac version: " + rawVersion);
 		}
@@ -408,6 +414,17 @@
 				return 0200;
 			}
 		}
+		if (version == JavaCore.VERSION_12) {
+			if ("12".equals(rawVersion)) {
+				return 0000;
+			}
+			if ("12.0.1".equals(rawVersion)) {
+				return 0100;
+			}
+			if ("12.0.2".equals(rawVersion)) {
+				return 0200;
+			}
+		}
 		throw new RuntimeException("unknown raw javac version: " + rawVersion);
 	}
 	// returns 0L if everything went fine; else the lower word contains the
@@ -1719,6 +1736,9 @@
 			JavacTestOptions.DEFAULT /* default javac test options */);
 	}
 	protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) {
+		runConformTest(testFiles, expectedOutput, customOptions, null);
+	}
+	protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions, String[] vmArguments) {
 		runTest(
 			// test directory preparation
 			true /* flush output directory */,
@@ -1733,7 +1753,7 @@
 			null /* do not check compiler log */,
 			// runtime options
 			false /* do not force execution */,
-			null /* no vm arguments */,
+			vmArguments /* no vm arguments */,
 			// runtime results
 			expectedOutput /* expected output string */,
 			null /* do not check error string */,
@@ -2553,10 +2573,19 @@
 						JavacTestOptions.DEFAULT /* javac test options */);
 		}
 	protected void runNegativeTest(
+			String[] testFiles,
+			String expectedCompilerLog,
+			String[] classLibraries,
+			boolean shouldFlushOutputDirectory,
+			Map customOptions) {
+		runNegativeTest(testFiles, expectedCompilerLog, classLibraries, shouldFlushOutputDirectory, null, customOptions);
+	}
+	protected void runNegativeTest(
 		String[] testFiles,
 		String expectedCompilerLog,
 		String[] classLibraries,
 		boolean shouldFlushOutputDirectory,
+		String[] vmArguments,
 		Map customOptions) {
 		runTest(
 	 		// test directory preparation
@@ -2577,7 +2606,7 @@
 			expectedCompilerLog /* expected compiler log */,
 			// runtime options
 			false /* do not force execution */,
-			null /* no vm arguments */,
+			vmArguments /* no vm arguments */,
 			// runtime results
 			null /* do not check output string */,
 			null /* do not check error string */,
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 398e5ac..1ccbeb2 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -1020,7 +1020,6 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.generateClassFiles\" value=\"enabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.maxProblemPerUnit\" value=\"100\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.APILeak\" value=\"warning\"/>\n" + 
-			"		<option key=\"org.eclipse.jdt.core.compiler.problem.EnablePreviews\" value=\"disabled\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.annotationSuperInterface\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.assertIdentifier\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.autoboxing\" value=\"ignore\"/>\n" + 
@@ -1032,6 +1031,7 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.discouragedReference\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.emptyStatement\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures\" value=\"disabled\"/>\n" +
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.enumIdentifier\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.fallthroughCase\" value=\"ignore\"/>\n" + 
@@ -1091,6 +1091,7 @@
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.redundantSuperinterface\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic\" value=\"ignore\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic\" value=\"ignore\"/>\n" + 
+			"		<option key=\"org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.specialParameterHidingField\" value=\"disabled\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\n" + 
 			"		<option key=\"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors\" value=\"disabled\"/>\n" + 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index 4d94ead..d40a565 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2018 IBM Corporation and others.
+ * Copyright (c) 2006, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Benjamin Muskalla - Contribution for bug 239066
@@ -76,270 +80,240 @@
 @SuppressWarnings({ "unchecked", "rawtypes" })
 public class CompilerInvocationTests extends AbstractRegressionTest {
 
-public CompilerInvocationTests(String name) {
-    super(name);
-}
+	public CompilerInvocationTests(String name) {
+		super(name);
+	}
 
 	// Static initializer to specify tests subset using TESTS_* static variables
-  	// All specified tests which does not belong to the class are skipped...
-  	// Only the highest compliance level is run; add the VM argument
-  	// -Dcompliance=1.4 (for example) to lower it if needed
-  	static {
-//    	TESTS_NAMES = new String[] { "test003_task_tags_options" };
+	// All specified tests which does not belong to the class are skipped...
+	// Only the highest compliance level is run; add the VM argument
+	// -Dcompliance=1.4 (for example) to lower it if needed
+	static {
+//    	TESTS_NAMES = new String[] { "test011_problem_categories" };
 //    	TESTS_NUMBERS = new int[] { 1 };
 //    	TESTS_RANGE = new int[] { 1, -1 };
 //  	TESTS_RANGE = new int[] { 1, 2049 };
 //  	TESTS_RANGE = new int[] { 449, 451 };
 //    	TESTS_RANGE = new int[] { 900, 999 };
-  	}
+	}
 
-public static Test suite() {
-    return buildAllCompliancesTestSuite(testClass());
-}
+	public static Test suite() {
+		return buildAllCompliancesTestSuite(testClass());
+	}
 
-public static Class testClass() {
-    return CompilerInvocationTests.class;
-}
+	public static Class testClass() {
+		return CompilerInvocationTests.class;
+	}
 
 // irritant vs warning token - check To/From symmetry
-public void test001_irritant_warning_token() {
-	Map matcher = new HashMap();
-	for (int group = 0; group < IrritantSet.GROUP_MAX; group++) {
-		for (int i = 0; i < 29; i++) {
-			int irritant = (group << IrritantSet.GROUP_SHIFT) + (1 << i);
-			String token = CompilerOptions.warningTokenFromIrritant(irritant);
-			if (token != null) {
-				matcher.put(token, token);
-				assertTrue(CompilerOptions.warningTokenToIrritants(token) != null);
-			}
-		}
-	}
-	// Add one for "preview", which doesn't have any irritant at the moment
-	matcher.put("preview", "preview");
-	String [] allTokens = CompilerOptions.warningTokens;
-	int length = allTokens.length;
-	matcher.put("all", "all"); // all gets undetected in the From/To loop
-	assertEquals(allTokens.length, matcher.size());
-	for (int i = 0; i < length; i++) {
-		Object object = matcher.get(allTokens[i]);
-		assertNotNull(object);
-	}
-}
-
-// problem categories - check that none is left unspecified
-// see also discussion in https://bugs.eclipse.org/bugs/show_bug.cgi?id=208383
-public void test002_problem_categories() {
-	try {
-		Class iProblemClass;
-		Field[] fields = (iProblemClass = IProblem.class).getFields();
-		for (int i = 0, length = fields.length; i < length; i++) {
-			Field field = fields[i];
-			if (field.getType() == Integer.TYPE) {
-				int problemId = field.getInt(iProblemClass), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
-				if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask
-						&& ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId)
-							== CategorizedProblem.CAT_UNSPECIFIED) {
-					 fail("unspecified category for problem " + field.getName());
+	public void test001_irritant_warning_token() {
+		Map matcher = new HashMap();
+		for (int group = 0; group < IrritantSet.GROUP_MAX; group++) {
+			for (int i = 0; i < 29; i++) {
+				int irritant = (group << IrritantSet.GROUP_SHIFT) + (1 << i);
+				String token = CompilerOptions.warningTokenFromIrritant(irritant);
+				if (token != null) {
+					matcher.put(token, token);
+					assertTrue(CompilerOptions.warningTokenToIrritants(token) != null);
 				}
 			}
 		}
+		// Add one for "preview", which doesn't have any irritant at the moment
+		matcher.put("preview", "preview");
+		String[] allTokens = CompilerOptions.warningTokens;
+		int length = allTokens.length;
+		matcher.put("all", "all"); // all gets undetected in the From/To loop
+		assertEquals(allTokens.length, matcher.size());
+		for (int i = 0; i < length; i++) {
+			Object object = matcher.get(allTokens[i]);
+			assertNotNull(object);
+		}
 	}
-	catch (IllegalAccessException e) {
-		fail("could not access members");
+
+// problem categories - check that none is left unspecified
+// see also discussion in https://bugs.eclipse.org/bugs/show_bug.cgi?id=208383
+	public void test002_problem_categories() {
+		try {
+			Class iProblemClass;
+			Field[] fields = (iProblemClass = IProblem.class).getFields();
+			for (int i = 0, length = fields.length; i < length; i++) {
+				Field field = fields[i];
+				if (field.getType() == Integer.TYPE) {
+					int problemId = field.getInt(iProblemClass),
+							maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
+					if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask
+							&& ProblemReporter.getProblemCategory(ProblemSeverities.Error,
+									problemId) == CategorizedProblem.CAT_UNSPECIFIED) {
+						fail("unspecified category for problem " + field.getName());
+					}
+				}
+			}
+		} catch (IllegalAccessException e) {
+			fail("could not access members");
+		}
 	}
-}
-class TasksReader implements ICompilerRequestor {
-	CompilationResult result;
-	public void acceptResult(CompilationResult compilationResult) {
-		this.result = compilationResult;
+
+	class TasksReader implements ICompilerRequestor {
+		CompilationResult result;
+
+		public void acceptResult(CompilationResult compilationResult) {
+			this.result = compilationResult;
+		}
 	}
-}
-static String taskTagsAsCutAndPaste(CategorizedProblem tasks[]) {
-	StringBuffer result = new StringBuffer();
-	String arguments[];
-	for (int i = 0; i < tasks.length - 1; i++) {
-		arguments = tasks[i].getArguments();
+
+	static String taskTagsAsCutAndPaste(CategorizedProblem tasks[]) {
+		StringBuffer result = new StringBuffer();
+		String arguments[];
+		for (int i = 0; i < tasks.length - 1; i++) {
+			arguments = tasks[i].getArguments();
+			System.out.print("\t\t\"[");
+			System.out.print(arguments[0]);
+			System.out.print(',');
+			System.out.print(arguments[1]);
+			System.out.print(',');
+			System.out.print(arguments[2]);
+			System.out.println("]\\n\" +");
+		}
+		arguments = tasks[tasks.length - 1].getArguments();
 		System.out.print("\t\t\"[");
 		System.out.print(arguments[0]);
 		System.out.print(',');
 		System.out.print(arguments[1]);
 		System.out.print(',');
 		System.out.print(arguments[2]);
-		System.out.println("]\\n\" +");
+		System.out.println("]\\n\"");
+		return result.toString();
 	}
-	arguments = tasks[tasks.length - 1].getArguments();
-	System.out.print("\t\t\"[");
-	System.out.print(arguments[0]);
-	System.out.print(',');
-	System.out.print(arguments[1]);
-	System.out.print(',');
-	System.out.print(arguments[2]);
-	System.out.println("]\\n\"");
-	return result.toString();
-}
-static String taskTagsAsStrings(CategorizedProblem tasks[]) {
-	StringBuffer result = new StringBuffer();
-	String arguments[];
-	for (int i = 0; i < tasks.length; i++) {
-		arguments = tasks[i].getArguments();
-		result.append('[');
-		result.append(arguments[0]);
-		result.append(',');
-		result.append(arguments[1]);
-		result.append(',');
-		result.append(arguments[2]);
-		result.append(']');
-		result.append("\n");
+
+	static String taskTagsAsStrings(CategorizedProblem tasks[]) {
+		StringBuffer result = new StringBuffer();
+		String arguments[];
+		for (int i = 0; i < tasks.length; i++) {
+			arguments = tasks[i].getArguments();
+			result.append('[');
+			result.append(arguments[0]);
+			result.append(',');
+			result.append(arguments[1]);
+			result.append(',');
+			result.append(arguments[2]);
+			result.append(']');
+			result.append("\n");
+		}
+		return result.toString();
 	}
-	return result.toString();
-}
-public void runTaskTagsOptionsTest(
-		String[] testFiles,
-		Map customOptions,
-		String expectedTags) {
-	TasksReader reader = new TasksReader();
-	Map options = JavaCore.getDefaultOptions();
-	if (customOptions != null) {
-		options.putAll(customOptions);
+
+	public void runTaskTagsOptionsTest(String[] testFiles, Map customOptions, String expectedTags) {
+		TasksReader reader = new TasksReader();
+		Map options = JavaCore.getDefaultOptions();
+		if (customOptions != null) {
+			options.putAll(customOptions);
+		}
+		this.runConformTest(testFiles, "", null /* no extra class libraries */, true /* flush output directory */,
+				null, /* no VM args */
+				options, reader, true /* skip javac */);
+		String tags = taskTagsAsStrings(reader.result.tasks);
+		if (!tags.equals(expectedTags)) {
+			System.out.println(getClass().getName() + '#' + getName());
+			System.out.println("Effective results:");
+			System.out.println(tags);
+			System.out.println("Cut and paste:");
+			taskTagsAsCutAndPaste(reader.result.tasks);
+			assertEquals(expectedTags, tags);
+		}
 	}
-	this.runConformTest(
-		testFiles,
-		"",
-		null /* no extra class libraries */,
-		true /* flush output directory */,
-		null, /* no VM args */
-		options,
-		reader,
-		true /* skip javac */);
-	String tags = taskTagsAsStrings(reader.result.tasks);
-	if (! tags.equals(expectedTags)) {
-		System.out.println(getClass().getName() + '#' + getName());
-		System.out.println("Effective results:");
-		System.out.println(tags);
-		System.out.println("Cut and paste:");
-		taskTagsAsCutAndPaste(reader.result.tasks);
-		assertEquals(expectedTags, tags);
-	}
-}
+
 // Basic test on task tags: watch default behavior
-public void test003_task_tags_options() {
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		null,
-		"[FIXME, message contents,HIGH]\n" +
-		"[TODO, message contents,NORMAL]\n" +
-		"[XXX, message contents,NORMAL]\n");
-}
+	public void test003_task_tags_options() {
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				null, "[FIXME, message contents,HIGH]\n" + "[TODO, message contents,NORMAL]\n"
+						+ "[XXX, message contents,NORMAL]\n");
+	}
+
 // effect of cancelling priorities
 // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed
-public void _test004_task_tags_options() {
-	Map customOptions = new HashMap();
-	customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "");
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		customOptions,
-		"[FIXME, message contents,NORMAL]\n" +
-		"[TODO, message contents,NORMAL]\n" +
-		"[XXX, message contents,NORMAL]\n");
-}
+	public void _test004_task_tags_options() {
+		Map customOptions = new HashMap();
+		customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "");
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				customOptions, "[FIXME, message contents,NORMAL]\n" + "[TODO, message contents,NORMAL]\n"
+						+ "[XXX, message contents,NORMAL]\n");
+	}
+
 // effect of cancelling priorities
 // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed
-public void _test005_task_tags_options() {
-	Map customOptions = new HashMap();
-	customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ",,");
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		customOptions,
-		"[FIXME,message contents,NORMAL]\n" +
-		"[TODO,message contents,NORMAL]\n" +
-		"[XXX,message contents,NORMAL]\n");
-	// would expect an exception of some sort
-}
+	public void _test005_task_tags_options() {
+		Map customOptions = new HashMap();
+		customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, ",,");
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n"
+						+ "[XXX,message contents,NORMAL]\n");
+		// would expect an exception of some sort
+	}
+
 // effect of changing priorities
 // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed
-public void _test006_task_tags_options() {
-	Map customOptions = new HashMap();
-	customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "A,B,C,D,E");
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		customOptions,
-		"[FIXME,message contents,NORMAL]\n" +
-		"[TODO,message contents,NORMAL]\n" +
-		"[XXX,message contents,NORMAL]\n");
-	// would expect an exception of some sort
-}
+	public void _test006_task_tags_options() {
+		Map customOptions = new HashMap();
+		customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "A,B,C,D,E");
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n"
+						+ "[XXX,message contents,NORMAL]\n");
+		// would expect an exception of some sort
+	}
+
 // effect of changing priorities
-public void test007_task_tags_options() {
-	Map customOptions = new HashMap();
-	customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL,NORMAL");
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		customOptions,
-		"[FIXME, message contents,NORMAL]\n" +
-		"[TODO, message contents,NORMAL]\n" +
-		"[XXX, message contents,NORMAL]\n");
-}
+	public void test007_task_tags_options() {
+		Map customOptions = new HashMap();
+		customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL,NORMAL");
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				customOptions, "[FIXME, message contents,NORMAL]\n" + "[TODO, message contents,NORMAL]\n"
+						+ "[XXX, message contents,NORMAL]\n");
+	}
+
 // effect of changing priorities
 // reactivate when bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=143402 is fixed
-public void _test008_task_tags_options() {
-	Map customOptions = new HashMap();
-	customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL"); // one less than the number of tags
-	runTaskTagsOptionsTest(
-		new String[] {
-			"X.java",
-			"public class X {\n" +
-			"  void foo(X x) {\n" +
-			"    // FIXME TODO XXX message contents\n" +
-			"  }\n" +
-			"}\n"},
-		customOptions,
-		"[FIXME,message contents,NORMAL]\n" +
-		"[TODO,message contents,NORMAL]\n" +
-		"[XXX,message contents,NORMAL]\n");
-}
+	public void _test008_task_tags_options() {
+		Map customOptions = new HashMap();
+		customOptions.put(JavaCore.COMPILER_TASK_PRIORITIES, "NORMAL,NORMAL"); // one less than the number of tags
+		runTaskTagsOptionsTest(
+				new String[] { "X.java",
+						"public class X {\n" + "  void foo(X x) {\n" + "    // FIXME TODO XXX message contents\n"
+								+ "  }\n" + "}\n" },
+				customOptions, "[FIXME,message contents,NORMAL]\n" + "[TODO,message contents,NORMAL]\n"
+						+ "[XXX,message contents,NORMAL]\n");
+	}
+
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=206423
 // that bug showed that we had no coverage in the area of missing message
 // templates, which can occur downstream in the localization process (assuming
 // that we always release the English version right)
-public void test009_missing_message_templates() {
-	assertEquals("Unable to retrieve the error message for problem id: 8388607. Check compiler resources.",
-			new DefaultProblemFactory().getLocalizedMessage(Integer.MAX_VALUE, new String[]{}));
-}
+	public void test009_missing_message_templates() {
+		assertEquals("Unable to retrieve the error message for problem id: 4194303. Check compiler resources.",
+				new DefaultProblemFactory().getLocalizedMessage(Integer.MAX_VALUE, new String[] {}));
+	}
+
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=206423
-public void test010_missing_elaboration_templates() {
-	assertEquals("Unable to retrieve the error message elaboration for elaboration id: 1073741823. Check compiler resources.",
-			new DefaultProblemFactory().getLocalizedMessage(0, Integer.MAX_VALUE / 2, new String[]{"Zork"}));
-}
+	public void test010_missing_elaboration_templates() {
+		assertEquals(
+				"Unable to retrieve the error message elaboration for elaboration id: 1073741823. Check compiler resources.",
+				new DefaultProblemFactory().getLocalizedMessage(0, Integer.MAX_VALUE / 2, new String[] { "Zork" }));
+	}
+
 // problem categories - check that categories match expected ones
 // see also discussion in https://bugs.eclipse.org/bugs/show_bug.cgi?id=208383
 public void test011_problem_categories() {
@@ -1188,6 +1162,23 @@
 		expectedProblemAttributes.put("IllegalArrayOfUnionType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("IllegalArrayTypeInIntersectionCast", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
 		expectedProblemAttributes.put("ProblemNotAnalysed", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
+		expectedProblemAttributes.put("SwitchExpressionsIncompatibleResultExpressionTypes",	new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+		expectedProblemAttributes.put("SwitchExpressionsEmptySwitchBlock", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("SwitchExpressionsNoResultExpression", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+		expectedProblemAttributes.put("SwitchExpressionSwitchLabeledBlockCompletesNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("SwitchExpressionLastStatementCompletesNormally", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("SwitchExpressionTrailingSwitchLabels", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+		expectedProblemAttributes.put("switchMixedCase", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+		expectedProblemAttributes.put("SwitchExpressionMissingDefaultCase", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+	    expectedProblemAttributes.put("SwitchExpressionNotBelow12", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+	    expectedProblemAttributes.put("SwitchCaseLabelWithArrowNotBelow12", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+	    expectedProblemAttributes.put("SwitchExpressionPreviewDisabled", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+	    expectedProblemAttributes.put("SwitchCaseLabelWithArrowPreviewDisabled", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
+	    expectedProblemAttributes.put("SwitchExpressionBreakMissingValue", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+	    expectedProblemAttributes.put("SwitchExpressionMissingEnumConstantCase", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+	    expectedProblemAttributes.put("PreviewFeatureDisabled", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE));
+	    expectedProblemAttributes.put("PreviewFeatureUsed", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE));
+	    expectedProblemAttributes.put("PreviewFeatureNotSupported", new ProblemAttributes(CategorizedProblem.CAT_COMPLIANCE));
 		StringBuffer failures = new StringBuffer();
 		StringBuffer correctResult = new StringBuffer(70000);
 		Field[] fields = (iProblemClass = IProblem.class).getFields();
@@ -1196,71 +1187,79 @@
 				Field field1 = (Field) o1;
 				Field field2 = (Field) o2;
 				return field1.getName().compareTo(field2.getName());
-			}
-		});
-		boolean watchInternalCategory = false, printHeader = true;
-		for (int i = 0, length = fields.length; i < length; i++) {
-			Field field = fields[i];
-			if (field.getType() == Integer.TYPE) {
-				int problemId = field.getInt(iProblemClass);
-				int maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
-				if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) {
-					String name = field.getName();
-					ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name);
-					if (expectedAttributes == null) {
-						failures.append("missing expected problem attributes for problem " + name + "\n");
-						int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId);
-						correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + "));\n");
-					} else if (!expectedAttributes.deprecated) {
-						int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId);
-						correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory) + "));\n");
-						if (expectedAttributes.category != actualCategory) {
-							failures.append("category mismatch for problem " + name + " (expected " + categoryName(expectedAttributes.category) + ", got " + categoryName(actualCategory) + ")\n");
-						}
-						if (watchInternalCategory && actualCategory == CategorizedProblem.CAT_INTERNAL) {
-							if (printHeader) {
-								printHeader = false;
-								System.err.println("CAT_INTERNAL for problems:");
+				}
+			});
+			boolean watchInternalCategory = false, printHeader = true;
+			for (int i = 0, length = fields.length; i < length; i++) {
+				Field field = fields[i];
+				if (field.getType() == Integer.TYPE) {
+					int problemId = field.getInt(iProblemClass);
+					int maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
+					if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) {
+						String name = field.getName();
+						ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name);
+						if (expectedAttributes == null) {
+							failures.append("missing expected problem attributes for problem " + name + "\n");
+							int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId);
+							correctResult.append("\t\texpectedProblemAttributes.put(\"" + name
+									+ "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory)
+									+ "));\n");
+						} else if (!expectedAttributes.deprecated) {
+							int actualCategory = ProblemReporter.getProblemCategory(ProblemSeverities.Error, problemId);
+							correctResult.append("\t\texpectedProblemAttributes.put(\"" + name
+									+ "\", new ProblemAttributes(CategorizedProblem." + categoryName(actualCategory)
+									+ "));\n");
+							if (expectedAttributes.category != actualCategory) {
+								failures.append("category mismatch for problem " + name + " (expected "
+										+ categoryName(expectedAttributes.category) + ", got "
+										+ categoryName(actualCategory) + ")\n");
 							}
-							System.err.println("\t" + name);
+							if (watchInternalCategory && actualCategory == CategorizedProblem.CAT_INTERNAL) {
+								if (printHeader) {
+									printHeader = false;
+									System.err.println("CAT_INTERNAL for problems:");
+								}
+								System.err.println("\t" + name);
+							}
+						} else {
+							correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", DEPRECATED);\n");
 						}
-					} else {
-						correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", DEPRECATED);\n");
+					}
+				}
+			}
+			if (failures.length() > 0) {
+				System.out.println(correctResult);
+				System.out.println();
+			}
+			assertEquals(failures.toString(), 0, failures.length());
+		} catch (IllegalAccessException e) {
+			fail("could not access members");
+		}
+	}
+
+	private static Map categoryNames;
+
+	private String categoryName(int category) {
+		if (categoryNames == null) {
+			categoryNames = new HashMap();
+			Field[] fields = CategorizedProblem.class.getFields();
+			for (int i = 0, length = fields.length; i < length; i++) {
+				Field field = fields[i];
+				if (field.getType() == Integer.TYPE) {
+					String name = field.getName();
+					if (name.startsWith("CAT_")) {
+						try {
+							categoryNames.put(Integer.valueOf(field.getInt(CategorizedProblem.class)), name);
+						} catch (IllegalArgumentException e) {
+						} catch (IllegalAccessException e) {
+						}
 					}
 				}
 			}
 		}
-		if (failures.length() > 0) {
-			System.out.println(correctResult);
-			System.out.println();
-		}
-		assertEquals(failures.toString(), 0, failures.length());
+		return (String) categoryNames.get(Integer.valueOf(category));
 	}
-	catch (IllegalAccessException e) {
-		fail("could not access members");
-	}
-}
-private static Map categoryNames;
-private String categoryName(int category) {
-	if (categoryNames == null) {
-		categoryNames = new HashMap();
-		Field[] fields = CategorizedProblem.class.getFields();
-		for (int i = 0, length = fields.length; i < length; i++) {
-			Field field = fields[i];
-			if (field.getType() == Integer.TYPE) {
-				String name = field.getName();
-				if (name.startsWith("CAT_")) {
-					try {
-						categoryNames.put(Integer.valueOf(field.getInt(CategorizedProblem.class)), name);
-					} catch (IllegalArgumentException e) {
-					} catch (IllegalAccessException e) {
-					}
-				}
-			}
-		}
-	}
-	return (String) categoryNames.get(Integer.valueOf(category));
-}
+
 // compiler problems tuning
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=218603
 public void test012_compiler_problems_tuning() {
@@ -2108,6 +2107,23 @@
 		expectedProblemAttributes.put("VarLocalReferencesItself", SKIP);
 		expectedProblemAttributes.put("VarLocalTooManyBrackets", SKIP);
 		expectedProblemAttributes.put("VarLocalWithoutInitizalier", SKIP);
+		expectedProblemAttributes.put("SwitchExpressionsIncompatibleResultExpressionTypes",SKIP);
+		expectedProblemAttributes.put("SwitchExpressionsEmptySwitchBlock",SKIP);
+		expectedProblemAttributes.put("SwitchExpressionsNoResultExpression",SKIP);
+		expectedProblemAttributes.put("SwitchExpressionSwitchLabeledBlockCompletesNormally",SKIP);
+		expectedProblemAttributes.put("SwitchExpressionLastStatementCompletesNormally",SKIP);
+		expectedProblemAttributes.put("SwitchExpressionTrailingSwitchLabels",SKIP);
+		expectedProblemAttributes.put("switchMixedCase", SKIP);
+		expectedProblemAttributes.put("SwitchExpressionMissingDefaultCase",SKIP);
+	    expectedProblemAttributes.put("SwitchExpressionNotBelow12", SKIP);
+	    expectedProblemAttributes.put("SwitchCaseLabelWithArrowNotBelow12", SKIP);
+	    expectedProblemAttributes.put("SwitchExpressionPreviewDisabled", SKIP);
+	    expectedProblemAttributes.put("SwitchCaseLabelWithArrowPreviewDisabled", SKIP);
+	    expectedProblemAttributes.put("SwitchExpressionBreakMissingValue", SKIP);
+	    expectedProblemAttributes.put("SwitchExpressionMissingEnumConstantCase", SKIP);
+	    expectedProblemAttributes.put("PreviewFeatureDisabled", SKIP);
+	    expectedProblemAttributes.put("PreviewFeatureUsed", SKIP);
+	    expectedProblemAttributes.put("PreviewFeatureNotSupported", SKIP);
 		Map constantNamesIndex = new HashMap();
 		Field[] fields = JavaCore.class.getFields();
 		for (int i = 0, length = fields.length; i < length; i++) {
@@ -2115,46 +2131,47 @@
 			String fieldName;
 			if (field.getType() == String.class && (fieldName = field.getName()).startsWith("COMPILER_PB_")) {
 				constantNamesIndex.put(field.get(null), fieldName);
-			}
-		}
-		fields = IProblem.class.getFields();
-		StringBuffer failures = new StringBuffer();
-		StringBuffer correctResult = new StringBuffer(70000);
-		Arrays.sort(fields, new Comparator() {
-			public int compare(Object o1, Object o2) {
-				Field field1 = (Field) o1;
-				Field field2 = (Field) o2;
-				return field1.getName().compareTo(field2.getName());
-			}
-		});
-		for (int i = 0, length = fields.length; i < length; i++) {
-			Field field = fields[i];
-			if (field.getType() == Integer.TYPE) {
-				int problemId = field.getInt(null), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
-				if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) {
-					String name = field.getName();
-					ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name);
-					String actualTuningOption = JavaCore.getOptionForConfigurableSeverity(problemId);
-					if (expectedAttributes == null) {
-						failures.append("missing expected problem attributes for problem " + name + "\n");
-					} else if (!expectedAttributes.skip && !expectedAttributes.option.equals(actualTuningOption)) {
-						failures.append("tuning option mismatch for problem " + name + " (expected " + expectedAttributes.option + ", got " + actualTuningOption + ")\n");
-					}
-					String optionFieldName = (String) constantNamesIndex.get(actualTuningOption);
-					correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", " +
-						(optionFieldName != null ? "new ProblemAttributes(JavaCore." + optionFieldName + ")" :
-							"SKIP") + ");\n");
 				}
 			}
+			fields = IProblem.class.getFields();
+			StringBuffer failures = new StringBuffer();
+			StringBuffer correctResult = new StringBuffer(70000);
+			Arrays.sort(fields, new Comparator() {
+				public int compare(Object o1, Object o2) {
+					Field field1 = (Field) o1;
+					Field field2 = (Field) o2;
+					return field1.getName().compareTo(field2.getName());
+				}
+			});
+			for (int i = 0, length = fields.length; i < length; i++) {
+				Field field = fields[i];
+				if (field.getType() == Integer.TYPE) {
+					int problemId = field.getInt(null), maskedProblemId = problemId & IProblem.IgnoreCategoriesMask;
+					if (maskedProblemId != 0 && maskedProblemId != IProblem.IgnoreCategoriesMask) {
+						String name = field.getName();
+						ProblemAttributes expectedAttributes = (ProblemAttributes) expectedProblemAttributes.get(name);
+						String actualTuningOption = JavaCore.getOptionForConfigurableSeverity(problemId);
+						if (expectedAttributes == null) {
+							failures.append("missing expected problem attributes for problem " + name + "\n");
+						} else if (!expectedAttributes.skip && !expectedAttributes.option.equals(actualTuningOption)) {
+							failures.append("tuning option mismatch for problem " + name + " (expected "
+									+ expectedAttributes.option + ", got " + actualTuningOption + ")\n");
+						}
+						String optionFieldName = (String) constantNamesIndex.get(actualTuningOption);
+						correctResult.append("\t\texpectedProblemAttributes.put(\"" + name + "\", "
+								+ (optionFieldName != null ? "new ProblemAttributes(JavaCore." + optionFieldName + ")"
+										: "SKIP")
+								+ ");\n");
+					}
+				}
+			}
+			if (failures.length() > 0) {
+				System.out.println(correctResult);
+				System.out.println();
+			}
+			assertEquals(failures.toString(), 0, failures.length());
+		} catch (IllegalAccessException e) {
+			fail("could not access members");
 		}
-		if (failures.length() > 0) {
-			System.out.println(correctResult);
-			System.out.println();
-		}
-		assertEquals(failures.toString(), 0, failures.length());
 	}
-	catch (IllegalAccessException e) {
-		fail("could not access members");
-	}
-}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
index 5602566..ac0da2f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2018 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for
@@ -2904,6 +2908,1944 @@
 		"The local variable action may not have been initialized\n" + 
 		"----------\n");
 }
+public void testBug542707_001() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 11)\n" + 
+			"	break k;\n" + 
+			"	      ^\n" + 
+			"The local variable k may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 14)\n" + 
+			"	return k + it;\n" + 
+			"	       ^\n" + 
+			"The local variable k may not have been initialized\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		final int k;\n" +
+			"\n" +
+			"		int it = switch (i) { \n" +
+			"		case 1  ->   {\n" +
+			"			k = 1;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		default -> {\n" +
+			"			break k;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return k + it;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+		};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+
+}
+public void testBug542707_002() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 5)\n" + 
+			"	k = switch (i) { \n" + 
+			"	^\n" + 
+			"The final local variable k may already have been assigned\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 11)\n" + 
+			"	break k;\n" + 
+			"	      ^\n" + 
+			"The local variable k may not have been initialized\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		final int k;\n" +
+			"\n" +
+			"		k = switch (i) { \n" +
+			"		case 1  ->   {\n" +
+			"			k = 1;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		default -> {\n" +
+			"			break k;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return k;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+		};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/*
+ * k is definitely assigned - no errors on that front.
+ */
+public void testBug542707_003() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 23)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		final int k;\n" +
+			"\n" +
+			"		int it = switch (i) { \n" +
+			"		case 1  ->   {\n" +
+			"			k = 1;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		case 2  ->   {\n" +
+			"			k = 2;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		default -> {\n" +
+			"			k = 3;\n" +
+			"			break k;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return k;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+public void testBug542707_004() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	k = 1;\n" + 
+			"	^\n" + 
+			"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 11)\n" + 
+			"	k = 2;\n" + 
+			"	^\n" + 
+			"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 15)\n" + 
+			"	k = 3;\n" + 
+			"	^\n" + 
+			"The final local variable k cannot be assigned. It must be blank and not using a compound assignment\n" + 
+			"----------\n" + 
+			"4. ERROR in X.java (at line 23)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		final int k = 1;\n" +
+			"\n" +
+			"		int it = switch (i) { \n" +
+			"		case 1  ->   {\n" +
+			"			k = 1;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		case 2  ->   {\n" +
+			"			k = 2;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		default -> {\n" +
+			"			k = 3;\n" +
+			"			break k;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return k;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+public void testBug542707_005() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 11)\n" + 
+			"	break k ;\n" + 
+			"	      ^\n" + 
+			"The local variable k may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 18)\n" + 
+			"	return k;\n" + 
+			"	       ^\n" + 
+			"The local variable k may not have been initialized\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		final int k;\n" +
+			"\n" +
+			"		int it = switch (i) { \n" +
+			"		case 1  ->   {\n" +
+			"			k = 1;\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		case 2  ->   {\n" +
+			"			break k ;\n" +
+			"		}\n" +
+			"		default -> {\n" +
+			"			k = 3;\n" +
+			"			break k;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return k;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is definitely assigned after a switch expression when true iff for every value break statement with
+ * expression e in the switch block that may exit the switch expression, V is definitely assigned after e when true.
+ * V is definitely assigned after a switch expression when false iff for every value break statement with
+ * expression e in the switch block that may exit the switch expression, V is definitely assigned after e when false.
+ */
+public void testBug542707_006() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 1 :\n" +
+			"			v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued.
+ * V is definitely unassigned after a switch expression when true iff for every value break statement with expression
+ * e in the switch block that may exit the switch expression, V is definitely unassigned before the value break
+ * statement and V is definitely unassigned after e when true.
+ * V is definitely unassigned after a switch expression when false iff for every value break statement with expression
+ * e in the switch block that may exit the switch expression, V is definitely unassigned before the value break
+ * statement and V is definitely unassigned after e when false.
+ */
+public void testBug542707_007() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 18)\n" + 
+			"	return v + d;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 1 :\n" +
+			"			//v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			//v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			//v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
+ */
+public void testBug542707_008() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v = 1;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 1 :\n" +
+			"			//v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			//v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			//v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
+ */
+public void testBug542707_009() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 4)\n" + 
+			"	boolean b = switch (v) {\n" + 
+			"	                    ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (v) {\n" +
+			"		case 1 :\n" +
+			"			v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
+ * iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_010() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i + (v =1)) {\n" +
+			"		case 1 :\n" +
+			"			v += 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
+ * iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_011() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	v += 1;\n" + 
+			"	^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 1 :\n" +
+			"			v += 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued.
+ * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff
+ * V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement.
+ * TODO: the second part - "and V is [un]assigned after the preceding statement" needs to be checked, now it looks identical to the 
+ * preceding rule
+ */
+public void testBug542707_012() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i + (v =1)) {\n" +
+			"		case 1 :\n" +
+			"			v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v += 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff
+ * V is [un]assigned after the selector expression and V is [un]assigned after the preceding statement.
+ * TODO: the second part - "and V is [un]assigned after the preceding statement" needs to be checked, now it looks identical to the 
+ * preceding rule
+ */
+public void testBug542707_013() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 9)\n" + 
+			"	v += 2;\n" + 
+			"	^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 22)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 1 :\n" +
+			"			v = 1;\n" +
+			"			break true;\n" +
+			"		case 2 : {\n" +
+			"			v += 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is definitely assigned after a switch expression when true iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely assigned after e when true.
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that may exit the switch expression, 
+ * 			V is definitely assigned after e when true.
+ * 		It is a switch labeled throw statement.
+ * 
+ * V is definitely assigned after a switch expression when false iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely assigned after e when false.
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that may exit the switch expression,
+ * 		V is definitely assigned after e when false.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_014() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 23)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i ) {\n" +
+			"		case 0 -> (v = 1) != 0;\n" +
+			"		case 1 -> (v = 1) == 0;\n" +
+			"		case 2 -> {\n" +
+			"			v = 2;\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		case 3 -> {\n" +
+			"			v = 3;\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is definitely unassigned after a switch expression when true iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely unassigned after e when true .
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that
+ * 		 may exit the switch expression, V is definitely unassigned before the value break statement and 
+ * 		     V is definitely unassigned after e when true.
+ * 		It is a switch labeled throw statement.
+ * 
+ * V is definitely unassigned after a switch expression when false iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely unassigned after e when false.
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that may
+ * 		exit the switch expression,	V is definitely unassigned before the value break statement and V is definitely unassigned 
+ * 			after e when false.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_015() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 17)\n" + 
+			"	return v + d;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 21)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i ) {\n" +
+			"		case 0 ->  true;\n" +
+			"		case 1 -> false;\n" +
+			"		case 2 -> {\n" +
+			"			break true;\n" +
+			"		}\n" +
+			"		case 3 -> {\n" +
+			"			break false;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * V is [un]assigned before any switch labeled expression or statement in the switch
+ * block iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_016() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 14)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v;\n" +
+			"		boolean b = switch ((v = 1)) {\n" +
+			"		case 0 ->  v != 0;\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.7 , Suppose that the switch expression has result expressions e1, …, en, all of
+ * which are boolean-valued. 
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is [un]assigned before any switch labeled expression or statement in the switch
+ * block iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_017() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	case 0 ->  v != 0;\n" + 
+			"	           ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 10)\n" + 
+			"	return v + d;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"3. ERROR in X.java (at line 14)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v;\n" +
+			"		boolean b = switch (i) {\n" +
+			"		case 0 ->  v != 0;\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		int d = b == true ? 0 : 1; \n" +
+			"		return v + d;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is definitely assigned after a switch expression iff for every value break statement with expression e
+ *  in the switch block that may exit the switch expression, either V is definitely assigned before the value
+ *   break statement or V is definitely assigned after e.
+ */
+public void testBug542707_018() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 20)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 : {\n" +
+			"			v = 1; // definitely assigned before break\n" +
+			"			break v;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break v =1; // definitely assigned after e\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break v = 2;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return v + t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is definitely unassigned after a switch expression iff for every value break statement with expression e
+ * in the switch block that may exit the switch expression, V is definitely unassigned before the value break
+ * statement and V is definitely unassigned after e.
+ */
+public void testBug542707_019() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 15)\n" + 
+			"	return v + t;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 : {\n" +
+			"			break 1;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break 2;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return v + t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
+ */
+public void testBug542707_020() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v =1;\n" +
+			"		int t = switch (v) {\n" +
+			"		case 0 : {\n" +
+			"			break 1;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break 2;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is [un]assigned before the selector expression iff V is [un]assigned before the switch statement.
+ */
+public void testBug542707_021() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 4)\n" + 
+			"	int t = switch (v) {\n" + 
+			"	                ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		int t = switch (v) {\n" +
+			"		case 0 : {\n" +
+			"			break 1;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break 2;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
+ * iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_022() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v =1;\n" +
+			"		int t = switch (v) {\n" +
+			"		case 0 : {\n" +
+			"			break v;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break 2;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is [un]assigned before the first statement of the first switch labeled statement group in the switch block
+ * iff V is [un]assigned after the selector expression.
+ */
+public void testBug542707_023() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	break v;\n" + 
+			"	      ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 : {\n" +
+			"			break v;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break 2;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression (15.28) consists of switch
+ * labeled statement groups:
+ * V is [un]assigned before the first statement of any switch labeled statement group other than the first iff V is [un]assigned
+ * after the selector expression and V is [un]assigned after the preceding statement.
+ */
+public void testBug542707_024() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 9)\n" + 
+			"	break v;\n" + 
+			"	      ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 19)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"public class X {\n" +
+			"	public static int foo(int i) {\n" +
+			"		int v ;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 : {\n" +
+			"			break 1;\n" +
+			"		}\n" +
+			"		case 2 : {\n" +
+			"			break v;\n" +
+			"		}\n" +
+			"		default : {\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		System.out.println(foo(3));\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is definitely assigned after a switch expression iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely assigned after e.
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that may exit
+ * 			the switch expression, either V is definitely assigned before the value break statement or V is definitely
+ * 			assigned after e.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_025() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 20)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 -> v = 1;\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				break v = 2;\n" +
+			"			}\n" +
+			"			break v = 3;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return v + t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is definitely unassigned after a switch expression iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and V is definitely unassigned after e.
+ * 		It is a switch labeled block b and for every value break statement expression e contained in b that may exit the
+ * 			switch expression, V is definitely unassigned before the value break statement
+ * 			and V is definitely unassigned after e.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_026() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 16)\n" + 
+			"	return v + t;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 20)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 ->  1;\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				break  2;\n" +
+			"			}\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return v + t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is [un]assigned before any switch labeled expression or statement in the switch block iff
+ * V is [un]assigned after the selector expression.
+ */
+public void testBug542707_027() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 20)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		int t = switch (v = 1) {\n" +
+			"		case 0 ->  v;\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				break  2;\n" +
+			"			}\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return v + t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.1.8, Suppose that the switch expression has result expressions e1, …, en, not all of
+ * which are boolean-valued.
+ * The following rules apply only if the switch block of a switch expression consists of switch labeled rules:
+ * V is [un]assigned before any switch labeled expression or statement in the switch block iff
+ * V is [un]assigned after the selector expression.
+ */
+public void testBug542707_028() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	case 0 ->  v;\n" + 
+			"	           ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 20)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		int t = switch (i) {\n" +
+			"		case 0 ->  v;\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				break  2;\n" +
+			"			}\n" +
+			"			break 3;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return t;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.2.9, The following rules apply only if the switch block of the switch statement consists of switch labeled rules:
+ * V is [un]assigned after a switch statement iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and either V is [un]assigned after e or after the selector expression.
+ * 		It is a switch labeled block b and either V is [un]assigned after e or V is [un]assigned before every
+ * 		break statement contained in b that may exit the switch statement.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_029() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"2. ERROR in X.java (at line 24)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		switch (i) {\n" +
+			"		case 0 -> {\n" +
+			"			v = 0;\n" +
+			"		}\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				v =  2;\n" +
+			"				break;\n" +
+			"			}\n" +
+			"			v = 3;\n" +
+			"			break;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return v;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
+/**
+ * From JLS 12 16.2.9, The following rules apply only if the switch block of the switch statement consists of switch labeled rules:
+ * V is [un]assigned after a switch statement iff for every switch labeled rule one of the following is true:
+ * 		It is a switch labeled expression e and either V is [un]assigned after e or after the selector expression.
+ * 		It is a switch labeled block b and either V is [un]assigned after e or V is [un]assigned before every
+ * 		break statement contained in b that may exit the switch statement.
+ * 		It is a switch labeled throw statement.
+ */
+public void testBug542707_030() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map<String, String> defaultOptions = super.getCompilerOptions();
+	defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	String expectedProblemLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 20)\n" + 
+			"	return v;\n" + 
+			"	       ^\n" + 
+			"The local variable v may not have been initialized\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 24)\n" + 
+			"	Zork();\n" + 
+			"	^^^^\n" + 
+			"The method Zork() is undefined for the type X\n" + 
+			"----------\n";
+	String[] testFiles = new String[] {
+			"X.java", // =================
+			"import java.io.IOException;\n" +
+			"\n" +
+			"public class X {\n" +
+			"	public static int foo(int i) throws IOException {\n" +
+			"		int v ;\n" +
+			"		switch (i) {\n" +
+			"		case 0 -> {\n" +
+			"			v = 0;\n" +
+			"		}\n" +
+			"		case 2 -> {\n" +
+			"			if (i > 1) {\n" +
+			"				v =  2;\n" +
+			"				break;\n" +
+			"			}\n" +
+			"	//		v = 3;\n" +
+			"			break;\n" +
+			"		}\n" +
+			"		default -> throw new IOException();\n" +
+			"		};\n" +
+			"		return v;\n" +
+			"	}\n" +
+			"	\n" +
+			"	public boolean bar() {\n" +
+			"		Zork();\n" +
+			"		return true;\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			System.out.println(foo(3));\n" +
+			"		} catch (IOException e) {\n" +
+			"			// TODO Auto-generated catch block\n" +
+			"			e.printStackTrace();\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n",
+	};
+	this.runNegativeTest(
+			testFiles,
+			expectedProblemLog,
+			null,
+			true,
+			defaultOptions);
+}
 public static Class testClass() {
 	return FlowAnalysisTest.class;
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
index 10d7a54..de0df41 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -15337,7 +15337,9 @@
 			"1. ERROR in X.java (at line 6)\n" +
 			"	Integer[] var = cond ? tab1 : tab2;\n" +
 			"	                ^^^^^^^^^^^^^^^^^^\n" +
-			"Type mismatch: cannot convert from Object&Serializable&Comparable<? extends Object&Serializable&Comparable<?>>[] to Integer[]\n" +
+			"Type mismatch: cannot convert from Object&Serializable&" +
+			"" + intersection("Comparable<? extends Object&Serializable&" + intersection("Comparable<?>") + ">") +
+			"[] to Integer[]\n" +
 			"----------\n": 
 				"----------\n" + 
 				"1. ERROR in X.java (at line 6)\n" + 
@@ -19815,7 +19817,7 @@
 	    			"1. ERROR in X.java (at line 10)\n" + 
 	    			"	String s = l1 != null ? foo(l1, l2) : l3;\n" + 
 		    		"	                        ^^^^^^^^^^^\n" +
-		    		"Type mismatch: cannot convert from List<capture#2-of ? extends Number & Comparable<?>> to String\n" +
+		    		"Type mismatch: cannot convert from List<capture#2-of ? extends Number & "+intersection("Comparable<?>")+"> to String\n" +
 	    			"----------\n");
 	}
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=92556
@@ -25439,7 +25441,7 @@
 		"1. ERROR in X.java (at line 7)\n" +
 		"	if (isGreater(i, d)) \n" +
 		"	    ^^^^^^^^^\n" +
-		"Bound mismatch: The generic method isGreater(T, T) of type X is not applicable for the arguments (Integer, Double). The inferred type Number&Comparable<?> is not a valid substitute for the bounded parameter <T extends Comparable<T>>\n" +
+		"Bound mismatch: The generic method isGreater(T, T) of type X is not applicable for the arguments (Integer, Double). The inferred type "+ intersection("Number", "Comparable<?>") +" is not a valid substitute for the bounded parameter <T extends Comparable<T>>\n" +
 		"----------\n" +
 		"2. ERROR in X.java (at line 15)\n" +
 		"	isGreater(c1, c2);\n" +
@@ -26064,7 +26066,9 @@
 		"2. ERROR in X.java (at line 14)\n" +
 		"	String s2 = foo(integers, floats);\n" +
 		"	            ^^^^^^^^^^^^^^^^^^^^^\n" +
-		"Type mismatch: cannot convert from "+intersection("Number","Comparable<? extends "+intersection("Number","Comparable<?>")+">[]")+" to String\n" +
+		"Type mismatch: cannot convert from "+intersection("Number",
+				intersection("Comparable<? extends "+intersection("Number","Comparable<?>")+">")
+				)+"[] to String\n" +
 		"----------\n");
 }
 //https://bugs.eclipse.org/bugs/show_bug.cgi?id=107079
@@ -33564,12 +33568,12 @@
 		"4. WARNING in X.java (at line 14)\n" + 
 		"	Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + 
 		"	                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Type safety: A generic array of Iterator<? extends Number&Comparable<?>> is created for a varargs parameter\n" + 
+		"Type safety: A generic array of Iterator<? extends "+ intersection("Number", "Comparable<?>") +"> is created for a varargs parameter\n" + 
 		"----------\n" + 
 		"5. ERROR in X.java (at line 14)\n" + 
 		"	Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + 
 		"	                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-		"Type mismatch: cannot convert from Iterator<Number&Comparable<?>> to Iterator<Number>\n" + 
+		"Type mismatch: cannot convert from Iterator<"+ intersection("Number", "Comparable<?>") +"> to Iterator<Number>\n" + 
 		"----------\n" + 
 		"6. WARNING in X.java (at line 18)\n" + 
 		"	Iterator<Number> it2 = X.chain(l1.iterator(), l1.iterator());\n" + 
@@ -33606,12 +33610,12 @@
 			"5. WARNING in X.java (at line 14)\n" + 
 			"	Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + 
 			"	                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-			"Type safety: A generic array of Iterator<? extends Number&Comparable<?>> is created for a varargs parameter\n" + 
+			"Type safety: A generic array of Iterator<? extends Number&"+ intersection("Comparable<?>") +"> is created for a varargs parameter\n" + 
 			"----------\n" + 
 			"6. ERROR in X.java (at line 14)\n" + 
 			"	Iterator<Number> it2 = X.chain(l1.iterator(), l2.iterator());\n" + 
 			"	                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
-			"Type mismatch: cannot convert from Iterator<Number&Comparable<?>> to Iterator<Number>\n" + 
+			"Type mismatch: cannot convert from Iterator<Number&"+ intersection("Comparable<?>") +"> to Iterator<Number>\n" + 
 			"----------\n" + 
 			"7. WARNING in X.java (at line 18)\n" + 
 			"	Iterator<Number> it2 = X.chain(l1.iterator(), l1.iterator());\n" + 
@@ -34746,7 +34750,7 @@
 			"1. ERROR in X.java (at line 10)\n" +
 			"	List<Number> name = makeNumberList(5, 5D);\n" +
 			"	                    ^^^^^^^^^^^^^^^^^^^^^\n" +
-			"Type mismatch: cannot convert from List<Number&Comparable<?>> to List<Number>\n" +
+			"Type mismatch: cannot convert from List<"+ intersection("Number", "Comparable<?>") +"> to List<Number>\n" +
 			"----------\n",
 			null,
 			true,
@@ -39658,7 +39662,7 @@
 			"1. ERROR in X.java (at line 4)\n" +
 			"	List<Object>  l1 = Arrays.asList(1, \"X\");\n" +
 			"	                   ^^^^^^^^^^^^^^^^^^^^^\n" +
-			"Type mismatch: cannot convert from List<Object&Comparable<?>&Serializable> to List<Object>\n" +
+			"Type mismatch: cannot convert from List<Object&"+ intersection("Comparable<?>") +"&Serializable> to List<Object>\n" +
 			"----------\n" +
 			"2. ERROR in X.java (at line 8)\n" +
 			"	List<Object>  l2 = Arrays.asList(b, c);\n" +
@@ -43202,7 +43206,7 @@
 		"1. WARNING in X.java (at line 4)\n" +
 		"	Arrays.asList(String.class, Integer.class);\n" +
 		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
-		"Type safety: A generic array of Class<? extends Object&Serializable&Comparable<?>> is created for a varargs parameter\n" +
+		"Type safety: A generic array of Class<? extends Object&Serializable&"+ intersection("Comparable<?>") +"> is created for a varargs parameter\n" +
 		"----------\n" +
 		"2. ERROR in X.java (at line 6)\n" +
 		"	Zork z;\n" +
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java
index d7c3fb2..891f9e4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JEP286Test.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2018 Jesper Steen Møller and others.
+ * Copyright (c) 2018, 2019 Jesper Steen Møller and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  * 
  * Contributors:
@@ -69,7 +73,11 @@
 	simpleTypeNames.put("ComparableAny", "Comparable<?>");
 	simpleTypeNames.put("CollectionExt_ComparableAny", "Collection<? extends Comparable<?>>");
 	simpleTypeNames.put("CollectionSuperComparableAny", "Collection<? super Comparable<?>>");
-	simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?>");
+	isJRE12Plus = isJRELevel(F_12);
+	if (isJRE12Plus)
+		simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?> & java.lang.constant.Constable & java.lang.constant.ConstantDesc");
+	else 
+		simpleTypeNames.put("IntLongFloat", "java.lang.Number & Comparable<?>");
 	simpleTypeNames.put("ListTestAndSerializable", "List<? extends Z & java.io.Serializable>");
 	simpleTypeNames.put("TestAndSerializable", "Z & java.io.Serializable");
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
index 349e89c..bdbb120 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ModuleCompilationTests.java
@@ -4325,6 +4325,121 @@
 	        true,
 	        /*not tested with javac*/"");
 	}
+	public void testReleaseOption20() throws Exception {
+		if (!isJRE12Plus) return;
+		this.runNegativeTest(
+				new String[] {
+					"X.java",
+					"import java.io.*;\n" + 
+					"\n" + 
+					"public class X {\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		String str = Integer.toUnsignedString(1, 1);\n" + 
+					"	}\n" + 
+					"}",
+				},
+		     "\"" + OUTPUT_DIR +  File.separator + "X.java\""
+		     + " --release 7 -d \"" + OUTPUT_DIR + "\"",
+		     "",
+		     "----------\n" + 
+    		 "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 5)\n" + 
+    		 "	String str = Integer.toUnsignedString(1, 1);\n" + 
+    		 "	                     ^^^^^^^^^^^^^^^^\n" + 
+    		 "The method toUnsignedString(int, int) is undefined for the type Integer\n" + 
+    		 "----------\n" + 
+    		 "1 problem (1 error)\n",
+		     true);
+	}
+	public void testReleaseOption21() throws Exception {
+		if (!isJRE12Plus) return;
+		this.runConformTest(
+				new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		Integer.toUnsignedString(1, 1);\n" + 
+					"	}\n" + 
+					"}",
+				},
+		     "\"" + OUTPUT_DIR +  File.separator + "X.java\""
+		     + " --release 8 -d \"" + OUTPUT_DIR + "\"",
+		     "",
+    		 "",
+		     true);
+	}
+	public void testReleaseOption22() {
+		if (isJRE11Plus || isJRE12Plus) return;
+		runConformTest(
+			new String[] {
+				"p/X.java",
+				"package p;\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"	}\n" +
+				"}",
+				"module-info.java",
+				"module mod.one { \n" +
+				"	requires java.base;\n" +
+				"	requires java.xml.ws.annotation;\n" +
+				"}"
+	        },
+			" --limit-modules java.base,java.xml.ws.annotation " +
+			" --release 10 \"" + OUTPUT_DIR +  File.separator + "module-info.java\" "
+	        + "\"" + OUTPUT_DIR +  File.separator + "p/X.java\"",
+	        "",
+	        "----------\n" + 
+    		"1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/module-info.java (at line 3)\n" + 
+    		"	requires java.xml.ws.annotation;\n" + 
+    		"	         ^^^^^^^^^^^^^^^^^^^^^^\n" + 
+    		"The module java.xml.ws.annotation has been deprecated since version 9 and marked for removal\n" + 
+    		"----------\n" + 
+    		"1 problem (1 warning)\n",
+	        true);
+	}
+	public void testReleaseOption23() {
+		if (!isJRE11Plus) return;
+		runNegativeTest(
+			new String[] {
+				"p/X.java",
+				"package p;\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"	}\n" +
+				"}",
+				"module-info.java",
+				"module mod.one { \n" +
+				"	requires java.xml.ws.annotation;\n" +
+				"}"
+	        },
+			" --limit-modules java.base,java.xml.ws.annotation " +
+			" --release 11 \"" + OUTPUT_DIR +  File.separator + "module-info.java\" "
+	        + "\"" + OUTPUT_DIR +  File.separator + "p/X.java\"",
+	        "",
+	        "invalid module name: java.xml.ws.annotation\n",
+	        true);
+	}
+	public void testReleaseOption24() {
+		if (!isJRE11Plus) return;
+		runNegativeTest(
+			new String[] {
+				"p/X.java",
+				"package p;\n" +
+				"public class X {\n" +
+				"	public static void main(String[] args) {\n" +
+				"	}\n" +
+				"}",
+				"module-info.java",
+				"module mod.one { \n" +
+				"	requires java.xml.ws.annotation;\n" +
+				"}"
+	        },
+			" --limit-modules java.base,java.xml.ws.annotation " +
+			" --release 12 \"" + OUTPUT_DIR +  File.separator + "module-info.java\" "
+	        + "\"" + OUTPUT_DIR +  File.separator + "p/X.java\"",
+	        "",
+	        "invalid module name: java.xml.ws.annotation\n",
+	        true);
+	}
 	public void testLimitModules1() {
 		File outputDirectory = new File(OUTPUT_DIR);
 		Util.flushDirectoryContent(outputDirectory);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
index 57ce8de..3a818b4 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2010, 2018 GK Software AG and others.
+ * Copyright (c) 2010, 2019 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     Till Brychcy <register.eclipse@brychcy.de> - Contribution for
@@ -10359,4 +10363,228 @@
 		"----------\n"
 	);
 }
+public void testBug542707_001() {
+	if (this.complianceLevel < ClassFileConstants.JDK12)
+		return;
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR);
+	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runNegativeTestWithLibs(
+			new String[] {
+			"X.java",
+			"import java.io.IOException;\n"+
+			"\n"+
+			"import org.eclipse.jdt.annotation.NonNull;\n"+
+			"\n"+
+			"public class X {\n"+
+			"	public static int foo(int i) throws IOException {\n"+
+			"		int k = 0;\n"+
+			"		@NonNull\n"+
+			"		X x = new X();\n"+
+			"		x  = switch (i) { \n"+
+			"		case 1  ->   {\n"+
+			"			x = null;\n"+
+			"			break x;\n"+
+			"		}\n"+
+			"		default -> null;\n"+
+			"		};\n"+
+			"\n"+
+			"		return k ;\n"+
+			"	}\n"+
+			"\n"+
+			"	public static void main(String[] args) {\n"+
+			"		try {\n"+
+			"			System.out.println(foo(3));\n"+
+			"		} catch (IOException e) {\n"+
+			"			// do nothing\n"+
+			"		}\n"+
+			"	}\n"+
+			"}\n"
+				},
+		options,
+		"----------\n" + 
+		"1. ERROR in X.java (at line 12)\n" + 
+		"	x = null;\n" + 
+		"	    ^^^^\n" + 
+		"Null type mismatch: required \'@NonNull X\' but the provided value is null\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 15)\n" + 
+		"	default -> null;\n" + 
+		"	           ^^^^\n" + 
+		"Null type mismatch: required \'@NonNull X\' but the provided value is null\n" + 
+		"----------\n"
+	);
+}
+/**
+ * should not throw IOOBE while building - a safety check test case.
+ */
+public void testBug542707_002() {
+	if (this.complianceLevel != ClassFileConstants.JDK12)
+		return;
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR);
+	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); 
+	options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+	options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+	options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runNegativeTestWithLibs(
+			new String[] {
+			"X.java",
+			"import org.eclipse.jdt.annotation.*;\n" +
+			"public class X {\n" +
+			"    	void m1(@NonNull String a) {}\n" +
+			"		void m2(@Nullable String b, int i) {\n" +
+			"			m1(switch(i) {\n" +
+			"			case 0 : {\n" +
+			"				break \"hello\";\n" +
+			"			}\n" +
+			"			default : break \"world\";\n" +
+			"			});\n" +
+			"		}\n" +
+			"		void m3() {\n" +
+			"			Zork();\n" +
+			"		}\n" +
+			"}\n"
+				},
+		options,
+		"----------\n" + 
+		"1. ERROR in X.java (at line 13)\n" + 
+		"	Zork();\n" + 
+		"	^^^^\n" + 
+		"The method Zork() is undefined for the type X\n" + 
+		"----------\n"
+	);
+}
+public void testBug542707_003() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	// outer expected type (from assignment) is propagated deeply into a switch expression
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"X.java",
+		"import org.eclipse.jdt.annotation.*;\n" +
+		"public class X {\n" +
+		"	@Nullable String maybe() { return null; }\n" + 
+		"	void test(int i) {\n" +
+		"		@NonNull String s = switch (i) {\n" + 
+		"			case 1 -> \"\";\n" + 
+		"			default -> i == 3 ? maybe() : \"\";\n" + 
+		"		};\n" + 
+		"		System.out.println(s.toLowerCase());\n" +
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	default -> i == 3 ? maybe() : \"\";\n" + 
+			"	                    ^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
+// failing, see https://bugs.eclipse.org/543860
+public void _testBug542707_004() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	// outer expected type (from method parameter) is propagated deeply into a switch expression
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"X.java",
+		"import org.eclipse.jdt.annotation.*;\n" +
+		"public class X {\n" +
+		"	@Nullable String maybe() { return null; }\n" + 
+		"	void need(@NonNull String s) {\n" + 
+		"		System.out.println(s.toLowerCase());\n" + 
+		"	}\n" +
+		"	void test(int i) {\n" +
+		"		need(switch (i) {\n" + 
+		"			case 1 -> \"\";\n" + 
+		"			default -> i == 3 ? maybe() : \"\";\n" + 
+		"		});\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 10)\n" + 
+			"	default -> i == 3 ? maybe() : \"\";\n" + 
+			"	                    ^^^^^^^\n" + 
+			"Null type mismatch (type annotations): required '@NonNull String' but this expression has type '@Nullable String'\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
+public void testBug542707_005() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	// switch value must not be null (@Nullable)
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"X.java",
+		"import org.eclipse.jdt.annotation.*;\n" +
+		"enum SomeDays { Mon, Wed, Fri }\n" +
+		"public class X {\n" +
+		"	int testEnum(@Nullable SomeDays day) {\n" + 
+		"		return switch(day) {\n" + 
+		"		case Mon -> 1;\n" + 
+		"		case Wed -> 2;\n" + 
+		"		case Fri -> 3;\n" + 
+		"		};\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 5)\n" + 
+			"	return switch(day) {\n" + 
+			"	              ^^^\n" + 
+			"Potential null pointer access: this expression has a \'@Nullable\' type\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
+public void testBug542707_006() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	// switch value must not be null (pot-null by flow analysis)
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"X.java",
+		"enum SomeDays { Mon, Wed, Fri }\n" +
+		"public class X {\n" +
+		"	int testEnum(boolean b) {\n" +
+		"		SomeDays day = b ? SomeDays.Mon : null;\n" + 
+		"		return switch(day) {\n" + 
+		"		case Mon -> 1;\n" + 
+		"		case Wed -> 2;\n" + 
+		"		case Fri -> 3;\n" + 
+		"		};\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"2. ERROR in X.java (at line 5)\n" + 
+			"	return switch(day) {\n" + 
+			"	              ^^^\n" + 
+			"Potential null pointer access: The variable day may be null at this location\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index 60f05cc..0eee7cd 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2016 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
@@ -45,6 +49,7 @@
 package org.eclipse.jdt.core.tests.compiler.regression;
 
 import java.io.File;
+import java.util.HashMap;
 import java.util.Map;
 
 import junit.framework.Test;
@@ -18237,4 +18242,31 @@
 	runner.javacTestOptions = JavacTestOptions.Excuse.EclipseWarningConfiguredAsError;
 	runner.runNegativeTest();
 }
+public void testBug542707_1() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	Runner runner = new Runner();
+	runner.customOptions = new HashMap<>();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+	runner.testFiles = new String[] {
+		"X.java",
+		"public class X {\n" +
+		"	void test(int i) {\n" +
+		"		String s = switch (i) {\n" +
+		"			case 1 -> \"one\";\n" +
+		"			default -> null;\n" +
+		"		};\n" +
+		"		System.out.println(s.toLowerCase());\n" +
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	System.out.println(s.toLowerCase());\n" + 
+			"	                   ^\n" + 
+			"Potential null pointer access: The variable s may be null at this location\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
index ccbd91d..9cbfdcf 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullTypeAnnotationTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2018 GK Software AG and others.
+ * Copyright (c) 2012, 2019 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     IBM Corporation
@@ -17749,4 +17753,52 @@
 		"----------\n"
 	);
 }
+public void testBug542707_1() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression
+	// switch expression has a functional type with interesting type inference and various null issues:
+	Runner runner = new Runner();
+	runner.customOptions = getCompilerOptions();
+	runner.customOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+	runner.customOptions.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+	runner.classLibraries = this.LIBS;
+	runner.testFiles = new String[] {
+		"X.java",
+		"import org.eclipse.jdt.annotation.*;\n" +
+		"import java.util.function.*;\n" +
+		"interface IN0 {}\n" + 
+		"interface IN1 extends IN0 {}\n" + 
+		"interface IN2 extends IN0 {}\n" +
+		"public class X {\n" +
+		"	@NonNull IN1 n1() { return new IN1() {}; }\n" + 
+		"	IN2 n2() { return null; }\n" + 
+		"	<M> void m(@NonNull Supplier<@NonNull M> m2) { }\n" + 
+		"	void testSw(int i) {\n" + 
+		"		m(switch(i) {\n" + 
+		"			case 1 -> this::n1;\n" + 
+		"			case 2 -> () -> n1();\n" + 
+		"			case 3 -> null;\n" + 
+		"			case 4 -> () -> n2();\n" + 
+		"			default -> this::n2; });\n" + 
+		"	}\n" +
+		"}\n"
+	};
+	runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. ERROR in X.java (at line 14)\n" + 
+			"	case 3 -> null;\n" + 
+			"	          ^^^^\n" + 
+			"Null type mismatch: required \'@NonNull Supplier<@NonNull IN0>\' but the provided value is null\n" + 
+			"----------\n" + 
+			"2. WARNING in X.java (at line 15)\n" + 
+			"	case 4 -> () -> n2();\n" + 
+			"	                ^^^^\n" + 
+			"Null type safety (type annotations): The expression of type \'IN2\' needs unchecked conversion to conform to \'@NonNull IN0\'\n" + 
+			"----------\n" + 
+			"3. WARNING in X.java (at line 16)\n" + 
+			"	default -> this::n2; });\n" + 
+			"	           ^^^^^^^^\n" + 
+			"Null type safety at method return type: Method descriptor Supplier<IN0>.get() promises \'@NonNull IN0\' but referenced method provides \'IN2\'\n" + 
+			"----------\n";
+	runner.runNegativeTest();
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
index 0d2d7a5..7169599 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2014 GK Software AG and others.
+ * Copyright (c) 2011, 2019 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     Nikolay Metchev (nikolaymetchev@gmail.com) - Contributions for
@@ -53,7 +57,7 @@
 	"}\n";
 
 static {
-//	TESTS_NAMES = new String[] { "testBug462371_shouldWarn" };
+//	TESTS_NAMES = new String[] { "testBug542707" };
 //	TESTS_NUMBERS = new int[] { 50 };
 //	TESTS_RANGE = new int[] { 11, -1 };
 }
@@ -5496,4 +5500,176 @@
 	};
 	runner.runConformTest();
 }
+public void testBug542707_001() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"import java.io.Closeable;\n"+
+			"import java.io.IOException;\n"+
+			"\n"+
+			"public class X implements Closeable{\n"+
+			"	public static int foo(int i) throws IOException {\n"+
+			"		int k = 0;\n"+
+			"		X x = null;\n"+
+			"		try {\n"+
+			"			x = new X();\n"+
+			"			x  = switch (i) { \n"+
+			"			  case 1  ->   {\n"+
+			"				 break x;\n"+
+			"			  }\n"+
+			"			  default -> x;\n"+
+			"			};\n"+
+			"		} finally {\n"+
+			"			x.close();\n"+
+			"		}\n"+
+			"		return k ;\n"+
+			"	}\n"+
+			"\n"+
+			"	public static void main(String[] args) {\n"+
+			"		try {\n"+
+			"			System.out.println(foo(3));\n"+
+			"		} catch (IOException e) {\n"+
+			"			// do nothing\n"+
+			"		}\n"+
+			"	}\n"+
+			"	@Override\n"+
+			"	public void close() throws IOException {\n"+
+			"		Zork();\n"+
+			"	}\n"+
+			"}\n"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 31)\n" + 
+		"	Zork();\n" + 
+		"	^^^^\n" + 
+		"The method Zork() is undefined for the type X\n" + 
+		"----------\n",
+		options);
+}
+public void testBug542707_002() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"import java.io.Closeable;\n"+
+			"import java.io.IOException;\n"+
+			"\n"+
+			"public class X implements Closeable{\n"+
+			"	public static int foo(int i) throws IOException {\n"+
+			"		int k = 0;\n"+
+			"		X x = null;\n"+
+			"		try {\n"+
+			"			x = new X();\n"+
+			"			x  = switch (i) { \n"+
+			"			  case 1  ->   {\n"+
+			"				 x = new X();\n"+
+			"				 break x;\n"+
+			"			  }\n"+
+			"			  default -> x;\n"+
+			"			};\n"+
+			"		} finally {\n"+
+			"			x.close();\n"+
+			"		}\n"+
+			"		return k ;\n"+
+			"	}\n"+
+			"\n"+
+			"	public static void main(String[] args) {\n"+
+			"		try {\n"+
+			"			System.out.println(foo(3));\n"+
+			"		} catch (IOException e) {\n"+
+			"			// do nothing\n"+
+			"		}\n"+
+			"	}\n"+
+			"	@Override\n"+
+			"	public void close() throws IOException {\n"+
+			"		Zork();\n"+
+			"	}\n"+
+			"}\n"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 12)\n" + 
+		"	x = new X();\n" + 
+		"	^^^^^^^^^^^\n" + 
+		"Resource leak: \'x\' is not closed at this location\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 32)\n" + 
+		"	Zork();\n" + 
+		"	^^^^\n" + 
+		"The method Zork() is undefined for the type X\n" + 
+		"----------\n",
+		options);
+}
+public void testBug542707_003() {
+	if (this.complianceLevel < ClassFileConstants.JDK12) return; // uses switch expression
+	Map options = getCompilerOptions();
+	options.put(JavaCore.COMPILER_PB_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(JavaCore.COMPILER_PB_POTENTIALLY_UNCLOSED_CLOSEABLE, CompilerOptions.ERROR);
+	options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+	options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+	runLeakTest(
+		new String[] {
+			"X.java",
+			"import java.io.Closeable;\n"+
+			"import java.io.IOException;\n"+
+			"\n"+
+			"public class X implements Closeable{\n"+
+			"	public static int foo(int i) throws IOException {\n"+
+			"		int k = 0;\n"+
+			"		X x = null;\n"+
+			"		try {\n"+
+			"			x = new X();\n"+
+			"			x  = switch (i) { \n"+
+			"			  case 1  ->   {\n"+
+			"				 break new X();\n"+
+			"			  }\n"+
+			"			  default -> x;\n"+
+			"			};\n"+
+			"		} finally {\n"+
+			"			x.close();\n"+
+			"		}\n"+
+			"		return k ;\n"+
+			"	}\n"+
+			"\n"+
+			"	public static void main(String[] args) {\n"+
+			"		try {\n"+
+			"			System.out.println(foo(3));\n"+
+			"		} catch (IOException e) {\n"+
+			"			// do nothing\n"+
+			"		}\n"+
+			"	}\n"+
+			"	@Override\n"+
+			"	public void close() throws IOException {\n"+
+			"		Zork();\n"+
+			"	}\n"+
+			"}\n"
+		},
+		"----------\n" +
+		"1. ERROR in X.java (at line 10)\n" + 
+		"	x  = switch (i) { \n" + 
+		"			  case 1  ->   {\n" + 
+		"				 break new X();\n" + 
+		"			  }\n" + 
+		"			  default -> x;\n" + 
+		"			};\n" + 
+		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+		"Resource leak: \'x\' is not closed at this location\n" + 
+		"----------\n" + 
+		"2. ERROR in X.java (at line 31)\n" + 
+		"	Zork();\n" + 
+		"	^^^^\n" + 
+		"The method Zork() is undefined for the type X\n" + 
+		"----------\n",
+		options);
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
new file mode 100644
index 0000000..b3cf798
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionTest.java
@@ -0,0 +1,2185 @@
+/*******************************************************************************
+ * Copyright (c) 2018, 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.util.Map;
+
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+import junit.framework.Test;
+
+public class SwitchExpressionTest extends AbstractRegressionTest {
+
+	static {
+//		TESTS_NUMBERS = new int [] { 40 };
+//		TESTS_NAMES = new String[] { "testBug543240_1" };
+	}
+	
+	public static Class<?> testClass() {
+		return SwitchExpressionTest.class;
+	}
+	public static Test suite() {
+		return buildMinimalComplianceTestSuite(testClass(), F_12);
+	}
+	public SwitchExpressionTest(String testName){
+		super(testName);
+	}
+
+	// Enables the tests to run individually
+	protected Map<String, String> getCompilerOptions() {
+		Map<String, String> defaultOptions = super.getCompilerOptions();
+		defaultOptions.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); // FIXME
+		defaultOptions.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+		defaultOptions.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+		defaultOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		defaultOptions.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		return defaultOptions;
+	}
+	
+	@Override
+	protected void runConformTest(String[] testFiles, Map customOptions) {
+		super.runConformTest(testFiles, "", null, true, new String[] {"--enable-preview"}, customOptions, null);
+	}
+
+	@Override
+	protected void runConformTest(String[] testFiles, String expectedOutput, Map customOptions) {
+		super.runConformTest(testFiles, expectedOutput, null, true, new String[] {"--enable-preview"}, customOptions, null);
+	}
+	public void testSimpleExpressions() {
+		runConformTest(
+				new String[] {
+						"X.java",
+						"public class X {\n" +
+						"	static int twice(int i) {\n" +
+						"		int tw = switch (i) {\n" +
+						"			case 0 -> i * 0;\n" +
+						"			case 1 -> 2;\n" +
+						"			default -> 3;\n" +
+						"		};\n" +
+						"		return tw;\n" +
+						"	}\n" +
+						"	public static void main(String... args) {\n" +
+						"		System.out.print(twice(3));\n" +
+						"	}\n" +
+						"}\n"
+				},
+				"3",
+				null,
+				new String[] {"--enable-preview"});
+	}
+	public void testSwitchExpression_531714_002() {
+		runConformTest(
+				new String[] {
+						"X.java",
+						"public class X {\n"+
+								"	static int twice(int i) throws Exception {\n"+
+								"		int tw = switch (i) {\n"+
+								"			case 0 -> 0;\n"+
+								"			case 1 -> { \n"+
+								"				System.out.println(\"do_not_print\");\n"+
+								"				break 1;\n"+
+								"			} \n"+
+								"			case 3 -> throw new Exception();\n"+
+								"			default -> throw new Exception();\n"+
+								"		};\n"+
+								"		return tw;\n"+
+								"	}\n"+
+								"	public static void main(String[] args) {\n"+
+								"		try {\n"+
+								"		    try {\n"+
+								"				System.out.print(twice(3));\n"+
+								"			} catch (Exception e) {\n"+
+								"				System.out.print(\"Got Exception - expected\");\n"+
+								"			}\n"+
+								"		} catch (Exception e) {\n"+
+								"		System.out.print(\"Got Exception\");\n"+
+								"		}\n"+
+								"	}\n"+
+								"}\n"
+				},
+				"Got Exception - expected",
+				null,
+				new String[] {"--enable-preview"});
+	}
+	public void testBug531714_error_003() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"  public static void main(String[] args) {\n" +
+				"    twice(1);\n" +
+				"  }\n" +
+				"	public static int twice(int i) {\n" +
+				"		int tw = switch (i) {\n" +
+				"		};\n" +
+				"		return tw;\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	int tw = switch (i) {\n" + 
+			"		};\n" + 
+			"	         ^^^^^^^^^^^^^^^^\n" + 
+			"A switch expression should have a non-empty switch block\n" + 
+			"----------\n" + 
+			"2. ERROR in X.java (at line 6)\n" + 
+			"	int tw = switch (i) {\n" + 
+			"	                 ^\n" + 
+			"A switch expression should have a default case\n" + 
+			"----------\n");
+	}
+	public void testBug531714_error_004() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"  public static void main(String[] args) {\n" +
+				"    twice(1);\n" +
+				"  }\n" +
+				"	public static int twice(int i) {\n" +
+				"		int tw = switch (i) {\n" +
+				"			case 0 -> 0;\n" +
+				"			case 1 -> { \n" +
+				"				System.out.println(\"heel\");\n" +
+				"				break 1;\n" +
+				"			} \n" +
+				"			case \"hello\" -> throw new java.io.IOException(\"hello\");\n" +
+				"			default -> throw new java.io.IOException(\"world\");\n" +
+				"		};\n" +
+				"		return tw;\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 12)\n" + 
+			"	case \"hello\" -> throw new java.io.IOException(\"hello\");\n" + 
+			"	     ^^^^^^^\n" + 
+			"Type mismatch: cannot convert from String to int\n" + 
+			"----------\n");
+	}
+	public void testBug531714_error_005() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"  public static void main(String[] args) {\n" +
+				"    twice(1);\n" +
+				"  }\n" +
+				"	public static int twice(int i) {\n" +
+				"		int tw = switch (i) {\n" +
+				"			case 0 -> 0;\n" +
+				"			case 1 -> { \n" +
+				"				System.out.println(\"heel\");\n" +
+				"				break 1;\n" +
+				"			} \n" +
+				"		    case 2 -> 2;\n" +
+				"		};\n" +
+				"		return tw;\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 6)\n" + 
+			"	int tw = switch (i) {\n" + 
+			"	                 ^\n" + 
+			"A switch expression should have a default case\n" + 
+			"----------\n");
+	}
+	/**
+	 * Add a test case for enum
+	 * If the type of the selector expression is an enum type, 
+	 * then the set of all the case constants associated with the switch block
+	 *  must contain all the enum constants of that enum type
+	 *  Add a missing enum test case
+	 */
+	public void _testBug531714_error_006() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"  public static void main(String[] args) {\n" +
+				"    int x, y;\n" +
+				"    I i = () -> {\n" +
+				"      int z = 10;\n" +
+				"    };\n" +
+				"    i++;\n" +
+				"  }\n" +
+				"	public static int twice(int i) {\n" +
+				"		int tw = switch (i) {\n" +
+				"			case 0 -> 0;\n" +
+				"			case 1 -> { \n" +
+				"				System.out.println(\"heel\");\n" +
+				"				break 1;\n" +
+				"			} \n" +
+				"		//	case 2 -> 2;\n" +
+				"			case \"hello\" -> throw new IOException(\"hello\");\n" +
+				"		};\n" +
+				"		return tw;\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 7)\n" + 
+			"	int tw = switch (i) {\n" + 
+			"	      ^^^^^\n" + 
+			" The switch expression should have a default case\n" + 
+			"----------\n");
+	}
+	/*
+	 * should compile - test for adding additional nesting in variables
+	 * dev note: ref consumeToken().case Switch 
+	 */
+	public void testBug531714_error_007() {
+		runConformTest(
+				new String[] {
+						"X.java",
+						"public class X {\n"+
+						"	static int foo(int i) {\n"+
+						"		int tw = \n"+
+						"		switch (i) {\n"+
+						"			case 1 -> \n"+
+						"			 {\n"+
+						" 				int z = 100;\n"+
+						" 				break z;\n"+
+						"			}\n"+
+						"			default -> {\n"+
+						"				break 12;\n"+
+						"			}\n"+
+						"		};\n"+
+						"		return tw;\n"+
+						"	}\n"+
+						"	public static void main(String[] args) {\n"+
+						"		System.out.print(foo(1));\n"+
+						"	}\n"+
+						"}\n"
+				},
+				"100",
+				null,
+				new String[] {"--enable-preview"});
+	}
+	public void testBug531714_008() {
+		Map<String, String> disablePreviewOptions = getCompilerOptions();
+		disablePreviewOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	static int twice(int i) {\n" +
+				"		int tw = switch (i) {\n" +
+				"			case 0 -> i * 0;\n" +
+				"			case 1 -> 2;\n" +
+				"			default -> 3;\n" +
+				"		};\n" +
+				"		return tw;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.print(twice(3));\n" +
+				"	}\n" +
+				"}\n",
+		};
+
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 3)\n" + 
+				"	int tw = switch (i) {\n" + 
+				"			case 0 -> i * 0;\n" + 
+				"			case 1 -> 2;\n" + 
+				"			default -> 3;\n" + 
+				"		};\n" + 
+				"	         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+				"Switch Expressions is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 4)\n" + 
+				"	case 0 -> i * 0;\n" + 
+				"	^^^^^^\n" + 
+				"Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n" + 
+				"3. ERROR in X.java (at line 5)\n" + 
+				"	case 1 -> 2;\n" + 
+				"	^^^^^^\n" + 
+				"Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n" + 
+				"4. ERROR in X.java (at line 6)\n" + 
+				"	default -> 3;\n" + 
+				"	^^^^^^^\n" + 
+				"Case Labels with '->' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n";
+
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				disablePreviewOptions);
+	}
+	public void testBug543667_001() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"\n" +
+				"	public static void bar(int  i) {\n" +
+				"		switch (i) {\n" +
+				"		case 1 -> System.out.println(\"hello\");\n" +
+				"		default -> System.out.println(\"DEFAULT\");\n" +
+				"		}\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		bar(1);\n" +
+				"	}\n" +
+				"}\n"
+			},
+			"hello",
+			null,
+			false,
+			new String[] { "--enable-preview"});
+	}
+	public void testBug531714_009() {
+		Map<String, String> disablePreviewOptions = getCompilerOptions();
+		disablePreviewOptions.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.DISABLED);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	static int twice(int i) {\n" +
+				"		switch (i) {\n" +
+				"			case 0 -> i * 0;\n" +
+				"			case 1 -> 2;\n" +
+				"			default -> 3;\n" +
+				"		}\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.print(twice(3));\n" +
+				"	}\n" +
+				"}\n",
+		};
+
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	case 0 -> i * 0;\n" + 
+				"	^^^^^^\n" + 
+				"Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 5)\n" + 
+				"	case 1 -> 2;\n" + 
+				"	^^^^^^\n" + 
+				"Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n" + 
+				"3. ERROR in X.java (at line 6)\n" + 
+				"	default -> 3;\n" + 
+				"	^^^^^^^\n" + 
+				"Case Labels with \'->\' is a preview feature and disabled by default. Use --enable-preview to enable\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				disablePreviewOptions);
+	}
+	public void testBug531714_010() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.ERROR);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	static int twice(int i) {\n" +
+				"		switch (i) {\n" +
+				"			default -> 3;\n" +
+				"		}\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.print(twice(3));\n" +
+				"	}\n" +
+				"}\n",
+		};
+
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	default -> 3;\n" + 
+				"	^^^^^^^\n" + 
+				"You are using a preview language feature that may or may not be supported in a future release\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 4)\n" + 
+				"	default -> 3;\n" + 
+				"	           ^\n" + 
+				"Invalid expression as statement\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	public void testBug531714_011() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.WARNING);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	@SuppressWarnings(\"preview\")\n" +
+				"	static int twice(int i) {\n" +
+				"		switch (i) {\n" +
+				"			default -> 3;\n" +
+				"		}\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.print(twice(3));\n" +
+				"	}\n" +
+				"}\n",
+		};
+
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 5)\n" + 
+				"	default -> 3;\n" + 
+				"	           ^\n" + 
+				"Invalid expression as statement\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				getCompilerOptions());
+	}
+	public void testBug531714_012() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.WARNING);
+		String release = options.get(CompilerOptions.OPTION_Release);
+		options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
+		try {
+			String[] testFiles = new String[] {
+					"X.java",
+					"public class X {\n" +
+					"	static int twice(int i) {\n" +
+					"		switch (i) {\n" +
+					"			default -> 3;\n" +
+					"		}\n" +
+					"		return 0;\n" +
+					"	}\n" +
+					"	public static void main(String[] args) {\n" +
+					"		System.out.print(twice(3));\n" +
+					"	}\n" +
+					"}\n",
+			};
+
+			String expectedProblemLog =
+					"----------\n" + 
+					"1. ERROR in X.java (at line 4)\n" + 
+					"	default -> 3;\n" + 
+					"	^^^^^^^\n" + 
+					"The preview feature Case Labels with \'->\' is only available with source level 12 and above\n" + 
+					"----------\n" + 
+					"2. ERROR in X.java (at line 4)\n" + 
+					"	default -> 3;\n" + 
+					"	           ^\n" + 
+					"Invalid expression as statement\n" + 
+					"----------\n";
+			this.runNegativeTest(
+					testFiles,
+					expectedProblemLog,
+					null,
+					true,
+					options);
+		} finally {
+			options.put(CompilerOptions.OPTION_Source, release);
+		}
+	}
+	public void testBug531714_013() {
+			String[] testFiles = new String[] {
+					"X.java",
+					"public class X {\n" +
+					"	public static int foo(int i) {\n" +
+					"		int v;\n" +
+					"		int t = switch (i) {\n" +
+					"		case 0 : {\n" +
+					"			break 0;\n" +
+					"		}\n" +
+					"		default :v = 2;\n" +
+					"		};\n" +
+					"		return t;\n" +
+					"	}\n" +
+					"	\n" +
+					"	public boolean bar() {\n" +
+					"		return true;\n" +
+					"	}\n" +
+					"	public static void main(String[] args) {\n" +
+					"		System.out.println(foo(3));\n" +
+					"	}\n" +
+					"}\n",
+			};
+
+			String expectedProblemLog =
+					"----------\n" + 
+					"1. ERROR in X.java (at line 8)\n" + 
+					"	default :v = 2;\n" + 
+					"	         ^^^^^\n" + 
+					"A switch labeled block in a switch expression should not complete normally\n" + 
+					"----------\n";
+			this.runNegativeTest(
+					testFiles,
+					expectedProblemLog,
+					null,
+					true,
+					getCompilerOptions());
+	}
+	public void testBug531714_014() {
+		// switch expression is not a Primary
+		Runner runner = new Runner();
+		runner.customOptions = getCompilerOptions();
+		runner.testFiles = new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	void test(int i) {\n" +
+			"		System.out.println(switch (i) {\n" +
+			"			case 1 -> \"one\";\n" +
+			"			default -> null;\n" +
+			"		}.toLowerCase());\n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		new X().test(1);\n" +
+			"	}\n" +
+			"}\n"
+		};
+		runner.expectedCompilerLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 6)\n" + 
+				"	}.toLowerCase());\n" + 
+				"	 ^\n" + 
+				"Syntax error on token \".\", , expected\n" + 
+				"----------\n";
+		runner.runNegativeTest();
+	}
+	public void testBug543673_001() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	public static int foo(Day day) {\n" +
+				"\n" +
+				"		var len= switch (day) {\n" +
+				"			case SUNDAY-> 6;\n" +
+				"			default -> 10;\n" +
+				"		};\n" +
+				"\n" +
+				"		return len;\n" +
+				"	}\n" +
+				"\n" +
+				"	public static void main(String[] args) {\n" +
+				"		System.out.println(foo(Day.SUNDAY));\n" +
+				"	}\n" +
+				"}\n" +
+				"enum Day {\n" +
+				"	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" +
+				"}\n"
+			},
+			"6",
+			null,
+			false,
+			new String[] { "--enable-preview"});
+	}
+	/*
+	 * A simple multi constant case statement, compiled and run as expected
+	 */
+	public void testBug543240_1() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		case MONDAY : System.out.println(Day.MONDAY);\n" + 
+						"					break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"	public static void main(String[] args) {\n" +
+						"		bar(Day.SATURDAY);\n" +
+						"	}\n" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY;}",
+		};
+
+		String expectedProblemLog =
+				"SUNDAY";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] { "--enable-preview"});
+	}
+	/*
+	 * A simple multi constant case statement, compiler reports missing enum constants
+	 */
+	public void testBug543240_1a() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"	public static void main(String[] args) {\n" + 
+						"	}\n" + 
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		case MONDAY : System.out.println(Day.MONDAY);\n" + 
+						"					break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY, TUESDAY;}",
+		};
+
+		String expectedProblemLog =
+						"----------\n" + 
+						"1. WARNING in X.java (at line 5)\n" + 
+						"	switch (day) {\n" + 
+						"	        ^^^\n" + 
+						"The enum constant TUESDAY needs a corresponding case label in this enum switch on Day\n" + 
+						"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	/*
+	 * A simple multi constant case statement with duplicate enums
+	 */
+	public void testBug543240_2() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		case SUNDAY : System.out.println(Day.SUNDAY);\n" + 
+						"					break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"	public static void main(String[] args) {\n" +
+						"		bar(Day.SATURDAY);\n" +
+						"	}\n" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY;}",
+		};
+
+		String expectedProblemLog =
+						"----------\n" + 
+						"1. ERROR in X.java (at line 7)\n" + 
+						"	case SUNDAY : System.out.println(Day.SUNDAY);\n" + 
+						"	^^^^^^^^^^^\n" + 
+						"Duplicate case\n" + 
+						"----------\n" + 
+						"2. ERROR in X.java (at line 7)\n" + 
+						"	case SUNDAY : System.out.println(Day.SUNDAY);\n" + 
+						"	^^^^^^^^^^^\n" + 
+						"Duplicate case\n" + 
+						"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	/*
+	 * A simple multi constant case statement with duplicate enums
+	 */
+	public void testBug543240_2a() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		case SUNDAY, SATURDAY : \n" +
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY;}",
+		};
+
+		String expectedProblemLog =
+						"----------\n" + 
+						"1. WARNING in X.java (at line 3)\n" + 
+						"	switch (day) {\n" + 
+						"	        ^^^\n" + 
+						"The enum constant MONDAY needs a corresponding case label in this enum switch on Day\n" + 
+						"----------\n" + 
+						"2. ERROR in X.java (at line 7)\n" + 
+						"	case SUNDAY, SATURDAY : \n" + 
+						"	^^^^^^^^^^^^^^^^^^^^^\n" + 
+						"Duplicate case\n" + 
+						"----------\n" + 
+						"3. ERROR in X.java (at line 7)\n" + 
+						"	case SUNDAY, SATURDAY : \n" + 
+						"	^^^^^^^^^^^^^^^^^^^^^\n" + 
+						"Duplicate case\n" + 
+						"----------\n" + 
+						"4. ERROR in X.java (at line 7)\n" + 
+						"	case SUNDAY, SATURDAY : \n" + 
+						"	^^^^^^^^^^^^^^^^^^^^^\n" + 
+						"Duplicate case\n" + 
+						"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	/*
+	 * 
+	 */
+	public void testBug543240_3() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(Day.SUNDAY);\n" + 
+						"			break;\n" + 
+						"		case TUESDAY : System.out.println(Day.SUNDAY);\n" + 
+						"					break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"	public static void main(String[] args) {\n" +
+						"		bar(Day.SATURDAY);\n" +
+						"	}\n" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY, TUESDAY;}",
+		};
+
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. WARNING in X.java (at line 3)\n" + 
+				"	switch (day) {\n" + 
+				"	        ^^^\n" + 
+				"The enum constant MONDAY needs a corresponding case label in this enum switch on Day\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] {"--enable-preview"},
+				options);
+	}
+	public void testBug543240_4() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+						"public static void bar(Day day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY: \n" + 
+						"			System.out.println(day);\n" + 
+						"			break;\n" + 
+						"		case MONDAY : System.out.println(0);\n" + 
+						"					break;\n" + 
+						"		}\n" + 
+						"	}" +
+						"	public static void main(String[] args) {\n" +
+						"		bar(Day.SATURDAY);\n" +
+						"		bar(Day.MONDAY);\n" +
+						"		bar(Day.SUNDAY);\n" +
+						"	}\n" +
+						"}\n" +
+						"enum Day { SATURDAY, SUNDAY, MONDAY;}",
+		};
+
+		String expectedProblemLog =
+				"SATURDAY\n" + 
+				"0\n" + 
+				"SUNDAY";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] {"--enable-preview"});
+	}
+	/*
+	 * Simple switch case with string literals
+	 */
+	public void testBug543240_5() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(\"a\");\n" + 
+						"		bar(\"b\");\n" + 
+						"		bar(\"c\");\n" + 
+						"		bar(\"d\");\n" + 
+						"	}\n" + 
+						"	public static void bar(String s) {\n" + 
+						"		switch(s) {\n" + 
+						"		case \"a\":\n" + 
+						"		case \"b\":\n" + 
+						"			System.out.println(\"A/B\");\n" + 
+						"			break;\n" + 
+						"		case \"c\":\n" + 
+						"			System.out.println(\"C\");\n" + 
+						"			break;\n" + 
+						"		default:\n" + 
+						"			System.out.println(\"NA\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"A/B\n" + 
+				"A/B\n" + 
+				"C\n" + 
+				"NA";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] {"--enable-preview"});
+	}
+	public void testBug543240_6() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(\"a\");\n" + 
+						"		bar(\"b\");\n" + 
+						"		bar(\"c\");\n" + 
+						"		bar(\"d\");\n" + 
+						"	}\n" + 
+						"	public static void bar(String s) {\n" + 
+						"		switch(s) {\n" + 
+						"		case \"a\", \"b\":\n" + 
+						"			System.out.println(\"A/B\");\n" + 
+						"			break;\n" + 
+						"		case \"c\":\n" + 
+						"			System.out.println(\"C\");\n" + 
+						"			break;\n" + 
+						"		default:\n" + 
+						"			System.out.println(\"NA\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"A/B\n" + 
+				"A/B\n" + 
+				"C\n" + 
+				"NA";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] {"--enable-preview"});
+	}
+	/*
+	 * Switch with multi constant case statements with string literals
+	 * two string literals with same hashcode
+	 */
+	public void testBug543240_7() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(\"FB\");\n" + 
+						"		bar(\"Ea\");\n" + 
+						"		bar(\"c\");\n" + 
+						"		bar(\"D\");\n" + 
+						"	}\n" + 
+						"	public static void bar(String s) {\n" + 
+						"		switch(s) {\n" + 
+						"		case \"FB\", \"c\":\n" + 
+						"			System.out.println(\"A\");\n" + 
+						"			break;\n" + 
+						"		case \"Ea\":\n" + 
+						"			System.out.println(\"B\");\n" + 
+						"			break;\n" + 
+						"		default:\n" + 
+						"			System.out.println(\"NA\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"A\n" + 
+				"B\n" + 
+				"A\n" + 
+				"NA";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] {"--enable-preview"});
+	}
+	/*
+	 * Switch with multi constant case statements with integer constants
+	 */
+	public void testBug543240_8() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(1);\n" + 
+						"		bar(2);\n" + 
+						"		bar(3);\n" + 
+						"		bar(4);\n" + 
+						"		bar(5);\n" + 
+						"	}\n" + 
+						"	public static void bar(int i) {\n" + 
+						"		switch (i) {\n" + 
+						"		case 1, 3: \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"			break;\n" + 
+						"		case 2, 4: \n" + 
+						"			System.out.println(\"Even\");\n" + 
+						"			break;\n" + 
+						"		default:\n" + 
+						"			System.out.println(\"Out of range\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"Odd\n" + 
+				"Even\n" + 
+				"Odd\n" + 
+				"Even\n" + 
+				"Out of range";
+		this.runConformTest(
+				testFiles,
+				expectedProblemLog,
+				options,
+				new String[] {"--enable-preview"});
+	}
+	/*
+	 * Switch multi-constant with mixed constant types, reported
+	 */
+	public void testBug543240_9() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"	}\n" + 
+						"	public static void bar(int i) {\n" + 
+						"		switch (i) {\n" + 
+						"		case 1, 3: \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"			break;\n" + 
+						"		case \"2\": \n" + 
+						"			System.out.println(\"Even\");\n" + 
+						"			break;\n" + 
+						"		default:\n" + 
+						"				System.out.println(\"Out of range\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 9)\n" + 
+				"	case \"2\": \n" + 
+				"	     ^^^\n" + 
+				"Type mismatch: cannot convert from String to int\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	/*
+	 * Switch multi-constant without break statement, reported
+	 */
+	public void testBug543240_10() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		options.put(CompilerOptions.OPTION_ReportFallthroughCase, CompilerOptions.WARNING);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"	}\n" + 
+				"	public static void bar(int i) {\n" + 
+				"		switch (i) {\n" + 
+				"		case 1, 3: \n" + 
+				"			System.out.println(\"Odd\");\n" + 
+				"		case 2, 4: \n" + 
+				"			System.out.println(\"Even\");\n" + 
+				"			break;\n" +
+				"		default:\n" + 
+				"				System.out.println(\"Out of range\");\n" + 
+				"		}\n" + 
+				"	}\n" + 
+				"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. WARNING in X.java (at line 8)\n" + 
+				"	case 2, 4: \n" + 
+				"	^^^^^^^^^\n" + 
+				"Switch case may be entered by falling through previous case. If intended, add a new comment //$FALL-THROUGH$ on the line above\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	/*
+	 * Switch multi-constant without break statement, reported
+	 */
+	public void testBug543240_11() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		options.put(CompilerOptions.OPTION_ReportMissingDefaultCase, CompilerOptions.WARNING);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"	}\n" + 
+				"	public static void bar(int i) {\n" + 
+				"		switch (i) {\n" + 
+				"		case 1, 3: \n" + 
+				"			System.out.println(\"Odd\");\n" + 
+				"		case 2, 4: \n" + 
+				"			System.out.println(\"Even\");\n" + 
+				"		}\n" + 
+				"	}\n" + 
+				"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. WARNING in X.java (at line 5)\n" + 
+				"	switch (i) {\n" + 
+				"	        ^\n" + 
+				"The switch statement should have a default case\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	/*
+	 * Switch multi-constant with duplicate int constants
+	 */
+	public void testBug543240_12() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"	}\n" + 
+						"	public static void bar(int i) {\n" + 
+						"		switch (i) {\n" + 
+						"		case 1, 3: \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"		case 3, 4: \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 8)\n" + 
+				"	case 3, 4: \n" + 
+				"	^^^^^^^^^\n" + 
+				"Duplicate case\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 8)\n" + 
+				"	case 3, 4: \n" + 
+				"	^^^^^^^^^\n" + 
+				"Duplicate case\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	/*
+	 * Switch multi-constant with duplicate String literals
+	 */
+	public void testBug543240_13() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"	}\n" + 
+						"	public static void bar(String s) {\n" + 
+						"		switch (s) {\n" + 
+						"		case \"a\", \"b\": \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"		case \"b\", \"c\": \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 8)\n" + 
+				"	case \"b\", \"c\": \n" + 
+				"	^^^^^^^^^^^^^\n" + 
+				"Duplicate case\n" + 
+				"----------\n" + 
+				"2. ERROR in X.java (at line 8)\n" + 
+				"	case \"b\", \"c\": \n" + 
+				"	^^^^^^^^^^^^^\n" + 
+				"Duplicate case\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	/*
+	 * Switch multi-constant with illegal qualified enum constant
+	 */
+	public void testBug543240_14() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"	}\n" + 
+						"	public static void bar(Num s) {\n" + 
+						"		switch (s) {\n" + 
+						"		case ONE, Num.TWO: \n" + 
+						"			System.out.println(\"Odd\");\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"}\n" +
+						"enum Num { ONE, TWO}\n",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 6)\n" + 
+				"	case ONE, Num.TWO: \n" + 
+				"	          ^^^^^^^\n" + 
+				"The qualified case label Num.TWO must be replaced with the unqualified enum constant TWO\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	public void testBug543240_15() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	public void bar(int s) {\n" + 
+				"		int j = switch (s) {\n" + 
+				"			case 1, 2, 3 -> (s+1);\n" +
+				"			default -> j;\n" + 
+				"		};\n" + 
+				"	}\n" + 
+				"}\n",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 5)\n" + 
+				"	default -> j;\n" + 
+				"	           ^\n" + 
+				"The local variable j may not have been initialized\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	public void testBug543240_16() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"	}\n" + 
+				"	public void bar(int s) {\n" +
+				"		int j = 0;" + 
+				"		j = switch (s) {\n" + 
+				"			case 1, 2, 3 -> (s+1);\n" +
+				"			default -> j;\n" + 
+				"		};\n" + 
+				"	}\n" + 
+				"}\n",
+		};
+		this.runNegativeTest(
+				testFiles,
+				"",
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	public void testBug543795_01() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"import java.io.IOException;\n" +
+				"\n" +
+				"public class X {\n" +
+				"	public static int foo(int i) throws IOException {\n" +
+				"		int t = switch (i) {\n" +
+				"		case 0 : {\n" +
+				"			break 0;\n" +
+				"		}\n" +
+				"		case 2 : {\n" +
+				"			break;\n" +
+				"		}\n" +
+				"		default : break 10;\n" +
+				"		};\n" +
+				"		return t;\n" +
+				"	}\n" +
+				"	\n" +
+				"	public boolean bar() {\n" +
+				"		return true;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		try {\n" +
+				"			System.out.println(foo(3));\n" +
+				"		} catch (IOException e) {\n" +
+				"			// TODO Auto-generated catch block\n" +
+				"			e.printStackTrace();\n" +
+				"		}\n" +
+				"	}\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 10)\n" + 
+			"	break;\n" + 
+			"	^^^^^^\n" + 
+			"Break of a switch expression should have a value\n" + 
+			"----------\n");
+	}
+	public void testBug543691() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	@SuppressWarnings(\"preview\")\n" + 
+				"	public static void bar(int  i) {\n" + 
+				"		i = switch (i+0) {\n" + 
+				"			default: System.out.println(0);\n" + 
+				"		}; " + 
+				"	}\n" + 
+				"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	i = switch (i+0) {\n" + 
+				"			default: System.out.println(0);\n" + 
+				"		}; 	}\n" + 
+				"	    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
+				"A switch expression should have at least one result expression\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				options);
+	}
+	public void testBug543799_1() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	void test(int i) {\n" + 
+			"		need(switch (i) {\n" + 
+			"			case 1 -> \"\";\n" + 
+			"			default -> i == 3 ? null : \"\";\n" + 
+			"		}); \n" + 
+			"	}\n" + 
+			"	void need(String s) {\n" + 
+			"		System.out.println(s.toLowerCase());\n" + 
+			"	}\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		new X().need(\"Hello World\");\n" + 
+			"	}\n" + 
+			"}\n"
+		};
+		String expectedOutput = "hello world";
+		runConformTest(testFiles, expectedOutput, options);
+	}
+	public void testBug543799_2() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+			"X.java",
+			"public class X {\n" +
+			"	void test(int i) {\n" + 
+			"		need(switch (i) {\n" + 
+			"			case 1: break \"\";\n" + 
+			"			default: break i == 3 ? null : \"\";\n" + 
+			"		}); \n" + 
+			"	}\n" + 
+			"	void need(String s) {\n" + 
+			"		System.out.println(s.toLowerCase());\n" + 
+			"	}\n" +
+			"	public static void main(String[] args) {\n" + 
+			"		new X().need(\"Hello World\");\n" + 
+			"	}\n" + 
+			"}\n"
+		};
+		String expectedOutput = "hello world";
+		runConformTest(testFiles, expectedOutput, options);
+	}
+	public void testBug543799_3() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+			"X.java",
+			"interface I0 { void i(); }\n" + 
+			"interface I1 extends I0 {}\n" + 
+			"interface I2 extends I0 {}\n" +
+			"public class X {\n" +
+			"	I1 n1() { return null; }\n" + 
+			"	<I extends I2> I n2() { return null; }\n" + 
+			"	<M> M m(M m) { return m; }\n" + 
+			"	void test(int i, boolean b) {\n" + 
+			"		m(switch (i) {\n" + 
+			"			case 1 -> n1();\n" + 
+			"			default -> b ? n1() : n2();\n" + 
+			"		}).i(); \n" + 
+			"	}\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		try {\n" +
+			"			new X().test(1, true);\n" +
+			"		} catch (NullPointerException e) {\n" +
+			"			System.out.println(\"NPE as expected\");\n" +
+			"		}\n" +
+			"	}\n" + 
+			"}\n"
+		};
+		String expectedOutput = "NPE as expected";
+		runConformTest(testFiles, expectedOutput, options);
+	}
+	public void testBug543799_4() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+			"X.java",
+			"import java.util.function.Supplier;\n" +
+			"interface I0 { void i(); }\n" + 
+			"interface I1 extends I0 {}\n" + 
+			"interface I2 extends I0 {}\n" +
+			"public class X {\n" +
+			"	I1 n1() { return null; }\n" + 
+			"	<I extends I2> I n2() { return null; }\n" + 
+			"	<M> M m(Supplier<M> m) { return m.get(); }\n" + 
+			"	void test(int i, boolean b) {\n" + 
+			"		m(switch (i) {\n" + 
+			"			case 1 -> this::n1;\n" + 
+			"			default -> this::n2;\n" + 
+			"		}).i(); \n" + 
+			"	}\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		try {\n" +
+			"			new X().test(1, true);\n" +
+			"		} catch (NullPointerException e) {\n" +
+			"			System.out.println(\"NPE as expected\");\n" +
+			"		}\n" +
+			"	}\n" + 
+			"}\n"
+		};
+		String expectedOutput = "NPE as expected";
+		runConformTest(testFiles, expectedOutput, options);
+	}
+	public void testBug543799_5() {
+		// require resolving/inferring of poly-switch-expression during ASTNode.resolvePolyExpressionArguments()
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+			"X.java",
+			"public class X {\n" +
+			"		void test(int i) {\n" + 
+			"		need(switch (i) {\n" + 
+			"			case 1 -> 1.0f;\n" + 
+			"			default -> i == 3 ? 3 : 5.0d;\n" + 
+			"		}); \n" + 
+			"	}\n" + 
+			"	<N extends Number> void need(N s) {\n" + 
+			"		System.out.println(s.toString());\n" + 
+			"	}\n" + 
+			"	public static void main(String[] args) {\n" + 
+			"		new X().need(3);\n" +
+			"	}\n" + 
+			"}\n"
+		};
+		String expectedOutput = "3";
+		runConformTest(testFiles, expectedOutput, options);
+	}
+	public void testSwitchStatementWithBreakExpression() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	static int twice(int i) throws Exception {\n" + 
+					"		switch (i) {\n" + 
+					"			case 0 -> System.out.println(\"hellow\");\n" + 
+					"			case 1 -> foo();\n" + 
+					"			default -> throw new Exception();\n" + 
+					"		};\n" + 
+					"		return 0;\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	static int foo() {\n" + 
+					"		System.out.println(\"inside foo\");\n" + 
+					"		return 1;\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		try {\n" + 
+					"			System.out.print(twice(1));\n" + 
+					"		} catch (Exception e) {\n" + 
+					"			System.out.print(\"Got Exception\");\n" + 
+					"		}\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"inside foo\n"
+			+ "0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testSwitchStatementWithEnumValues() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"enum SomeDays {\n" + 
+					"	Mon, Wed, Fri\n" + 
+					"}\n" + 
+					"\n" + 
+					"public class X {\n" + 
+					"	int testEnum(boolean b) {\n" + 
+					"		SomeDays day = b ? SomeDays.Mon : null;\n" + 
+					"		return switch(day) {\n" + 
+					"			case Mon -> 1;\n" + 
+					"			case Wed -> 2;\n" + 
+					"			case Fri -> 3;\n" + 
+					"		};\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		System.out.println(new X().testEnum(true));\n" + 
+					"	}\n" + 
+					"}\n" + 
+					""
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug543967_01() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	static int foo(int i) {\n" +
+				"		switch (i) {\n" +
+				"			default -> 3; // should flag an error\n" +
+				"			\n" +
+				"		};\n" +
+				"		return 0;\n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		foo(1);\n" +
+				"	}\n" +
+				"}\n",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	default -> 3; // should flag an error\n" + 
+				"	           ^\n" + 
+				"Invalid expression as statement\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	public void testBug544204() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public void foo(int i) {\n" + 
+					"		int j = switch (i) {\n" + 
+					"			case 1 -> i;\n" + 
+					"			default -> i;\n" + 
+					"		};\n" + 
+					"		System.out.println(j);\n" + 
+					"	}\n" + 
+					"	\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		new X().foo(1);\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544204_2() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public void foo(int i) {\n" + 
+					"		long j = switch (i) {\n" + 
+					"			case 1 -> 10L;\n" + 
+					"			default -> 20L;\n" + 
+					"		};\n" + 
+					"		System.out.println(j);\n" + 
+					"	}\n" + 
+					"	\n" + 
+					"	public static void main(String[] args) {\n" + 
+					"		new X().foo(1);\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"10",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544223() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public int foo(String s) throws Exception {\n" + 
+					"		int i = switch (s) {\n" + 
+					"			case \"hello\" -> 1;\n" + 
+					"			default -> throw new Exception();\n" + 
+					"		};\n" + 
+					"		return i;\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		try {\n" + 
+					"			System.out.print(new X().foo(\"hello\"));\n" + 
+					"		} catch (Exception e) {\n" + 
+					"			//\n" + 
+					"		}\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544258_01() {
+		this.runNegativeTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"    public void foo(Day day) {\n" +
+				"    	var today = 1;\n" +
+				"    	today =  switch (day) {\n" +
+				"    		      case SATURDAY,SUNDAY :\n" +
+				"    		         today=1;\n" +
+				"    		         break today;\n" +
+				"    		      case MONDAY,TUESDAY,WEDNESDAY,THURSDAY :\n" +
+				"    			 today=2;\n" +
+				"    			 break today;\n" +
+				"    		};\n" +
+				"    }\n" +
+				"    public static void main(String argv[]) {\n" +
+				"    	new X().foo(Day.FRIDAY);\n" +
+				"    }\n" +
+				"}\n" +
+				"\n" +
+				"enum Day {\n" +
+				"	SUNDAY,\n" +
+				"	MONDAY,\n" +
+				"	TUESDAY,\n" +
+				"	WEDNESDAY,\n" +
+				"	THURSDAY,\n" +
+				"	FRIDAY,\n" +
+				"	SATURDAY\n" +
+				"}\n",
+			},
+			"----------\n" + 
+			"1. ERROR in X.java (at line 4)\n" + 
+			"	today =  switch (day) {\n" + 
+			"	                 ^^^\n" + 
+			"A Switch expression should cover all possible values\n" + 
+			"----------\n");
+	}
+	public void testBug544253() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"    public void foo(int i ) {\n" + 
+					"        boolean b = switch (i) {\n" + 
+					"            case 0 -> i == 1;\n" + 
+					"            default -> true;\n" + 
+					"        };\n" + 
+					"        System.out.println( b ? \" true\" : \"false\");\n" + 
+					"    }\n" + 
+					"    public static void main(String[] argv) {\n" + 
+					"    	new X().foo(0);\n" + 
+					"    }\n" + 
+					"}"
+			},
+			"false",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544254() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"    public void foo(String s) {\n" + 
+					"        try {\n" + 
+					"            int i = switch (s) {\n" + 
+					"                case \"hello\" -> 0;\n" + 
+					"                default -> 2;\n" + 
+					"            };\n" + 
+					"        } finally {\n" + 
+					"        	System.out.println(s);\n" + 
+					"        }\n" + 
+					"    }\n" + 
+					"    public static void main(String argv[]) {\n" + 
+					"    	new X().foo(\"hello\");\n" + 
+					"    }\n" + 
+					"}"
+			},
+			"hello",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544254_2() {
+		Map<String, String> customOptions = getCompilerOptions();
+		customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT);
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"    public void foo(String s) {\n" + 
+					"        try {\n" + 
+					"            int i = switch (s) {\n" + 
+					"                case \"hello\" -> 0;\n" + 
+					"                default -> 2;\n" + 
+					"            };\n" + 
+					"        } finally {\n" + 
+					"        	System.out.println(s);\n" + 
+					"        }\n" + 
+					"    }\n" + 
+					"    public static void main(String argv[]) {\n" + 
+					"    	new X().foo(\"hello\");\n" + 
+					"    }\n" + 
+					"}"
+			},
+			"hello",
+			customOptions,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544254_3() {
+		Map<String, String> customOptions = getCompilerOptions();
+		customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT);
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"    public void foo(String s) {\n" + 
+					"        try {\n" + 
+					"            long l = switch (s) {\n" + 
+					"                case \"hello\" -> 0;\n" + 
+					"                default -> 2;\n" + 
+					"            };\n" + 
+					"        } finally {\n" + 
+					"        	System.out.println(s);\n" + 
+					"        }\n" + 
+					"    }\n" + 
+					"    public static void main(String argv[]) {\n" + 
+					"    	new X().foo(\"hello\");\n" + 
+					"    }\n" + 
+					"}"
+			},
+			"hello",
+			customOptions,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544224_1() {
+		Map<String, String> customOptions = getCompilerOptions();
+		customOptions.put(CompilerOptions.OPTION_PreserveUnusedLocal, CompilerOptions.OPTIMIZE_OUT);
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" +
+					"    public int foo(int i)  {\n" +
+					"        int j = (switch (i) {\n" +
+					"            case 1 -> 1;\n" +
+					"            default -> 2;\n" +
+					"        });\n" +
+					"        return j;\n" +
+					"    }\n" +
+					"    public static void main(String[] argv) {\n" +
+					"    	new X().foo(1);\n" +
+					"    }\n" +
+					"}\n"
+			},
+			"",
+			customOptions,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544298() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	enum MyEnum {\n" + 
+					"		FIRST;\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public void foo(MyEnum myEnum) {\n" + 
+					"		int i = switch (myEnum) {\n" + 
+					"			case FIRST ->  1;\n" + 
+					"		};\n" + 
+					"			System.out.println( \"i:\" + i);\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public static void main(String argv[]) {\n" + 
+					"		new X().foo(MyEnum.FIRST);\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"i:1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544298_2() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	enum MyEnum {\n" + 
+					"		FIRST;\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public void foo(MyEnum myEnum) {\n" + 
+					"		int i = switch (myEnum) {\n" + 
+					"			case FIRST ->  1;\n" + 
+					"			default ->  0;\n" + 
+					"		};\n" + 
+					"			System.out.println( \"i:\" + i);\n" + 
+					"	}\n" + 
+					"\n" + 
+					"	public static void main(String argv[]) {\n" + 
+					"		new X().foo(MyEnum.FIRST);\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"i:1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544428_01() {
+		Map<String, String> options = getCompilerOptions();
+		options.put(CompilerOptions.OPTION_EnablePreviews, CompilerOptions.ENABLED);
+		options.put(CompilerOptions.OPTION_ReportPreviewFeatures, CompilerOptions.IGNORE);
+		String[] testFiles = new String[] {
+				"X.java",
+				"public class X {\n" +
+				"    public int foo(int i) {\n" +
+				"    	var v = switch(i) {\n" +
+				"    	case 0 -> x;\n" +
+				"    	default -> 1;\n" +
+				"    	};\n" +
+				"    	return v;\n" +
+				"    }\n" +
+				"    public static void main(String[] argv) {\n" +
+				"       System.out.println(new X().foo(0));\n" +
+				"    }\n" +
+				"}",
+		};
+		String expectedProblemLog =
+				"----------\n" + 
+				"1. ERROR in X.java (at line 4)\n" + 
+				"	case 0 -> x;\n" + 
+				"	          ^\n" + 
+				"x cannot be resolved to a variable\n" + 
+				"----------\n";
+		this.runNegativeTest(
+				testFiles,
+				expectedProblemLog,
+				null,
+				true,
+				new String[] { "--enable-preview"},
+				options);
+	}
+	public void testBug544523_01() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" +
+					"    @SuppressWarnings(\"preview\")\n" +
+					"	public int foo(int i) {\n" +
+					"    	int v = switch(i) {\n" +
+					"    	case 0 -> switch(i) {\n" +
+					"    			case 0 -> 0;\n" +
+					"    			default -> 1;\n" +
+					"    		};\n" +
+					"    	default -> 1;\n" +
+					"    	};\n" +
+					"    	return v;\n" +
+					"    }\n" +
+					"    public static void main(String[] argv) {\n" +
+					"       System.out.println(new X().foo(0));\n" +
+					"    }\n" +
+					"}"
+			},
+			"0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544560_01() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" +
+					"    public int foo(int i) {\n" +
+					"    	@SuppressWarnings(\"preview\")\n" +
+					"    	int v = switch(switch(i) {\n" +
+					"        		default -> 1;\n" +
+					"        		}) {\n" +
+					"        	default -> 1;\n" +
+					"        };\n" +
+					"       return v;\n" +
+					"    }\n" +
+					"\n" +
+					"    public static void main(String[] argv) {\n" +
+					"       System.out.println(new X().foo(0));\n" +
+					"    }\n" +
+					"}\n"
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544458() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static int foo(int i) {\n" + 
+					"		boolean v = switch (i) {\n" + 
+					"			case 1: i = 10; break true;\n" + 
+					"			default: break false;\n" + 
+					"		};\n" + 
+					"		return v ? 0 : 1;\n" + 
+					"	}\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		System.out.println(X.foo(0));\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544458_2() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static int foo(int i) {\n" + 
+					"		boolean v = switch (i) {\n" + 
+					"			case 1: i++; break true;\n" + 
+					"			default: break false;\n" + 
+					"		};\n" + 
+					"		return v ? 0 : 1;\n" + 
+					"	}\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		System.out.println(X.foo(1));\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544458_3() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static int foo(int i) {\n" + 
+					"		boolean v = switch (i) {\n" + 
+					"			case 1: i+= 10; break true;\n" + 
+					"			default: break false;\n" + 
+					"		};\n" + 
+					"		return v ? 0 : 1;\n" + 
+					"	}\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		System.out.println(X.foo(1));\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544458_4() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static int foo(int i) {\n" + 
+					"		boolean v = switch (i) {\n" + 
+					"			case 1: switch(i) {case 4: break;}; break true;\n" + 
+					"			default: break false;\n" + 
+					"		};\n" + 
+					"		return v ? 0 : 1;\n" + 
+					"	}\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		System.out.println(X.foo(1));\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544458_5() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" + 
+					"	public static int foo(int i) {\n" + 
+					"		boolean v = switch (i) {\n" + 
+					"			case 1: foo(5); break true;\n" + 
+					"			default: break false;\n" + 
+					"		};\n" + 
+					"		return v ? 0 : 1;\n" + 
+					"	}\n" + 
+					"	public static void main(String[] argv) {\n" + 
+					"		System.out.println(X.foo(1));\n" + 
+					"	}\n" + 
+					"}"
+			},
+			"0",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544601_1() {
+		runConformTest(
+			new String[] {
+					"X.java",
+					"public class X {\n" +
+					"    public int foo(int i) {\n" +
+					"    @SuppressWarnings(\"preview\")\n" +
+					"	boolean v = switch (i) {\n" +
+					"        case 1:\n" +
+					"        	switch (i) {\n" +
+					"        		case 1 : i = 10;\n" +
+					"        			break;\n" +
+					"        		default :\n" +
+					"        			i = 2;\n" +
+					"        			break;\n" +
+					"        		}\n" +
+					"        break true;\n" +
+					"        default: break false;\n" +
+					"    };\n" +
+					"    return v ? 0 : 1;\n" +
+					"    }\n" +
+					"\n" +
+					"    public static void main(String[] argv) {\n" +
+					"       System.out.println(new X().foo(0));\n" +
+					"    }\n" +
+					"}\n"
+			},
+			"1",
+			null,
+			new String[] {"--enable-preview"});
+	}
+	public void testBug544556() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" + 
+				"	public int foo(int i) {\n" + 
+				"		@SuppressWarnings(\"preview\")\n" + 
+				"		int v =\n" + 
+				"			switch(switch(i) {\n" + 
+				"					case 0 -> { break 2; }\n" + 
+				"					default -> { break 3; }\n" + 
+				"				}) {\n" + 
+				"			case 0 -> { break 0; }\n" + 
+				"			default -> { break 1; }\n" + 
+				"		};\n" + 
+				"	return v == 1 ? v : 0;\n" + 
+				"	}\n" + 
+				"	public static void main(String[] argv) {\n" + 
+				"		System.out.println(new X().foo(0));\n" + 
+				"	}\n" + 
+				"}"
+		},
+		"1",
+		null,
+		new String[] {"--enable-preview"});
+	}
+	public void testBug544702_01() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"    @SuppressWarnings(\"preview\")\n" +
+				"	public int foo(int i) {\n" +
+				"    	int k = 10;\n" +
+				"    	switch (i) {\n" +
+				"    		case 0 -> { k = 0;}\n" +
+				"    		default -> k = -1;\n" +
+				"    	}\n" +
+				"        return k;\n" +
+				"    }\n" +
+				"    public static void main(String[] argv) {\n" +
+				"        System.out.println(new X().foo(0) == 0 ? \"Success\" : \"Failure\");\n" +
+				"    }\n" +
+				"\n" +
+				"}\n"
+		},
+		"Success",
+		null,
+		new String[] {"--enable-preview"});
+	}
+	public void testBug545168_01() {
+		runConformTest(
+			new String[] {
+				"X.java",
+				"public class X {\n" +
+				"	@SuppressWarnings(\"preview\")\n" +
+				"	public static void foo(Day day) {\n" +
+				"		switch (day) {\n" +
+				"		case MONDAY, FRIDAY -> System.out.println(Day.SUNDAY);\n" +
+				"		case TUESDAY                -> System.out.println(7);\n" +
+				"		case THURSDAY, SATURDAY     -> System.out.println(8);\n" +
+				"		case WEDNESDAY              -> System.out.println(9);\n" +
+				"		default -> {}\n" +
+				"		}     \n" +
+				"	}\n" +
+				"	public static void main(String[] args) {\n" +
+				"		X.foo(Day.WEDNESDAY);\n" +
+				"	}\n" +
+				"}\n" +
+				"\n" +
+				"enum Day {\n" +
+				"	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n" +
+				"}\n"
+		},
+		"9",
+		null,
+		new String[] {"--enable-preview"});
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
index 1b1baca..69bfe88 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for
@@ -172,12 +176,18 @@
 	// add 10 specific test here (check duplicates)
 	ArrayList since_10 = new ArrayList();
 	since_10.add(JEP286Test.class);
+	since_10.add(Unicode10Test.class);
 	
 	// add 11 specific test here (check duplicates)
 	ArrayList since_11 = new ArrayList();
 	 since_11.add(JEP323VarLambdaParamsTest.class);
 	 since_11.add(JEP181NestTest.class);
 
+	// add 12 specific test here (check duplicates)
+	 ArrayList since_12 = new ArrayList();
+	 since_12.add(SwitchExpressionTest.class);
+	 since_12.add(Unicode11Test.class);
+
 	// Build final test suite
 	TestSuite all = new TestSuite(TestAll.class.getName());
 	all.addTest(new TestSuite(StandAloneASTParserTest.class));
@@ -275,6 +285,20 @@
 		TestCase.resetForgottenFilters(tests_11);
 		all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11), tests_11));
 	}
+	if ((possibleComplianceLevels & AbstractCompilerTest.F_12) != 0) {
+		ArrayList tests_12 = (ArrayList)standardTests.clone();
+		tests_12.addAll(since_1_4);
+		tests_12.addAll(since_1_5);
+		tests_12.addAll(since_1_6);
+		tests_12.addAll(since_1_7);
+		tests_12.addAll(since_1_8);
+		tests_12.addAll(since_9);
+		tests_12.addAll(since_10);
+		tests_12.addAll(since_11);
+		tests_12.addAll(since_12);
+		TestCase.resetForgottenFilters(tests_12);
+		all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12), tests_12));
+	}
 	all.addTest(new TestSuite(Jsr14Test.class));
 	return all;
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java
new file mode 100644
index 0000000..878286b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Unicode11Test.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.compiler.regression;
+
+import java.util.Map;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+
+public class Unicode11Test extends AbstractRegressionTest {
+public Unicode11Test(String name) {
+	super(name);
+}
+public static Test suite() {
+	return buildMinimalComplianceTestSuite(testClass(), F_12);
+}
+public void test1() {
+	Map<String, String> options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+	this.runConformTest(
+		new String[] {
+			"X.java",
+			"public class X {\n" + 
+			"		public int a\u0560; // new unicode character in unicode 11.0 \n" + 
+			"}",
+		},
+		"",
+		options);
+}
+public void test2() {
+	Map<String, String> options = getCompilerOptions();
+	options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
+	this.runNegativeTest(
+		new String[] {
+			"X.java",
+			"public class X {\n" + 
+			"		public int a\\u0560; // new unicode character in unicode 11.0 \n" + 
+			"}",
+		},
+		"----------\n" + 
+		"1. ERROR in X.java (at line 2)\n" + 
+		"	public int a\\u0560; // new unicode character in unicode 11.0 \n" + 
+		"	            ^^^^^^\n" + 
+		"Syntax error on token \"Invalid Character\", delete this token\n" + 
+		"----------\n",
+		null,
+		true,
+		options);
+}
+public static Class<Unicode11Test> testClass() {
+	return Unicode11Test.class;
+}
+}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
index d0e2f28..6e7d315 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/VarargsTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2016 IBM Corporation and others.
+ * Copyright (c) 2005, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -50,7 +50,11 @@
 	public static Class testClass() {
 		return VarargsTest.class;
 	}
-
+	protected String intersection(String... types) {
+		if (this.complianceLevel >= ClassFileConstants.JDK1_8)
+			return String.join(" & ", types);
+		return String.join("&", types);
+	}
 	public void test001() {
 		this.runConformTest(
 			new String[] {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
index fee9aac..eec4716 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/AbstractCompilerTest.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -43,6 +47,7 @@
 	public static final int F_9   = 0x40;
 	public static final int F_10  = 0x80;
 	public static final int F_11  = 0x100;
+	public static final int F_12  = 0x200;
 
 	public static final boolean RUN_JAVAC = CompilerOptions.ENABLED.equals(System.getProperty("run.javac"));
 	private static final int UNINITIALIZED = -1;
@@ -98,6 +103,9 @@
 		if ((complianceLevels & AbstractCompilerTest.F_11) != 0) {
 			suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)));
 		}
+		if ((complianceLevels & AbstractCompilerTest.F_12) != 0) {
+			suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12)));
+		}
 	}
 
 	/**
@@ -140,6 +148,9 @@
 		if ((complianceLevels & AbstractCompilerTest.F_11) != 0) {
 			suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)));
 		}
+		if ((complianceLevels & AbstractCompilerTest.F_12) != 0) {
+			suite.addTest(buildComplianceTestSuite(testClasses, setupClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12)));
+		}
 		return suite;
 	}
 
@@ -148,7 +159,7 @@
          int lessthan9 = F_1_3 | F_1_4 | F_1_5 | F_1_6 | F_1_7 | F_1_8;
          isJRE9Plus = !isJRELevel(lessthan9);
          isJRE11Plus = isJRELevel(F_11);
-         isJRE12Plus = "12".equals(System.getProperty("java.specification.version"));
+         isJRE12Plus = isJRELevel(F_12);
 	 }
 
 	/**
@@ -291,6 +302,14 @@
 				suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)));
 			}
 		}
+		int level12 = complianceLevels & AbstractCompilerTest.F_12;
+		if (level12 != 0) {
+			if (level12 < minimalCompliance) {
+				System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance 12!");
+			} else {
+				suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12)));
+			}
+		}
 		return suite;
 	}
 
@@ -324,7 +343,7 @@
 			else if (highestLevel == ClassFileConstants.JDK1_3)
 				complianceString = "1.3";
 			else {
-				highestLevel = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11);
+				highestLevel = ClassFileConstants.getLatestJDKLevel();
 				if (highestLevel > 0) {
 					complianceString = CompilerOptions.versionFromJdkLevel(highestLevel);
 				} else {
@@ -349,6 +368,9 @@
 	 */
 	public static long highestComplianceLevels() {
 		int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels();
+		if ((complianceLevels & AbstractCompilerTest.F_12) != 0) {
+			return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12);
+		}
 		if ((complianceLevels & AbstractCompilerTest.F_11) != 0) {
 			return ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11);
 		}
@@ -402,10 +424,10 @@
 	public static int getPossibleComplianceLevels() {
 		if (possibleComplianceLevels == UNINITIALIZED) {
 			String specVersion = System.getProperty("java.specification.version");
-			isJRE9Plus = CompilerOptions.VERSION_9.equals(specVersion)
-					||	CompilerOptions.VERSION_10.equals(specVersion)
-					||	CompilerOptions.VERSION_11.equals(specVersion);
-			isJRE11Plus = CompilerOptions.VERSION_11.equals(specVersion);
+			isJRE12Plus = CompilerOptions.VERSION_12.equals(specVersion);
+			isJRE11Plus = isJRE12Plus || CompilerOptions.VERSION_11.equals(specVersion);
+			isJRE9Plus = isJRE11Plus || CompilerOptions.VERSION_9.equals(specVersion)
+					||	CompilerOptions.VERSION_10.equals(specVersion);
 			initReflectionVersion();
 			String compliances = System.getProperty("compliance");
 			if (compliances != null) {
@@ -429,6 +451,8 @@
 						possibleComplianceLevels |= F_10;
 					} else if (CompilerOptions.VERSION_11.equals(compliance)) {
 						possibleComplianceLevels |= F_11;
+					} else if (CompilerOptions.VERSION_12.equals(compliance)) {
+						possibleComplianceLevels |= F_12;
 					} else {
 						System.out.println("Ignoring invalid compliance (" + compliance + ")");
 						System.out.print("Use one of ");
@@ -441,7 +465,8 @@
 						System.out.print(CompilerOptions.VERSION_1_8 + ", ");
 						System.out.print(CompilerOptions.VERSION_9 + ", ");
 						System.out.print(CompilerOptions.VERSION_10 + ", ");
-						System.out.println(CompilerOptions.VERSION_11);
+						System.out.print(CompilerOptions.VERSION_11 + ", ");
+						System.out.println(CompilerOptions.VERSION_12);
 					}
 				}
 				if (possibleComplianceLevels == 0) {
@@ -487,6 +512,10 @@
 					if (canRun11) {
 						possibleComplianceLevels |= F_11;
 					}
+					boolean canRun12 = canRun11 && !CompilerOptions.VERSION_11.equals(specVersion);
+					if (canRun12) {
+						possibleComplianceLevels |= F_12;
+					}
 				} else if ("1.0".equals(specVersion)
 							|| CompilerOptions.VERSION_1_1.equals(specVersion)
 							|| CompilerOptions.VERSION_1_2.equals(specVersion)
@@ -507,6 +536,9 @@
 										possibleComplianceLevels |= F_10;
 										if (!CompilerOptions.VERSION_10.equals(specVersion)) {
 											possibleComplianceLevels |= F_11;
+											if (!CompilerOptions.VERSION_11.equals(specVersion)) {
+												possibleComplianceLevels |= F_12;
+											}
 										}
 									}
 								}
@@ -662,6 +694,8 @@
 			options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
 			options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
 		} else {
+			// This is already good enough to cover versions from future 
+			// (as long as versionFromJdkLevel does its job)
 			String ver = CompilerOptions.versionFromJdkLevel(this.complianceLevel);
 			options.put(CompilerOptions.OPTION_Compliance, ver);
 			options.put(CompilerOptions.OPTION_Source, ver);
@@ -683,6 +717,11 @@
 		if (compliance < ClassFileConstants.JDK9) return "version 1.8 : 52.0";
 		if (compliance == ClassFileConstants.JDK9) return "version 9 : 53.0";
 		if (compliance == ClassFileConstants.JDK10) return "version 10 : 54.0";
+		if (compliance > ClassFileConstants.JDK10) {
+			String ver = CompilerOptions.versionFromJdkLevel(compliance);
+			int major = Integer.parseInt(ver) + ClassFileConstants.MAJOR_VERSION_0;
+			return "version " + ver + " : " + major + ".0";
+		}
 		if (compliance >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) return version; // keep this stmt for search for next bump up
 		return version;
 	}
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar
new file mode 100644
index 0000000..eed2c4d
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip
new file mode 100644
index 0000000..35e5589
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip
new file mode 100644
index 0000000..35e5589
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin12src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar
index df361f5..bb48557 100644
--- a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip
index 23ce774..031b53a 100644
--- a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip
+++ b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin9src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar
new file mode 100644
index 0000000..0f621d1
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin12.jar
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip b/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip
new file mode 100644
index 0000000..bf05b46
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/JCL/jclMin12src.zip
Binary files differ
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index 0743433..1acae5c 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -139,6 +139,37 @@
 			<tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,11</tycho.surefire.argLine>
 		</properties>
 	</profile>
+	<profile>
+		<id>test-on-javase-12</id>
+		<build>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-toolchains-plugin</artifactId>
+					<version>1.1</version>
+					<executions>
+						<execution>
+							<phase>validate</phase>
+							<goals>
+								<goal>toolchain</goal>
+							</goals>
+						</execution>
+					</executions>
+					<configuration>
+						<toolchains>
+							<jdk>
+								<id>JavaSE-12</id>
+							</jdk>
+						</toolchains>
+					</configuration>
+				</plugin>
+			</plugins>
+		</build>
+		<properties>
+			<!-- Overridden in https://ci.eclipse.org/jdt/job/eclipse.jdt.core-run.javac-12/configure  -->
+			<tycho.surefire.argLine>--add-modules ALL-SYSTEM -Dcompliance=1.4,1.7,1.8,12</tycho.surefire.argLine>
+		</properties>
+	</profile>
   </profiles>
 
 </project>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java
new file mode 100644
index 0000000..55ada0a
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunAllJava12Tests.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.eclipse.jdt.core.tests.dom.ASTConverter12Test;
+import org.eclipse.jdt.core.tests.dom.ConverterTestSetup;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class RunAllJava12Tests extends TestCase {
+
+	public RunAllJava12Tests(String name) {
+		super(name);
+	}
+	public static Class[] getAllTestClasses() {
+		return new Class[] {
+				// to be filled after other tests are added
+		};
+	}
+
+	public static Class[] getConverterTestClasses() {
+		return new Class[] {
+				ASTConverter12Test.class,
+		};
+	}
+
+	public static Class[] getCompilerClasses() {
+		return new Class[] {
+			org.eclipse.jdt.core.tests.eval.TestAll.class,
+			org.eclipse.jdt.core.tests.compiler.regression.TestAll.class,
+		};
+	}
+
+	public static Test suite() {
+		TestSuite ts = new TestSuite(RunAllJava12Tests.class.getName());
+
+		Class[] testClasses = getAllTestClasses();
+		addTestsToSuite(ts, testClasses);
+		testClasses = getConverterTestClasses();
+		addTestsToSuite(ts, testClasses);
+
+		AbstractCompilerTest.setpossibleComplianceLevels(AbstractCompilerTest.F_11);
+		addTestsToSuite(ts, getCompilerClasses());
+		// ComplianceDiagnoseTest is already added to the test suite through getTestSuite
+		ts.addTest(org.eclipse.jdt.core.tests.compiler.parser.TestAll.getTestSuite(false));
+		return ts;
+	}
+	public static void addTestsToSuite(TestSuite suite, Class[] testClasses) {
+
+		for (int i = 0; i < testClasses.length; i++) {
+			Class testClass = testClasses[i];
+			// call the suite() method and add the resulting suite to the suite
+			try {
+				Method suiteMethod = testClass.getDeclaredMethod("suite", new Class[0]); //$NON-NLS-1$
+				Test test = (Test)suiteMethod.invoke(null, new Object[0]);
+				suite.addTest(test);
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			} catch (InvocationTargetException e) {
+				e.getTargetException().printStackTrace();
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	protected void tearDown() throws Exception {
+		ConverterTestSetup.PROJECT_SETUP = false;
+		super.tearDown();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java
new file mode 100644
index 0000000..46a8dff
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunOnlyJava12Tests.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.jdt.core.tests.dom.ASTConverter12Test;
+import org.eclipse.jdt.core.tests.dom.ConverterTestSetup;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class RunOnlyJava12Tests extends TestCase {
+	
+	public RunOnlyJava12Tests(String name) {
+		super(name);
+	}
+	public static Class[] getAllTestClasses() {
+		return new Class[] {
+			// to be filled after other tests are added
+		};
+	}
+	
+	public static Class[] getConverterTestClasses() {
+		return new Class[] {
+				ASTConverter12Test.class
+		};
+	}
+	public static Test suite() {
+		TestSuite ts = new TestSuite(RunOnlyJava12Tests.class.getName());
+
+		Class[] testClasses = getAllTestClasses();
+		addTestsToSuite(ts, testClasses);
+		testClasses = getConverterTestClasses();
+		ConverterTestSetup.TEST_SUITES = new ArrayList(Arrays.asList(testClasses));
+		addTestsToSuite(ts, testClasses);
+		return ts;
+	}
+	public static void addTestsToSuite(TestSuite suite, Class[] testClasses) {
+
+		for (int i = 0; i < testClasses.length; i++) {
+			Class testClass = testClasses[i];
+			// call the suite() method and add the resulting suite to the suite
+			try {
+				Method suiteMethod = testClass.getDeclaredMethod("suite", new Class[0]); //$NON-NLS-1$
+				Test test = (Test)suiteMethod.invoke(null, new Object[0]);
+				suite.addTest(test);
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			} catch (InvocationTargetException e) {
+				e.getTargetException().printStackTrace();
+			} catch (NoSuchMethodException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+	protected void tearDown() throws Exception {
+		ConverterTestSetup.PROJECT_SETUP = false;
+		super.tearDown();
+	}
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java
new file mode 100644
index 0000000..f7637c7
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter12Test.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.dom;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
+
+import junit.framework.Test;
+
+public class ASTConverter12Test extends ConverterTestSetup {
+
+	ICompilationUnit workingCopy;
+
+	public void setUpSuite() throws Exception {
+		super.setUpSuite();
+		this.ast = AST.newAST(getAST12());
+	}
+
+	public ASTConverter12Test(String name) {
+		super(name);
+	}
+
+	static {
+//		TESTS_NUMBERS = new int[] { 19 };
+//		TESTS_RANGE = new int[] { 1, -1 };
+//		TESTS_NAMES = new String[] {"test0001"};
+	}
+	public static Test suite() {
+		return buildModelTestSuite(ASTConverter12Test.class);
+	}
+	
+	static int getAST12() {
+		return AST.JLS12;
+	}
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		if (this.workingCopy != null) {
+			this.workingCopy.discardWorkingCopy();
+			this.workingCopy = null;
+		}
+	}
+
+	public void test0001() throws JavaModelException {
+		String contents =
+			"	public class X {\n" +
+			"   enum Day\n" +
+			"   {\n" + 
+			"   	SUNDAY, MONDAY, TUESDAY, WEDNESDAY,\n" + 
+			"   	THURSDAY, FRIDAY, SATURDAY;\n" + 
+			"	}\n" +
+			"	public static void main(String[] args) {\n" + 
+			"		Day day = Day.SUNDAY;\n" +
+			"		int k = switch (day) {\n" + 
+			"    	case MONDAY  -> throw new NullPointerException();\n" + 
+			"    	case TUESDAY -> 1;\n" + 
+			"\n" +     
+			"	 	case WEDNESDAY -> {break 10;}\n" + 
+			"    	default      -> {\n" +
+			"        	int g = day.toString().length();\n" +
+			"        	break g;\n" +
+			"   	}};\n" +
+			"   	System.out.println(k);\n" +
+			"	}\n" +
+			"}" ;
+		this.workingCopy = getWorkingCopy("/Converter12/src/X.java", true/*resolve*/);
+		IJavaProject javaProject = this.workingCopy.getJavaProject();
+		String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+		try {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+			javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+			ASTNode node = buildAST(
+				contents,
+				this.workingCopy);
+			assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+			CompilationUnit compilationUnit = (CompilationUnit) node;
+			assertProblemsSize(compilationUnit, 0);
+			node = getASTNode(compilationUnit, 0, 1);
+			MethodDeclaration methodDeclaration = (MethodDeclaration) node;
+			VariableDeclarationStatement vStmt1 = (VariableDeclarationStatement) methodDeclaration.getBody().statements().get(1);
+			Type type = vStmt1.getType();
+			IBinding binding = type.resolveBinding();
+			assertTrue("null binding", binding != null);
+			assertTrue("binding incorrect", binding.getName().equals("int"));
+		} finally {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+		}
+	}
+	public void test0002() throws JavaModelException {
+		String contents =
+			"public class X {\n" + 
+			"	static enum Day {MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY, SATURDAY,SUNDAY}\n" + 
+			"	String aa(Day day) throws Exception {\n" + 
+			"		var today = \"\";\n" + 
+			"		switch (day) {\n" + 
+			"			case SATURDAY,SUNDAY ->\n" + 
+			"				today=\"Weekend\";\n" + 
+			"			case MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY ->\n" + 
+			"				today=\"Working\";\n" + 
+			"			default ->\n" + 
+			"				throw new Exception(\"Invalid day: \" + day.name());\n" + 
+			"		}\n" + 
+			"		return today;\n" + 
+			"	}\n" + 
+			"	\n" + 
+			"	String bb(Day day) throws Exception {\n" + 
+			"		var today = \"\";\n" + 
+			"		switch (day) {\n" + 
+			"			case SATURDAY,SUNDAY:\n" + 
+			"				today = \"Weekend day\";\n" + 
+			"				break;\n" + 
+			"			case MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY:\n" + 
+			"				today = \"Working day\";\n" + 
+			"				break;\n" + 
+			"			default:\n" + 
+			"				throw new Exception(\"Invalid day: \" + day.name());\n" + 
+			"		}\n" + 
+			"		return today;\n" + 
+			"	}\n" + 
+			"}" ;
+		this.workingCopy = getWorkingCopy("/Converter12/src/X.java", true/*resolve*/);
+		IJavaProject javaProject = this.workingCopy.getJavaProject();
+		String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+		try {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+			javaProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+			ASTNode node = buildAST(
+				contents,
+				this.workingCopy);
+			assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
+			CompilationUnit compilationUnit = (CompilationUnit) node;
+			assertProblemsSize(compilationUnit, 0);
+			node = getASTNode(compilationUnit, 0, 1, 1);
+			assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
+			SwitchStatement switchStatement = (SwitchStatement) node;
+			checkSourceRange((Statement) switchStatement.statements().get(0), "case SATURDAY,SUNDAY ->", contents);
+		} finally {
+			javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+		}
+	}
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
index dc6db31..21383f0 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java
@@ -4829,12 +4829,14 @@
 		statement = (Statement) statements.get(0);
     	assertEquals("Not a switch case statement", ASTNode.SWITCH_CASE, statement.getNodeType());
 		SwitchCase switchCase = (SwitchCase) statement;
+		@SuppressWarnings("deprecation")
 		Expression expression = switchCase.getExpression();
 		assertNull("Got a constant", expression.resolveConstantExpressionValue());
    }
 
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548
-    public void test0152() throws CoreException {
+    @SuppressWarnings("deprecation")
+	public void test0152() throws CoreException {
     	this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
     	String contents =
 	   		"public class X {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
index 32ef339..546c5a5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java
@@ -4759,7 +4759,8 @@
    }
 
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548
-    public void test0151() throws CoreException {
+    @SuppressWarnings("deprecation")
+	public void test0151() throws CoreException {
     	this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
     	String contents =
 	   		"public enum X {\n" +
@@ -4822,7 +4823,8 @@
    }
 
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548
-    public void test0152() throws CoreException {
+    @SuppressWarnings("deprecation")
+	public void test0152() throws CoreException {
     	this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
     	String contents =
 	   		"public class X {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
index 3a42702..00cd53b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java
@@ -4781,7 +4781,8 @@
    }
 
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548
-    public void test0151() throws CoreException {
+    @SuppressWarnings("deprecation")
+	public void test0151() throws CoreException {
     	this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
     	String contents =
 	   		"public enum X {\n" +
@@ -4844,7 +4845,8 @@
    }
 
 	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88548
-    public void test0152() throws CoreException {
+    @SuppressWarnings("deprecation")
+	public void test0152() throws CoreException {
     	this.workingCopy = getWorkingCopy("/Converter15/src/X.java", true/*resolve*/);
     	String contents =
 	   		"public class X {\n" +
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
index 6321d36..e80eba3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2016, 2018 IBM Corporation and others.
+ * Copyright (c) 2016, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -37,6 +41,7 @@
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.IProblem;
 
 @SuppressWarnings({"rawtypes"})
 public class ASTConverter9Test extends ConverterTestSetup {
@@ -1414,5 +1419,93 @@
 			deleteProject("Foo");
 		}
 	}
+	// TODO: should probably start a new test class
+	public void testBug531714_015() throws CoreException {
+		// saw NPE in SwitchExpression.resolveType(SwitchExpression.java:423)
+		if (!isJRE12) {
+			System.err.println("Test "+getName()+" requires a JRE 12");
+			return;
+		}
+		IJavaProject p =  createJavaProject("Foo", new String[] {"src"}, new String[] {jcl9lib}, "bin", "12"); // FIXME jcl12?
+		p.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		p.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
+		try {
+			String source =
+				"import java.util.*;\n" +
+				"public class X {\n" +
+				"	void testForeach1(int i, List<String> list) {\n" + 
+				"		for (String s : switch(i) { case 1 -> list; default -> ; }) {\n" + 
+				"			\n" + 
+				"		}\n" +
+				"		Throwable t = switch (i) {\n" +
+				"			case 1 -> new Exception();\n" +
+				"			case 2 -> new RuntimeException();\n" + // trigger !typeUniformAcrossAllArms
+				"			default -> missing;\n" +
+				"		};\n" +
+				"	}\n" + 
+				"	void testForeach0(int i, List<String> list) {\n" + // errors in first arm
+				"		for (String s : switch(i) { case 1 -> ; default -> list; }) {\n" + 
+				"			\n" + 
+				"		}\n" +
+				"		Throwable t = switch (i) {\n" +
+				"			case 0 -> missing;\n" +
+				"			case 1 -> new Exception();\n" +
+				"			default -> new RuntimeException();\n" + // trigger !typeUniformAcrossAllArms
+				"		};\n" +
+				"	}\n" +
+				"	void testForeachAll(int i) {\n" + // only erroneous arms
+				"		Throwable t = switch (i) {\n" +
+				"			case 0 -> missing;\n" +
+				"			default -> absent;\n" +
+				"		};\n" +
+				"	}\n" +
+				"}\n";
+			createFile("Foo/src/X.java", source);
+			ICompilationUnit cuD = getCompilationUnit("/Foo/src/X.java");
+				
+			ASTParser parser = ASTParser.newParser(AST_INTERNAL_JLS11);
+			parser.setProject(p);
+			parser.setSource(cuD);
+			parser.setResolveBindings(true);
+			parser.setStatementsRecovery(true);
+			parser.setBindingsRecovery(true);
+			org.eclipse.jdt.core.dom.CompilationUnit cuAST = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(null);
+			IProblem[] problems = cuAST.getProblems();
+			assertProblems("Unexpected problems",
+					"1. ERROR in /Foo/src/X.java (at line 4)\n" + 
+					"	for (String s : switch(i) { case 1 -> list; default -> ; }) {\n" + 
+					"	                                                    ^^\n" + 
+					"Syntax error on token \"->\", Expression expected after this token\n" + 
+					"----------\n" + 
+					"2. ERROR in /Foo/src/X.java (at line 10)\n" + 
+					"	default -> missing;\n" + 
+					"	           ^^^^^^^\n" + 
+					"missing cannot be resolved to a variable\n" + 
+					"----------\n" + 
+					"3. ERROR in /Foo/src/X.java (at line 14)\n" + 
+					"	for (String s : switch(i) { case 1 -> ; default -> list; }) {\n" + 
+					"	                                   ^^\n" + 
+					"Syntax error on token \"->\", Expression expected after this token\n" + 
+					"----------\n" + 
+					"4. ERROR in /Foo/src/X.java (at line 18)\n" + 
+					"	case 0 -> missing;\n" + 
+					"	          ^^^^^^^\n" + 
+					"missing cannot be resolved to a variable\n" + 
+					"----------\n" + 
+					"5. ERROR in /Foo/src/X.java (at line 25)\n" + 
+					"	case 0 -> missing;\n" + 
+					"	          ^^^^^^^\n" + 
+					"missing cannot be resolved to a variable\n" + 
+					"----------\n" + 
+					"6. ERROR in /Foo/src/X.java (at line 26)\n" + 
+					"	default -> absent;\n" + 
+					"	           ^^^^^^\n" + 
+					"absent cannot be resolved to a variable\n" + 
+					"----------\n",
+					problems, source.toCharArray());
+		} finally {
+			deleteProject(p);
+		}
+	}
 // Add new tests here
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java
index addae41..f4d1f0e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST3Test.java
@@ -2088,6 +2088,7 @@
 	/**
 	 * SwitchStatement ==> SwitchStatement
 	 */
+	@SuppressWarnings("deprecation")
 	public void test0097() throws JavaModelException {
 		ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		char[] source = sourceUnit.getSource().toCharArray();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java
index 926d8a3..4b77b6e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST4Test.java
@@ -2088,6 +2088,7 @@
 	/**
 	 * SwitchStatement ==> SwitchStatement
 	 */
+	@SuppressWarnings("deprecation")
 	public void test0097() throws JavaModelException {
 		ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		char[] source = sourceUnit.getSource().toCharArray();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java
index 9c83e01..9e617b1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterAST8Test.java
@@ -2072,6 +2072,7 @@
 	/**
 	 * SwitchStatement ==> SwitchStatement
 	 */
+	@SuppressWarnings("deprecation")
 	public void test0097() throws JavaModelException {
 		ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		char[] source = sourceUnit.getSource().toCharArray();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java
index acbd8dd..dfafd6d 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterTest.java
@@ -2177,6 +2177,7 @@
 	/**
 	 * SwitchStatement ==> SwitchStatement
 	 */
+	@SuppressWarnings("deprecation")
 	public void test0097() throws JavaModelException {
 		ICompilationUnit sourceUnit = getCompilationUnit("Converter" , "src", "test0097", "Test.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
 		char[] source = sourceUnit.getSource().toCharArray();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
index 04ca9bb..6b421b9 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTMatcherTest.java
@@ -1206,6 +1206,7 @@
 		x1.setName(this.N2);
 		basicMatch(x1);
 	}
+	@SuppressWarnings("deprecation")
 	public void testSwitchCase() {
 		SwitchCase x1 = this.ast.newSwitchCase();
 		x1.setExpression(this.E1);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
index 667df5d..fb64939 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -8868,6 +8872,7 @@
 			ASTNode.USES_DIRECTIVE,
 			ASTNode.PROVIDES_DIRECTIVE,
 			ASTNode.MODULE_MODIFIER,
+			ASTNode.SWITCH_EXPRESSION,
 
 		};
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
index 0407d10..c5e62c6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTVisitorTest.java
@@ -2096,6 +2096,7 @@
 		String result = this.b.toString();
 		assertTrue(result.equals("[(eSMR"+this.N1S+this.N2S+"eSMR)]")); //$NON-NLS-1$ //$NON-NLS-2$
 	}
+	@SuppressWarnings("deprecation")
 	public void testSwitchCase() {
 		SwitchCase x1 = this.ast.newSwitchCase();
 		x1.setExpression(this.E1);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java
index b6fafe4..8b895c1 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/AbstractASTTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2018 IBM Corporation and others.
+ * Copyright (c) 2004, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -493,7 +497,9 @@
 		String option = cu.getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true);
 		long jdkLevel = CompilerOptions.versionToJdkLevel(option);
 		int JLSLevel = AST_INTERNAL_JLS3;
-		if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) {
+		if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12)) {
+			JLSLevel = AST_INTERNAL_JLS12;
+		} else if (jdkLevel >= ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_11)) {
 			JLSLevel = AST_INTERNAL_JLS11;			
 		} else if (jdkLevel >= ClassFileConstants.JDK10) {
 			JLSLevel = AST_INTERNAL_JLS10;			
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
index f34d73e..513a512 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -105,6 +109,7 @@
 			this.deleteProject("Converter9"); //$NON-NLS-1$
 			this.deleteProject("Converter10"); //$NON-NLS-1$
 			this.deleteProject("Converter11"); //$NON-NLS-1$
+			this.deleteProject("Converter12"); //$NON-NLS-1$
 			PROJECT_SETUP = false;
 		} else {
 			TEST_SUITES.remove(getClass());
@@ -117,6 +122,7 @@
 				this.deleteProject("Converter9"); //$NON-NLS-1$
 				this.deleteProject("Converter10"); //$NON-NLS-1$
 				this.deleteProject("Converter11"); //$NON-NLS-1$
+				this.deleteProject("Converter12"); //$NON-NLS-1$
 				PROJECT_SETUP = false;
 			}
 		}
@@ -178,6 +184,14 @@
 						new IPath[] {getConverterJCLPath("11"), getConverterJCLSourcePath("11"), getConverterJCLRootSourcePath()},
 						null);
 			}
+		} else if ("12".equals(compliance)) {
+			if (JavaCore.getClasspathVariable("CONVERTER_JCL12_LIB") == null) {
+				setupExternalJCL("converterJclMin12");
+				JavaCore.setClasspathVariables(
+						new String[] {"CONVERTER_JCL11_LIB", "CONVERTER_JCL11_SRC", "CONVERTER_JCL11_SRCROOT"},
+						new IPath[] {getConverterJCLPath("12"), getConverterJCLSourcePath("12"), getConverterJCLRootSourcePath()},
+						null);
+			}
 		} else if (JavaCore.getClasspathVariable("CONVERTER_JCL_LIB") == null) {
 			setupExternalJCL("converterJclMin");
 			JavaCore.setClasspathVariables(
@@ -202,6 +216,7 @@
 			setUpJavaProject("Converter9", "9"); //$NON-NLS-1$ //$NON-NLS-2$
 			setUpJavaProject("Converter10", "10"); //$NON-NLS-1$ //$NON-NLS-2$
 			setUpJavaProject("Converter11", "11"); //$NON-NLS-1$ //$NON-NLS-2$
+			setUpJavaProject("Converter12", "12"); //$NON-NLS-1$ //$NON-NLS-2$
 			waitUntilIndexesReady(); // needed to find secondary types
 			PROJECT_SETUP = true;
 		}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
index 028e170..f12cc67 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
@@ -52,6 +52,7 @@
 		TypeAnnotationsConverterTest.class,
 		ASTConverter18Test.class,
 		ASTConverter9Test.class,
+		ASTConverter12Test.class,
 	};
 }
 public static Test suite() {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 7260030..59b92d6 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -90,11 +94,10 @@
 			}
 		}
 		long jdkLevel = CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion);
+		if (jdkLevel >= ClassFileConstants.getLatestJDKLevel()) {
+			isJRE12 = true;
+		}
 		if (jdkLevel >= ClassFileConstants.JDK11) {
-			if (CompilerOptions.versionToJdkLevel(javaVersion.length() > 3 ? javaVersion.substring(0, 3) : javaVersion, false) == 0) {
-				// version was capped to 11 during versionToJdkLevel(version, true)
-				isJRE12 = true;
-			}
 			isJRE11 = true;
 		}
 		if (jdkLevel >= ClassFileConstants.JDK10) {
@@ -114,7 +117,7 @@
 						"jdk.packager,jdk.packager.services,jdk.plugin.dom," +												// not present in OpenJDK
 						"jdk.scripting.nashorn,jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported,jdk.xml.dom," +
 						"oracle.desktop,oracle.net";																		// not present in OpenJDK
-			} else if (vmName.contains("OpenJDK")) {
+			} else if (vmName.contains("OpenJDK") || vmName.contains("OpenJ9")) {
 				DEFAULT_MODULES = "java.se," +
 						"jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver," +
 						"jdk.incubator.httpclient,jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jdi," +
@@ -124,7 +127,7 @@
 				System.out.println(System.getProperties());
 				fail("Unexpected java vm "+javaVersion+" "+vmName);
 			}
-			System.out.println("Recognized Java 9 version '"+javaVersion+"' with vm.name '"+vmName+"'");
+			System.out.println("Recognized Java version '"+javaVersion+"' with vm.name '"+vmName+"'");
 		}
 	}
 
@@ -142,11 +145,16 @@
 	protected static final int AST_INTERNAL_JLS10 = AST.JLS10;
 
 	/**
+	 * Internal synonym for constant AST.JSL12
+	 * to alleviate deprecation warnings once AST.JLS12 is deprecated in future.
+	 */
+	protected static final int AST_INTERNAL_JLS12 = AST.JLS12;
+
+	/**
 	 * Internal synonym for constant AST.JSL11
 	 * to alleviate deprecation warnings once AST.JLS11 is deprecated in future.
 	 */
 	protected static final int AST_INTERNAL_JLS11 = AST.JLS11;
-
 	public static class BasicProblemRequestor implements IProblemRequestor {
 		public void acceptProblem(IProblem problem) {}
 		public void beginReporting() {}
@@ -2044,6 +2052,12 @@
 					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
 					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
 					javaProject.setOptions(options);
+				} else if ("12".equals(compliance)) {
+					Map options = new HashMap();
+					options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+					options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
+					options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
+					javaProject.setOptions(options);
 				}
 				result[0] = javaProject;
 			}
@@ -3119,6 +3133,7 @@
 		javaProject.setOption(JavaCore.COMPILER_PB_FIELD_HIDING, JavaCore.IGNORE);
 		javaProject.setOption(JavaCore.COMPILER_PB_LOCAL_VARIABLE_HIDING, JavaCore.IGNORE);
 		javaProject.setOption(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING, JavaCore.IGNORE);
+//		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
 		return javaProject;
 	}
 	protected void setUpProjectCompliance(IJavaProject javaProject, String compliance) throws JavaModelException, IOException {
@@ -3136,7 +3151,10 @@
 			newJclLibString = "JCL18_FULL";
 			newJclSrcString = "JCL18_SRC"; // Use the same source
 		} else {
-			if (compliance.equals("11")) {
+			if (compliance.equals("12")) {
+				newJclLibString = "JCL12_LIB";
+				newJclSrcString = "JCL12_SRC";
+			} else if (compliance.equals("11")) {
 				newJclLibString = "JCL11_LIB";
 				newJclSrcString = "JCL11_SRC";
 			} else if (compliance.equals("10")) {
@@ -3193,10 +3211,11 @@
 		IPath jcl9Lib = new Path("JCL19_LIB");
 		IPath jcl10Lib = new Path("JCL10_LIB");
 		IPath jcl11Lib = new Path("JCL11_LIB");
+		IPath jcl12Lib = new Path("JCL12_LIB");
 		IPath jclFull = new Path("JCL18_FULL");
 
 		return path.equals(jclLib) || path.equals(jcl5Lib) || path.equals(jcl8Lib) || path.equals(jcl9Lib)
-				|| path.equals(jcl10Lib) ||  path.equals(jcl11Lib) || path.equals(jclFull);
+				|| path.equals(jcl10Lib) ||  path.equals(jcl11Lib) || path.equals(jcl12Lib) || path.equals(jclFull);
 	}
 	public void setUpJCLClasspathVariables(String compliance) throws JavaModelException, IOException {
 		setUpJCLClasspathVariables(compliance, false);
@@ -3259,6 +3278,14 @@
 					new IPath[] {getExternalJCLPath("11"), getExternalJCLSourcePath("11"), getExternalJCLRootSourcePath()},
 					null);
 			}
+		} else if ("12".equals(compliance)) {
+			if (JavaCore.getClasspathVariable("JCL12_LIB") == null) {
+				setupExternalJCL("jclMin12");
+				JavaCore.setClasspathVariables(
+					new String[] {"JCL12_LIB", "JCL12_SRC", "JCL_SRCROOT"},
+					new IPath[] {getExternalJCLPath("12"), getExternalJCLSourcePath("12"), getExternalJCLRootSourcePath()},
+					null);
+			}
 		} else {
 			if (JavaCore.getClasspathVariable("JCL_LIB") == null) {
 				setupExternalJCL("jclMin");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
index 2f58097..5f37bc3 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -102,6 +102,7 @@
 		ResolveTests2.class,
 		ResolveTests_1_5.class,
 		ResolveTests18.class,
+		ResolveTests12.class,
 		SelectionJavadocModelTests.class,
 
 		// Support for completion tests
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
index a7d9e60..ba4462e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
@@ -1903,6 +1903,7 @@
 		System.err.println(this.getClass().getName()+'.'+getName()+" needs a Java 9 JRE - skipped");
 		return;
 	}
+	if (isJRE12) return;
 	try {
 		IJavaProject prj = createJava9Project("Test", new String[]{"src"});
 		String moduleSrc =
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java
new file mode 100644
index 0000000..4fd1385
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests12.java
@@ -0,0 +1,860 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.model;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.internal.codeassist.RelevanceConstants;
+
+import junit.framework.Test;
+
+public class CompletionTests12 extends AbstractJavaModelCompletionTests {
+
+	static {
+//		TESTS_NAMES = new String[]{"test018e"};
+	}
+
+	public CompletionTests12(String name) {
+		super(name);
+	}
+	public void setUpSuite() throws Exception {
+		if (COMPLETION_PROJECT == null)  {
+			COMPLETION_PROJECT = setUpJavaProject("Completion", "12");
+		} else {
+			setUpProjectCompliance(COMPLETION_PROJECT, "12");
+		}
+		super.setUpSuite();
+	}
+	public static Test suite() {
+		return buildModelTestSuite(CompletionTests12.class);
+	}
+	public void test001() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUN ->\n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "SATURDAY, SUN";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test002() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUN :\n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "SATURDAY, SUN";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test003() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATU -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "SATU";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"SATURDAY[FIELD_REF]{SATURDAY, LMyDay;, LMyDay;, SATURDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test004() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY, MOND -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY, MONDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "MOND";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"MONDAY[FIELD_REF]{MONDAY, LMyDay;, LMyDay;, MONDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test005() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUND, MONDAY -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY, MONDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "SUND";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"SUNDAY[FIELD_REF]{SUNDAY, LMyDay;, LMyDay;, SUNDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test005a() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day) {\n" + 
+						"		case SATURDAY, SUNDAY -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		case MON -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+				"enum MyDay { SATURDAY, SUNDAY, MONDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "case MON";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"MONDAY[FIELD_REF]{MONDAY, LMyDay;, LMyDay;, MONDAY, null, "+ 
+						(RelevanceConstants.R_DEFAULT + RelevanceConstants.R_RESOLVED + RelevanceConstants.R_INTERESTING+
+								RelevanceConstants.R_CASE + RelevanceConstants.R_EXACT_EXPECTED_TYPE +
+								RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT +
+								RelevanceConstants.R_UNQUALIFIED + RelevanceConstants.R_NON_RESTRICTED)+ "}",
+						requestor.getResults());
+	}
+	public void test006() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day.toS) {\n" + 
+						"		case \"SATURDAY\" -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+						"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "day.toS";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, 60}",
+						requestor.getResults());
+	}
+	public void test007() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (day.o) {\n" + 
+						"		case 0 -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+						"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "day.o";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"ordinal[METHOD_REF]{ordinal(), Ljava.lang.Enum<LMyDay;>;, ()I, ordinal, null, 60}",
+						requestor.getResults());
+	}
+	public void test008() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (1 + day.o) {\n" + 
+						"		case 0 -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+						"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "day.o";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"ordinal[METHOD_REF]{ordinal(), Ljava.lang.Enum<LMyDay;>;, ()I, ordinal, null, 90}",
+						requestor.getResults());
+	}
+	public void test009() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (1 + da) {\n" + 
+						"		case 0 -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+						"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "1 + da";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"day[LOCAL_VARIABLE_REF]{day, null, LMyDay;, day, null, 52}",
+						requestor.getResults());
+	}
+	public void test010() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(MyDay day) {\n" + 
+						"		switch (1 + da + 1) {\n" + 
+						"		case 0 -> \n" + 
+						"			System.out.println(day.toString());\n" + 
+						"		}\n" + 
+						"	}\n" + 
+						"	public static void main(String[] args) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n" + 
+						"enum MyDay { SATURDAY, SUNDAY}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "1 + da";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"day[LOCAL_VARIABLE_REF]{day, null, LMyDay;, day, null, 52}",
+						requestor.getResults());
+	}
+	public void test011() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		switch (arg) {\n" + 
+						"		case 1 -> 1;\n" + 
+						"		default -> 0;\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "switch (arg";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}",
+						requestor.getResults());
+	}
+	public void test012() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		switch (arg0) {\n" + 
+						"		case 1 -> arg;\n" + 
+						"		default -> 0;\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "-> arg";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}",
+						requestor.getResults());
+	}
+	public void test013() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/Switch.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		switch (0 + arg) {\n" + 
+						"		case 1 -> 1;\n" + 
+						"		default -> 0;\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "0 + arg";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 82}",
+						requestor.getResults());
+	}
+	public void test014() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class X {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		swi);\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "swi";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"switch[KEYWORD]{switch, null, null, switch, null, 49}",
+						requestor.getResults());
+	}
+	public void _test015() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		switch (0 + arg0) {\n" + 
+						"		case 1 -> {break ar;}\n" + 
+						"		default -> 0;\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "break ar";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}",
+						requestor.getResults());
+	}
+	public void test016() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		switch (0 + arg0) {\n" + 
+						"		case 1 -> {break 1;}\n" + 
+						"		default -> ar;\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "-> ar";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}",
+						requestor.getResults());
+	}
+	public void _test017() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		int arg1 = 0;\n" + 
+						"		foo(\n" + 
+						"		switch (0 + arg0) {\n" + 
+						"		case 1 -> 1;\n" + 
+						"		default -> {break ar;}\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "break ar";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}",
+						requestor.getResults());
+	}
+	public void _test017a() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class Switch {\n" + 
+						"	public static void bar(int arg0) {\n" + 
+						"		foo(\n" + 
+						"		argLabel: switch (0 + arg0) {\n" + 
+						"		case 1 -> 1;\n" + 
+						"		default -> {break ar;}\n" +
+						"		}\n" + 
+						"	});\n" + 
+						"	public static void foo(int arg0) {\n" + 
+						"		bar(MyDay.SUNDAY);\n" + 
+						"	}\n" + 
+						"}\n");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "break ar";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"arg0[LOCAL_VARIABLE_REF]{arg0, null, I, arg0, null, 52}\n" +
+				"argLabel[LABEL_REF]{argLabel, null, null, argLabel, null, 49}",
+						requestor.getResults());
+	}
+	public void test018a() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"import java.util.function.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			case 1 -> this::n_; \n" + 
+				"			case 2 -> () -> n1(); \n" + 
+				"			case 3 -> null; \n" + 
+				"			case 4 -> () -> n2(); \n" + 
+				"			default -> this::n2; }); \n" + 
+				"	}\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "this::n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + 
+				"n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}",
+						requestor.getResults());
+	}
+	public void test018b() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			case 2 -> () -> n_; \n" + 
+				"	}\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "-> n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + 
+				"n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}",
+						requestor.getResults());
+	}
+	public void test018c() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			default -> this::n_; }); \n" + 
+				"	}\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "this::n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + 
+				"n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}",
+						requestor.getResults());
+	}
+	public void test018d() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			default -> () -> n_; }); \n" + 
+				"	}\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "() -> n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + 
+				"n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}",
+						requestor.getResults());
+	}
+	public void test018e() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			case 1 -> this::n_1; \n" + 
+				"			case 2 -> () -> n_; \n" + 
+				"	}\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "() -> n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[LOCAL_VARIABLE_REF]{n_1, null, Ljava.lang.Object;, n_1, null, 51}\n" + 
+				"n_1[METHOD_REF]{n_1(), LX;, ()LIN1;, n_1, null, 52}\n" + 
+				"n_2[METHOD_REF]{n_2(), LX;, ()LIN2;, n_2, null, 52}",
+						requestor.getResults());
+	}
+	public void test018f() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"interface IN0 {} \n" + 
+				"interface IN1 extends IN0 {} \n" + 
+				"interface IN2 extends IN0 {}\n" + 
+				"public class X {\n" + 
+				"	@NonNull IN1 n_1() { return new IN1() {}; } \n" + 
+				"	IN2 n_2() { return null; } \n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(switch(i) { \n" + 
+				"			case 1 -> () -> n_1; \n" + 
+				"			case 2 -> this::n_; \n" + 
+				"	}\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "this::n_";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"n_1[METHOD_NAME_REFERENCE]{n_1, LX;, ()LIN1;, n_1, null, 60}\n" + 
+				"n_2[METHOD_NAME_REFERENCE]{n_2, LX;, ()LIN2;, n_2, null, 60}",
+						requestor.getResults());
+	}
+	public void test019() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"import org.eclipse.jdt.annotation.*;\n" + 
+				"	<M> void m(@NonNull Supplier<@NonNull M> m2) { } \n" + 
+				"public class X {\n" + 
+				"	void testSw(int i) { \n" + 
+				"		m(swi);\n" + 
+				"}\n" +
+				"interface Supplier<T> {\n" + 
+				"    T get();\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "swi";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"switch[KEYWORD]{switch, null, null, switch, null, 49}",
+						requestor.getResults());
+	}
+	public void test020() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class X {\n" + 
+				"	static final String MONDAY = \"MONDAY\";\n" + 
+				"	static final String TUESDAY = \"TUESDAY\";\n" + 
+				"	static final String WEDNESDAY = \"WEDNESDAY\";\n" + 
+				"	static final String THURSDAY = \"THURSDAY\";\n" + 
+				"	static final String FRIDAY = \"FRIDAY\";\n" + 
+				"	static final String SATURDAY = \"SATURDAY\";\n" + 
+				"	static final String SUNDAY = \"SUNDAY\"; \n" + 
+				"	@SuppressWarnings(\"preview\")\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"		String day = \"MONDAY\";\n" + 
+				"		switch (day) {\n" + 
+				"		    case MONDAY, FRIDAY, SUNDAY  -> System.out.println(6);\n" + 
+				"		    case TUESDAY           		 -> System.out.println(7);\n" + 
+				"		    case THURSDAY, SATURDAY     -> System.out.println(8);\n" + 
+				"		    case WEDNESDAY              -> System.out.println(9);\n" + 
+				"		}\n" + 
+				"		int k = switch (day) {\n" + 
+				"	    case MONDAY  -> throw new NullPointerException();\n" + 
+				"	    case TUESDAY -> 1;\n" + 
+				"	    case WEDNESDAY -> {break 10;}\n" + 
+				"	    default      -> {\n" + 
+				"	        int g = day.h();\n" + 
+				"	        int result = f(g);\n" + 
+				"	        break result;\n" + 
+				"	    }};\n" + 
+				"	}\n" + 
+				"	static int f(int k) {\n" + 
+				"		return k*k;\n" + 
+				"	}\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "day.h";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"hashCode[METHOD_REF]{hashCode, Ljava.lang.Object;, ()I, hashCode, null, 90}",
+						requestor.getResults());
+	}
+	public void test021() throws JavaModelException {
+		this.workingCopies = new ICompilationUnit[1];
+		this.workingCopies[0] = getWorkingCopy(
+				"/Completion/src/X.java",
+				"public class X {\n" + 
+				"	static final String MONDAY = \"MONDAY\";\n" + 
+				"	static final String TUESDAY = \"TUESDAY\";\n" + 
+				"	static final String WEDNESDAY = \"WEDNESDAY\";\n" + 
+				"	static final String THURSDAY = \"THURSDAY\";\n" + 
+				"	static final String FRIDAY = \"FRIDAY\";\n" + 
+				"	static final String SATURDAY = \"SATURDAY\";\n" + 
+				"	static final String SUNDAY = \"SUNDAY\"; \n" + 
+				"	@SuppressWarnings(\"preview\")\n" + 
+				"	public static void main(String[] args) {\n" + 
+				"		String day = \"MONDAY\";\n" + 
+				"		int k = switch (day) {\n" + 
+				"	    case MONDAY  -> throw new NullPointerException();\n" + 
+				"	    case TUESDAY -> 1;\n" + 
+				"	    case WEDNESDAY -> {break 10;}\n" + 
+				"	    default      -> {\n" + 
+				"	        int g = day.h();\n" + 
+				"	        int result = f(g);\n" + 
+				"	        break result;\n" + 
+				"	    }};\n" + 
+				"	}\n" + 
+				"	static int f(int k) {\n" + 
+				"		return k*k;\n" + 
+				"	}\n" + 
+				"}");
+		CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+		requestor.allowAllRequiredProposals();
+		String str = this.workingCopies[0].getSource();
+		String completeBehind = "day.h";
+		int cursorLocation = str.indexOf(completeBehind) + completeBehind.length();
+		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+		assertResults(
+				"hashCode[METHOD_REF]{hashCode, Ljava.lang.Object;, ()I, hashCode, null, 90}",
+						requestor.getResults());
+	}
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
index e5d2894..b1dee23 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaCoreOptionsTests.java
@@ -6,6 +6,10 @@
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -120,10 +124,11 @@
 	assertTrue(JavaCore.compareJavaVersions("9", "1.8") > 0);
 	assertTrue(JavaCore.compareJavaVersions("9.0.1", "9.1.2") == 0);
 	assertTrue(JavaCore.compareJavaVersions("9", "9.1.2") == 0);
+	assertTrue(JavaCore.compareJavaVersions("12", "11") > 0);
+	assertTrue(JavaCore.compareJavaVersions("12", "1.5") > 0);
 	String latest = JavaCore.latestSupportedJavaVersion();
 	String latestPlus = "" + (Integer.parseInt(latest) + 1);
 	assertTrue(JavaCore.compareJavaVersions(latest, latestPlus) == 0);
-	
 }
 }
 
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java
new file mode 100644
index 0000000..ee0bf13
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugs12Tests.java
@@ -0,0 +1,630 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.model;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.ReferenceMatch;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.core.search.SearchMatch;
+import org.eclipse.jdt.core.search.TypeReferenceMatch;
+
+import junit.framework.Test;
+
+public class JavaSearchBugs12Tests extends AbstractJavaSearchTests {
+
+	static {
+//	 org.eclipse.jdt.internal.core.search.BasicSearchEngine.VERBOSE = true;
+//		TESTS_NUMBERS = new int[] { 19 };
+//		TESTS_RANGE = new int[] { 1, -1 };
+//		TESTS_NAMES = new String[] {"testBug542559_001"};
+}
+
+public JavaSearchBugs12Tests(String name) {
+	super(name);
+	this.endChar = "";
+}
+public static Test suite() {
+	return buildModelTestSuite(JavaSearchBugs12Tests.class, BYTECODE_DECLARATION_ORDER);
+}
+class TestCollector extends JavaSearchResultCollector {
+	public void acceptSearchMatch(SearchMatch searchMatch) throws CoreException {
+		super.acceptSearchMatch(searchMatch);
+	}
+}
+class ReferenceCollector extends JavaSearchResultCollector {
+	protected void writeLine() throws CoreException {
+		super.writeLine();
+		ReferenceMatch refMatch = (ReferenceMatch) this.match;
+		IJavaElement localElement = refMatch.getLocalElement();
+		if (localElement != null) {
+			this.line.append("+[");
+			if (localElement.getElementType() == IJavaElement.ANNOTATION) {
+				this.line.append('@');
+				this.line.append(localElement.getElementName());
+				this.line.append(" on ");
+				this.line.append(localElement.getParent().getElementName());
+			} else {
+				this.line.append(localElement.getElementName());
+			}
+			this.line.append(']');
+		}
+	}
+
+}
+class TypeReferenceCollector extends ReferenceCollector {
+	protected void writeLine() throws CoreException {
+		super.writeLine();
+		TypeReferenceMatch typeRefMatch = (TypeReferenceMatch) this.match;
+		IJavaElement[] others = typeRefMatch.getOtherElements();
+		int length = others==null ? 0 : others.length;
+		if (length > 0) {
+			this.line.append("+[");
+			for (int i=0; i<length; i++) {
+				IJavaElement other = others[i];
+				if (i>0) this.line.append(',');
+				if (other.getElementType() == IJavaElement.ANNOTATION) {
+					this.line.append('@');
+					this.line.append(other.getElementName());
+					this.line.append(" on ");
+					this.line.append(other.getParent().getElementName());
+				} else {
+					this.line.append(other.getElementName());
+				}
+			}
+			this.line.append(']');
+		}
+	}
+}
+
+IJavaSearchScope getJavaSearchScope() {
+	return SearchEngine.createJavaSearchScope(new IJavaProject[] {getJavaProject("JavaSearchBugs")});
+}
+IJavaSearchScope getJavaSearchScopeBugs(String packageName, boolean addSubpackages) throws JavaModelException {
+	if (packageName == null) return getJavaSearchScope();
+	return getJavaSearchPackageScope("JavaSearchBugs", packageName, addSubpackages);
+}
+public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
+	if (this.wcOwner == null) {
+		this.wcOwner = new WorkingCopyOwner() {};
+	}
+	return getWorkingCopy(path, source, this.wcOwner);
+}
+@Override
+public void setUpSuite() throws Exception {
+	super.setUpSuite();
+	JAVA_PROJECT = setUpJavaProject("JavaSearchBugs", "12");
+}
+public void tearDownSuite() throws Exception {
+	deleteProject("JavaSearchBugs");
+	super.tearDownSuite();
+}
+protected void setUp () throws Exception {
+	super.setUp();
+	this.resultCollector = new TestCollector();
+	this.resultCollector.showAccuracy(true);
+}
+
+public void testBug542559_001() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+			"	int switch_expr_field = 10;\n" +
+			"	int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> switch_expr_field * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default -> 3;\n" +
+			"		};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String... args) {\n" +
+			"		System.out.print(new X().twice(3));\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("switch_expr_field", FIELD, REFERENCES);
+		assertSearchResults("src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH");
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+public void testBug542559_002() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+			"	int switch_expr_field = 10;\n" +
+			"	int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> switch_expr_field * 0;\n" +
+			"			case 1 -> { break switch_expr_field; }\n" +
+			"			default -> 3;\n" +
+			"		};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String... args) {\n" +
+			"		System.out.print(new X().twice(3));\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("switch_expr_field", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" +
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+public void testBug542559_003() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+			"        int switch_expr_field = 10; \n" +
+			"        int twice(int i) throws Exception {      \n" +
+			"                int tw = switch (i) {   \n" +
+			"                        case 0 -> { break switch_expr_field; }  \n" +
+			"                        case 4 -> throw new MyException();  \n" +
+			"                        default -> 3;           \n" +
+			"                };      \n" +
+			"                return tw;              \n" +
+			"        }               \n" +
+			"        public static void main(String[] args) {\n" +
+			"                try {\n" +
+			"                                       System.out.print(new X().twice(3));\n" +
+			"                               } catch (Exception e) {\n" +
+			"                                       // TODO Auto-generated catch block\n" +
+			"                                       e.printStackTrace();\n" +
+			"                               }\n" +
+			"        }               \n" +
+			"}\n" +
+			"class MyException extends Exception {\n" +
+			"       private static final long serialVersionUID = 3461899582505930474L;\n" +
+			"       \n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		IType type = this.workingCopies[0].getType("MyException");
+		search(type, REFERENCES);
+		assertSearchResults(
+				"src/X.java int X.twice(int) [MyException] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+/*
+ * java search reference for an integer in default block of switch expression
+ */
+public void testBug542559_004() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+			"	int switch_expr_field = 10;\n" +
+			"	int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> switch_expr_field * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default ->{ \n" +
+			"			switch_expr_field*9; \n" +
+			"		}};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String... args) {\n" +
+			"		System.out.print(new X().twice(3));\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("switch_expr_field", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" +
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+/*
+ * java search reference for an integer in default of switch expression
+ */
+public void testBug542559_005() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+			"	int switch_expr_field = 10;\n" +
+			"	int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> switch_expr_field * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default -> switch_expr_field*9;\n" +
+			"		};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String... args) {\n" +
+			"		System.out.print(new X().twice(3));\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("switch_expr_field", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH\n" +
+				"src/X.java int X.twice(int) [switch_expr_field] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+/*
+ * java search reference for simple multi constant case statement for enum
+ */
+public void testBug542559_006() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+					"enum Day { SATURDAY, SUNDAY, MONDAY;}\n" +
+					"public static void bar(Day day) {\n" +
+					"		switch (day) {\n" +
+					"		case SATURDAY, SUNDAY: \n" +
+					"			System.out.println(Day.SUNDAY);\n" +
+					"			break;\n" +
+					"		case MONDAY : System.out.println(Day.MONDAY);\n" +
+					"					break;\n" +
+					"		}\n" +
+					"	}" +
+					"	public static void main(String[] args) {\n" +
+					"		bar(Day.SATURDAY);\n" +
+					"	}\n"
+					+
+					"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("SATURDAY", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java void X.bar(Day) [SATURDAY] EXACT_MATCH\n"+
+				"src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+/*
+ * java search reference for simple multi constant case statement for enum, 2nd case
+ */
+public void testBug542559_007() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+					"enum Day { SATURDAY, SUNDAY, MONDAY;}\n" +
+					"public static void bar(Day day) {\n" +
+					"		switch (day) {\n" +
+					"		case SATURDAY, SUNDAY: \n" +
+					"			System.out.println(Day.SUNDAY);\n" +
+					"			break;\n" +
+					"		case MONDAY : System.out.println(Day.MONDAY);\n" +
+					"					break;\n" +
+					"		}\n" +
+					"	}" +
+					"	public static void main(String[] args) {\n" +
+					"		bar(Day.SATURDAY);\n" +
+					"	}\n"
+					+
+					"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("SUNDAY", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java void X.bar(Day) [SUNDAY] EXACT_MATCH\n"+
+				"src/X.java void X.bar(Day) [SUNDAY] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+/*
+ * java search reference for class file reference in switch expression
+ */
+public void testBug542559_008() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X2.java",
+			"public class X2 {\n" +
+			"   String s = new String();        \n" +
+			"	int switch_expr_field = 10;\n" +
+			"	int twice(int i) {\n" +
+			"		int tw = switch (i) {\n" +
+			"			case 0 -> switch_expr_field * 0;\n" +
+			"			case 1 -> 2;\n" +
+			"			default -> new X2().toString().length();\n" +
+			"		};\n" +
+			"		return tw;\n" +
+			"	}\n" +
+			"	public static void main(String... args) {\n" +
+			"		System.out.print(new X2().twice(3));\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("X2", CLASS, REFERENCES);
+		assertSearchResults(
+		"src/X2.java int X2.twice(int) [X2] EXACT_MATCH\n"+
+		"src/X2.java void X2.main(String ...) [X2] EXACT_MATCH");
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+/*
+ * java search reference for class file reference in case and default blocks
+ */
+public void testBug542559_009() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+					"	Integer abcd\n" +
+					"	public static int foo(int i) {\n" +
+					"		final int k;\n" +
+					"\n" +
+					"		int it = switch (i) { \n" +
+					"		case 1  ->   {\n" +
+					"			k = 1;\n" +
+					"			abcd.toString();\n" +
+					"			break k ;\n" +
+					"		}\n" +
+					"		case 2  ->   {\n" +
+					"			abcd.toString();\n" +
+					"			break k ;\n" +
+					"		}\n" +
+					"		default -> {\n" +
+					"			k = 3;\n" +
+					"			abcd.toString();\n" +
+					"			break k;\n" +
+					"		}\n" +
+					"		};\n" +
+					"		return k;\n" +
+					"	}\n" +
+					"\n" +
+					"	public boolean bar() {\n" +
+					"		return true;\n" +
+					"	}\n" +
+					"	public static void main(String[] args) {\n" +
+					"		System.out.println(foo(3));\n" +
+					"	}\n" +
+					"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("abcd", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java int X.foo(int) [abcd] EXACT_MATCH\n" +
+				"src/X.java int X.foo(int) [abcd] EXACT_MATCH\n" +
+				"src/X.java int X.foo(int) [abcd] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+/*
+ * java search reference for string constant in switch expression and switch statement
+ */
+public void testBug542559_0010() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"public class X {\n" +
+					"	static final String MONDAY = \"MONDAY\";\n" +
+					"	static final String TUESDAY = \"TUESDAY\";\n" +
+					"	static final String WEDNESDAY = \"WEDNESDAY\";\n" +
+					"	static final String THURSDAY = \"THURSDAY\";\n" +
+					"	static final String FRIDAY = \"FRIDAY\";\n" +
+					"	static final String SATURDAY = \"SATURDAY\";\n" +
+					"	static final String SUNDAY = \"SUNDAY\"; \n" +
+					"	@SuppressWarnings(\"preview\")\n" +
+					"	public static void main(String[] args) {\n" +
+					"		String day = \"MONDAY\";\n" +
+					"		switch (day) {\n" +
+					"		    case MONDAY, FRIDAY, SUNDAY  -> System.out.println(6);\n" +
+					"		    case TUESDAY           		 -> System.out.println(7);\n" +
+					"		    case THURSDAY, SATURDAY     -> System.out.println(8);\n" +
+					"		    case WEDNESDAY              -> System.out.println(9);\n" +
+					"		}\n" +
+					"		int k = switch (day) {\n" +
+					"	    case SATURDAY  -> throw new NullPointerException();\n" +
+					"	    case TUESDAY -> 1;\n" +
+					"	    case WEDNESDAY -> {break 10;}\n" +
+					"	    default      -> {\n" +
+					"	        int g = day.h();\n" +
+					"	        int result = f(g);\n" +
+					"	        break result;\n" +
+					"	    }};\n" +
+					"	}\n" +
+					"	static int f(int k) {\n" +
+					"		return k*k;\n" +
+					"	}\n" +
+					"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject(); //assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("SATURDAY", FIELD, REFERENCES);
+		assertSearchResults(
+				"src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH\n" +
+				"src/X.java void X.main(String[]) [SATURDAY] EXACT_MATCH"
+		);
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+/*
+ * java search a javatype reference from another java project if that is in switch expression
+ */
+public void testBug542559_0011() throws CoreException {
+	try {
+
+		IJavaProject project1 = createJavaProject("JavaSearchBugs12", new String[] {"src"}, new String[] {"JCL12_LIB"}, "bin", "12");
+		project1.open(null);
+		createFolder("/JavaSearchBugs12/src/pack1");
+		createFile("/JavaSearchBugs12/src/pack1/X11.java",
+				"package pack1;\n" +
+				"public class X11 { \n" +
+				"	static final String MONDAY = \"MONDAY\";\n" +
+				"	static final String TUESDAY = \"TUESDAY\";\n" +
+				"	static final String WEDNESDAY = \"WEDNESDAY\";\n" +
+				"	static final String THURSDAY = \"THURSDAY\";\n" +
+				"	static final String FRIDAY = \"FRIDAY\";\n" +
+				"	static final String SATURDAY = \"SATURDAY\";\n" +
+				"	static final String SUNDAY = \"SUNDAY\"; \n" +
+				"	@SuppressWarnings(\"preview\")\n" +
+				"	public static void main(String[] args) {\n" +
+				"		String day = \"MONDAY\";\n" +
+				"		switch (day) {\n" +
+				"		    case MONDAY, FRIDAY, SUNDAY  -> System.out.println(6);\n" +
+				"		    case TUESDAY           		 -> System.out.println(7);\n" +
+				"		    case THURSDAY, SATURDAY     -> System.out.println(8);\n" +
+				"		    case WEDNESDAY              -> System.out.println(9);\n" +
+				"		}\n" +
+				"		int k = switch (day) {\n" +
+				"	    case SATURDAY  -> throw new NullPointerException();\n" +
+				"	    case TUESDAY -> 1;\n" +
+				"	    case WEDNESDAY -> {break 10;}\n" +
+				"	    default      -> {\n" +
+				"	        pack2.X22.a2=99;\n" +
+				"	        int result = f(g);\n" +
+				"	        break result;\n" +
+				"	    }};\n" +
+				"	}\n" +
+				"	static int f(int k) {\n" +
+				"		return k*k;\n" +
+				"	}\n" +
+				 "}\n");
+
+		IJavaProject project2 = createJavaProject("second", new String[] {"src"},new String[] {"JCL12_LIB"}, "bin", "12");
+		project2.open(null);
+		createFolder("/second/src/pack2");
+		createFile("/second/src/pack2/X22.java",
+				"package pack2;\n" +
+				"public class X22 {public static int a2=9;}\n");
+		addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath()));
+		project1.close(); // sync
+		project2.close();
+		project2.open(null);
+		project1.open(null);
+		IPackageFragment pkg = getPackageFragment("second", "src", "pack2");
+
+		IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaProject[]
+				{getJavaProject("JavaSearchBugs12")});
+
+		search(
+			pkg,
+			ALL_OCCURRENCES,
+			scope,
+			this.resultCollector);
+		String exp = "src/pack1/X11.java void pack1.X11.main(String[]) [pack2] EXACT_MATCH\n"
+		+"src/pack2 pack2 EXACT_MATCH";
+		assertSearchResults(
+			exp,
+			this.resultCollector);
+
+	}
+	finally {
+		deleteProject("JavaSearchBugs12");
+		deleteProject("second");
+	}
+
+}
+/*
+ * java search a method reference in switch expression
+ */
+public void testBug542559_0012() throws CoreException {
+	this.workingCopies = new ICompilationUnit[1];
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/X.java",
+			"import java.util.function.Supplier;\n" +
+			"interface I0 { void i(); }\n" +
+			"interface I1 extends I0 {}\n" +
+			"interface I2 extends I0 {}\n" +
+			"public class X {\n" +
+			"	I1 n1() { return null; }\n" +
+			"	<I extends I2> I n2() { return null; }\n" +
+			"	<M> M m(Supplier<M> m) { return m.get(); }\n" +
+			"	void test(int i, boolean b) {\n" +
+			"		m(switch (i) {\n" +
+			"			case 1 -> this::n1;\n" +
+			"			default -> this::n2;\n" +
+			"		}).i(); \n" +
+			"	}\n" +
+			"	public static void main(String[] args) {\n" +
+			"		try {\n" +
+			"			new X().test(1, true);\n" +
+			"		} catch (NullPointerException e) {\n" +
+			"			System.out.println(\"NPE as expected\");\n" +
+			"		}\n" +
+			"	}\n" +
+			"}\n"
+			);
+	IJavaProject javaProject = this.workingCopies[0].getJavaProject();//assuming single project for all working copies
+	String old = javaProject.getOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, true);
+	try {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
+		search("n1", METHOD, REFERENCES);
+		assertSearchResults("src/X.java void X.test(int, boolean) [n1] EXACT_MATCH");
+	} finally {
+		javaProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, old);
+	}
+}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
index 8e5d3b4..d257673 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchTests.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
index ddc65ad..81d316f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -60,8 +64,8 @@
 	}
 
 	static {
-//		 TESTS_NAMES = new String[] { "testBug522330" };
-	}
+//		 TESTS_NAMES = new String[] { "testReleaseOption8" };
+	} 
 	private String sourceWorkspacePath = null;
 	protected ProblemRequestor problemRequestor;
 	public static Test suite() {
@@ -6184,6 +6188,7 @@
 	}
 
 	public void testBug526054() throws Exception {
+		if (!isJRE9) return;
 		ClasspathJrt.resetCaches();
 		try {
 			// jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module.
@@ -6807,6 +6812,7 @@
 		}
 	}
 	public void testBug527569c() throws CoreException {
+		if (!isJRE9) return;
 		IJavaProject p1 = createJava9Project("Bug527569", "1.7");
 		Map<String, String> options = new HashMap<>();
 		// Make sure the new options map doesn't reset.
@@ -6856,6 +6862,7 @@
 		}
 	}
 	public void testBug527569e() throws CoreException {
+		if (!isJRE9 || isJRE12) return;
 		IJavaProject p1 = createJava9Project("Bug527569", "1.8");
 		Map<String, String> options = new HashMap<>();
 		// Make sure the new options map doesn't reset.
@@ -7650,39 +7657,39 @@
 		}
 	}
 	public void testBug543195() throws CoreException {
-		IJavaProject pj1 = createJava9Project("p1");
-		IJavaProject pj2 = createJava9Project("p2");
+		IJavaProject pj1 = createJava9Project("pj1");
+		IJavaProject pj2 = createJava9Project("pj2");
 		IJavaProject ptest = createJava9Project("ptest");
 		try {
 			addModularProjectEntry(pj2, pj1);
 			addModularProjectEntry(ptest, pj2);
 
-			createFolder("p1/src/p");
-			createFile("p1/src/p/Missing.java",
+			createFolder("pj1/src/p");
+			createFile("pj1/src/p/Missing.java",
 					"package p;\n" +
 					"public class Missing {\n" +
 					"	public void miss() {}\n" +
 					"}\n");
-			createFile("p1/src/module-info.java",
-					"module p1 {\n" +
+			createFile("pj1/src/module-info.java",
+					"module pj1 {\n" +
 					"	exports p;\n" +
 					"}\n");
 
-			createFolder("p2/src/q");
-			createFile("p2/src/q/API.java",
+			createFolder("pj2/src/q");
+			createFile("pj2/src/q/API.java",
 					"package q;\n" +
 					"public class API extends p.Missing {}\n");
-			createFile("p2/src/q/API2.java",
+			createFile("pj2/src/q/API2.java",
 					"package q;\n" +
 					"public class API2 extends API {}\n");
-			createFile("p2/src/module-info.java",
-					"module p2 {\n" +
-					"	requires p1;\n" +
+			createFile("pj2/src/module-info.java",
+					"module pj2 {\n" +
+					"	requires pj1;\n" +
 					"	exports q;\n" +
 					"}\n");
 			getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);
 
-			deleteFile("p1/bin/p/Missing.class");
+			deleteFile("pj1/bin/p/Missing.class");
 			pj1.getProject().close(null);
 
 			createFolder("ptest/src/p/r");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java
new file mode 100644
index 0000000..3440f5f
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12.java
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.tests.model;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+
+import junit.framework.Test;
+
+public class ResolveTests12 extends AbstractJavaModelTests {
+	ICompilationUnit wc = null;
+
+static {
+//	 TESTS_NAMES = new String[] { "test018" };
+	// TESTS_NUMBERS = new int[] { 124 };
+	// TESTS_RANGE = new int[] { 16, -1 };
+}
+public static Test suite() {
+	return buildModelTestSuite(ResolveTests12.class);
+}
+public ResolveTests12(String name) {
+	super(name);
+}
+public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
+	return super.getWorkingCopy(path, source, this.wcOwner);
+}
+public void setUpSuite() throws Exception {
+	super.setUpSuite();
+	setUpJavaProject("Resolve", "12", false);
+	waitUntilIndexesReady();
+}
+protected void setUp() throws Exception {
+	super.setUp();
+	this.wcOwner = new WorkingCopyOwner(){};
+}
+public void tearDownSuite() throws Exception {
+	deleteProject("Resolve");
+	super.tearDownSuite();
+}
+
+protected void tearDown() throws Exception {
+	if (this.wc != null) {
+		this.wc.discardWorkingCopy();
+	}
+	super.tearDown();
+}
+/*
+ * Multi constant case statement with ':', selection node is the string constant
+ */
+public void test001() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}\n");
+
+	String str = this.wc.getSource();
+	String selection = "ONE";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"ONE [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with ':', selection node is the first enum constant
+ */
+public void test002() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "ONE";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"ONE [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with ':', selection node is the second string constant
+ */
+public void test003() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "TWO";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"TWO [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with ':', selection node is the second enum constant
+ */
+public void test004() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE:\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "TWO";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"TWO [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection node is the string constant
+ */
+public void test005() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "ONE";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"ONE [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection node is the first enum constant
+ */
+public void test006() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break; // illegal, but should be ignored and shouldn't matter\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "ONE";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"ONE [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection node is the second string constant
+ */
+public void test007() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"static final String ONE=\"One\", TWO = \"Two\", THREE=\"Three\";\n" +
+	"  public static void foo(String num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "TWO";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"TWO [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection node is the second enum constant
+ */
+public void test008() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num) {\n" +
+	" 	 switch (num) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "TWO";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"TWO [in Num [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a reference in the case block
+ * which same as the switch's expression
+ */
+public void test009() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE ->\n" +
+	"		 System.out.println(num_);\n" +
+	"		 break;\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a reference in the case block
+ * which is referencing a local variable defined in the case block
+ */
+public void test010() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE -> {\n" +
+	"		 int i_j = 0;" +
+	"		 System.out.println(i_j);\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "i_j";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"i_j [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type enum in switch expression
+ */
+public void test011() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(Num num_) {\n" +
+	" 	 switch (num_) {\n" +
+	"	   case ONE, TWO, THREE -> {\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"	enum Num { ONE, TWO, THREE;}\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(Num) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test012() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 switch (num_ + 1) {\n" +
+	"	   case 1, 2, 3 -> {\n" +
+	"		 break;" +
+	"		 }\n" +
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test013() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> (num_ + 1);\n" +
+	"      default -> 0;\n" + 
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test014() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> 0;\n" +
+	"      default -> (num_ + 1);\n" + 
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test015() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" +
+	"  public static void foo(int num_) {\n" +
+	" 	 int i = switch (num_) {\n" +
+	"	   case 1, 2, 3 -> 0;\n" +
+	"      default -> (num_ + 1);\n" + 
+	"    }" +
+	"  }\n" +
+	"}\n");
+	String str = this.wc.getSource();
+	String selection = "num_";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"num_ [in foo(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+/*
+ * Multi constant case statement with '->', selection is a referenced name of type int in switch expression
+ */
+public void test016() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + 
+			"	public void bar(int s) {\n" + 
+			"		int i_j = switch (s) {\n" + 
+			"			case 1, 2, 3 -> (s+1);\n" +
+			"			default -> i_j;\n" + 
+			"		};\n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "i_j";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"i_j [in bar(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+public void test017() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java","public class X {\n" + 
+			"	public void bar(int s) {\n" + 
+			"		int i_j = switch (s) {\n" + 
+			"			case 1, 2, 3 -> (s+1);\n" +
+			"			default -> (1+i_j);\n" + 
+			"		};\n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "i_j";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"i_j [in bar(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+public void test018() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java",
+			"import java.util.function.*;\n" +
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			case 1 -> this::n_1; \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "n_1";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"n_1() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+public void test019() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java",
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			case 2 -> () -> n_1(); \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "n_1";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"n_1() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+public void test020() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java",
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1() { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int i) { \n" + 
+			"		m(switch(i) { \n" + 
+			"			default -> this::n_2; }); \n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "n_2";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"n_2() [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+public void test021() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java",
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1(int ijk) { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int ijk) { \n" + 
+			"		m(switch(ijk) { \n" + 
+			"			default -> () -> n_1(ijk); }); \n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "n_1";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"n_1(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]",
+		elements
+	);
+}
+public void test022() throws JavaModelException {
+	this.wc = getWorkingCopy("/Resolve/src/X.java",
+			"import java.util.function.*;\n" + 
+			"interface IN0 {} \n" + 
+			"interface IN1 extends IN0 {} \n" + 
+			"interface IN2 extends IN0 {}\n" + 
+			"public class X {\n" + 
+			"	 IN1 n_1(int ijk) { return new IN1() {}; } \n" + 
+			"	IN2 n_2() { return null; } \n" + 
+			"	<M> void m( Supplier< M> m2) { } \n" + 
+			"	void testSw(int ijk) { \n" + 
+			"		m(switch(ijk) { \n" + 
+			"			default -> () -> n_1(ijk); }); \n" + 
+			"	}\n" + 
+			"}\n");
+	String str = this.wc.getSource();
+	String selection = "ijk";
+	int start = str.lastIndexOf(selection);
+	int length = selection.length();
+	IJavaElement[] elements = this.wc.codeSelect(start, length);
+	assertElementsEqual(
+		"Unexpected elements",
+		"ijk [in testSw(int) [in X [in [Working copy] X.java [in <default> [in src [in Resolve]]]]]]",
+		elements
+	);
+}
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
index dc7e1ac..348ad9c 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunCompletionModelTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -41,6 +41,7 @@
 			COMPLETION_SUITES.add(CompletionTests9.class);
 			COMPLETION_SUITES.add(CompletionTests10.class);
 			COMPLETION_SUITES.add(CompletionTests11.class);
+			COMPLETION_SUITES.add(CompletionTests12.class);
 			COMPLETION_SUITES.add(CompletionContextTests.class);
 			COMPLETION_SUITES.add(CompletionContextTests_1_5.class);
 			COMPLETION_SUITES.add(CompletionWithMissingTypesTests.class);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java
index 433b855..1eb98c5 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingStatementsTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -3562,6 +3566,7 @@
 	}
 
 
+	@SuppressWarnings("deprecation")
 	public void testSwitchStatement() throws Exception {
 		IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
@@ -3606,12 +3611,19 @@
 			assertTrue("Number of statements not 0", statements.size() == 0);
 
 			SwitchCase caseStatement1= ast.newSwitchCase();
-			caseStatement1.setExpression(ast.newNumberLiteral("1"));
+			if (this.apiLevel < AST.JLS12) {
+				caseStatement1.setExpression(ast.newNumberLiteral("1"));
+			}
+			else {
+				caseStatement1.expressions().add(ast.newNumberLiteral("1"));
+			}
 
 			Statement statement1= ast.newReturnStatement();
 
 			SwitchCase caseStatement2= ast.newSwitchCase(); // default
-			caseStatement2.setExpression(null);
+			if (this.apiLevel < AST.JLS12) {
+				caseStatement2.setExpression(null);
+			}
 
 			ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 			listRewrite.insertLast(caseStatement1, null);
@@ -3634,14 +3646,25 @@
 			// change case statement
 			SwitchCase caseStatement= (SwitchCase) statements.get(3);
 			Expression newCaseExpression= ast.newNumberLiteral("10");
-			rewrite.replace(caseStatement.getExpression(), newCaseExpression, null);
+			if (this.apiLevel < AST.JLS12) {
+				rewrite.replace(caseStatement.getExpression(), newCaseExpression, null);
+			} else {
+				List expressions = caseStatement.expressions();
+				ListRewrite listRewrite= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY);
+				listRewrite.replace((Expression)expressions.get(0), newCaseExpression, null);
+			}
 
 			ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 
 			{
 				// insert case statement
 				SwitchCase caseStatement2= ast.newSwitchCase();
-				caseStatement2.setExpression(ast.newNumberLiteral("11"));
+				if (this.apiLevel < AST.JLS12) {
+					caseStatement2.setExpression(ast.newNumberLiteral("11"));
+				}
+				else {
+					caseStatement2.expressions().add(ast.newNumberLiteral("11"));
+				}
 				listRewrite.insertFirst(caseStatement2, null);
 
 				// insert statement
@@ -3652,7 +3675,12 @@
 			{
 				// insert case statement
 				SwitchCase caseStatement2= ast.newSwitchCase();
-				caseStatement2.setExpression(ast.newNumberLiteral("12"));
+				if (this.apiLevel < AST.JLS12) {
+					caseStatement2.setExpression(ast.newNumberLiteral("12"));
+				}
+				else {
+					caseStatement2.expressions().add(ast.newNumberLiteral("12"));
+				}
 				listRewrite.insertLast(caseStatement2, null);
 
 				// insert statement
@@ -3691,6 +3719,7 @@
 
 	}
 	
+	@SuppressWarnings("deprecation")
 	public void testSwitchStatement2() throws Exception {
 		String previousValue = null;
 		try {
@@ -3741,12 +3770,19 @@
 				assertTrue("Number of statements not 0", statements.size() == 0);
 	
 				SwitchCase caseStatement1= ast.newSwitchCase();
-				caseStatement1.setExpression(ast.newNumberLiteral("1"));
+				if (this.apiLevel < AST.JLS12) {
+					caseStatement1.setExpression(ast.newNumberLiteral("1"));
+				}
+				else {
+					caseStatement1.expressions().add(ast.newNumberLiteral("1"));
+				}
 	
 				Statement statement1= ast.newReturnStatement();
 	
 				SwitchCase caseStatement2= ast.newSwitchCase(); // default
-				caseStatement2.setExpression(null);
+				if (this.apiLevel < AST.JLS12) {
+					caseStatement2.setExpression(null);
+				}
 	
 				ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 				listRewrite.insertLast(caseStatement1, null);
@@ -3769,14 +3805,26 @@
 				// change case statement
 				SwitchCase caseStatement= (SwitchCase) statements.get(3);
 				Expression newCaseExpression= ast.newNumberLiteral("10");
-				rewrite.replace(caseStatement.getExpression(), newCaseExpression, null);
+				if (this.apiLevel < AST.JLS12) {
+					rewrite.replace(caseStatement.getExpression(), newCaseExpression, null);
+				} else {
+					List expressions = caseStatement.expressions();
+					ListRewrite listRewrite2= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY);
+					listRewrite2.replace((Expression)expressions.get(0), newCaseExpression, null);
+				}
 	
 				ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 	
 				{
 					// insert case statement
 					SwitchCase caseStatement2= ast.newSwitchCase();
-					caseStatement2.setExpression(ast.newNumberLiteral("11"));
+					if (this.apiLevel < AST.JLS12) {
+						caseStatement2.setExpression(ast.newNumberLiteral("11"));
+					}
+					else {
+						caseStatement2.expressions().add(ast.newNumberLiteral("11"));
+						
+					}
 					listRewrite.insertFirst(caseStatement2, null);
 	
 					// insert statement
@@ -3787,7 +3835,12 @@
 				{
 					// insert case statement
 					SwitchCase caseStatement2= ast.newSwitchCase();
-					caseStatement2.setExpression(ast.newNumberLiteral("12"));
+					if (this.apiLevel < AST.JLS12) {
+						caseStatement2.setExpression(ast.newNumberLiteral("12"));
+					}
+					else {
+						caseStatement2.expressions().add(ast.newNumberLiteral("12"));
+					}
 					listRewrite.insertLast(caseStatement2, null);
 	
 					// insert statement
@@ -4050,6 +4103,7 @@
 	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=246627
 	 * Replace a statement preceded by an unchanged statement)
 	 */
+	@SuppressWarnings("deprecation")
 	public void testSwitchStatement7() throws Exception {
 		String previousValue = null;
 		try {
@@ -4092,7 +4146,12 @@
 				ExpressionStatement assignment = (ExpressionStatement)statements.get(1); // i= 1;:
 				
 				SwitchCase switchCase = ast.newSwitchCase();
-				switchCase.setExpression(ast.newNumberLiteral("2"));
+				if (this.apiLevel < AST.JLS12) {
+					switchCase.setExpression(ast.newNumberLiteral("2"));
+				}
+				else {
+					switchCase.expressions().add(ast.newNumberLiteral("2"));
+				}
 				
 				ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 				listRewrite.replace(assignment, switchCase, null);
@@ -4192,6 +4251,7 @@
 	 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=246627
 	 * Remove a statement followed by an inserted statement)
 	 */
+	@SuppressWarnings("deprecation")
 	public void testSwitchStatement9() throws Exception {
 		String previousValue = null;
 		try {
@@ -4234,7 +4294,12 @@
 				ExpressionStatement assignment = (ExpressionStatement)statements.get(1); // i= 1;
 				
 				SwitchCase switchCase = ast.newSwitchCase();
-				switchCase.setExpression(ast.newNumberLiteral("2"));
+				if (this.apiLevel < AST.JLS12) {
+					switchCase.setExpression(ast.newNumberLiteral("2"));
+				}
+				else {
+					switchCase.expressions().add(ast.newNumberLiteral("2"));
+				}
 				
 				ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
 				listRewrite.remove(assignment, null);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java
new file mode 100644
index 0000000..ea5df06
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingSwitchExpressionsTest.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.rewrite.describing;
+
+import java.util.List;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.SwitchCase;
+import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+
+import junit.framework.Test;
+
+public class ASTRewritingSwitchExpressionsTest extends ASTRewritingTest {
+
+
+	public ASTRewritingSwitchExpressionsTest(String name) {
+		super(name, 12);
+	}
+
+	public ASTRewritingSwitchExpressionsTest(String name, int apiLevel) {
+		super(name, apiLevel);
+	}
+
+	public static Test suite() {
+		return createSuite(ASTRewritingSwitchExpressionsTest.class);
+	}
+
+	@SuppressWarnings("rawtypes")
+	public void testSwitchExpressions_since_12() throws Exception {
+		IPackageFragment pack1= this.sourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo(int i) {\n");
+		buf.append("        switch (i) {\n");
+		buf.append("        }\n");
+		buf.append("        switch (i) {\n");
+		buf.append("            case 1, 2->\n");
+		buf.append("                i= 1;\n");
+		buf.append("            case 3->\n");
+		buf.append("                i= 3;\n");
+		buf.append("            default->\n");
+		buf.append("                i= 4;\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= createAST(cu);
+		ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+
+		AST ast= astRoot.getAST();
+
+		assertTrue("Parse errors", (astRoot.getFlags() & ASTNode.MALFORMED) == 0);
+		TypeDeclaration type= findTypeDeclaration(astRoot, "E");
+		MethodDeclaration methodDecl= findMethodDeclaration(type, "foo");
+		Block block= methodDecl.getBody();
+		List blockStatements= block.statements();
+		assertTrue("Number of statements not 2", blockStatements.size() == 2);
+		{ // insert statements, replace expression
+			SwitchStatement switchStatement= (SwitchStatement) blockStatements.get(0);
+
+			ASTNode expression= switchStatement.getExpression();
+			SimpleName newExpression= ast.newSimpleName("x");
+			rewrite.replace(expression, newExpression, null);
+
+			List statements= switchStatement.statements();
+			assertTrue("Number of statements not 0", statements.size() == 0);
+
+			SwitchCase caseStatement1= ast.newSwitchCase();
+			caseStatement1.setSwitchLabeledRule(true);
+			caseStatement1.expressions().add(ast.newNumberLiteral("1"));
+			caseStatement1.expressions().add(ast.newNumberLiteral("2"));
+			
+
+			Statement statement1= ast.newReturnStatement();
+
+			SwitchCase caseStatement2= ast.newSwitchCase(); // default
+			caseStatement2.setSwitchLabeledRule(true);
+
+
+			ListRewrite listRewrite= rewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
+			listRewrite.insertLast(caseStatement1, null);
+			listRewrite.insertLast(statement1, null);
+			listRewrite.insertLast(caseStatement2, null);
+		}
+
+		{ // insert, remove, replace statements, change case statements
+			SwitchStatement switchStatement= (SwitchStatement) blockStatements.get(1);
+
+			List statements= switchStatement.statements();
+			assertTrue("Number of statements not 6", statements.size() == 6);
+
+			// remove statements
+
+			rewrite.remove((ASTNode) statements.get(0), null);
+			rewrite.remove((ASTNode) statements.get(1), null);
+
+			// change case statement
+			SwitchCase caseStatement= (SwitchCase) statements.get(2);
+			ListRewrite listRewrite= rewrite.getListRewrite(caseStatement, SwitchCase.EXPRESSIONS2_PROPERTY);
+
+			{
+				listRewrite.insertFirst(ast.newNumberLiteral("10"), null);
+				listRewrite.insertLast(ast.newNumberLiteral("12"), null);
+
+			}
+
+		}
+
+		String preview= evaluateRewrite(cu, rewrite);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo(int i) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            case 1, 2->\n");
+		buf.append("                return;\n");
+		buf.append("            default->\n");
+		buf.append("        }\n");
+		buf.append("        switch (i) {\n");
+		buf.append("            case 10, 3, 12->\n");
+		buf.append("                i= 3;\n");
+		buf.append("            default->\n");
+		buf.append("                i= 4;\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		assertEqualString(preview, buf.toString());
+	}
+	
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java
index bf162e4..c3ca558 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingTest.java
@@ -1,10 +1,14 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * SPDX-License-Identifier: EPL-2.0
  *
@@ -16,21 +20,33 @@
 import java.lang.reflect.Method;
 import java.util.List;
 
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.dom.*;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.FieldDeclaration;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.core.tests.model.AbstractJavaModelTests;
 import org.eclipse.jface.text.Document;
 import org.eclipse.text.edits.TextEdit;
 
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
 /**
  * Tests for ASTRewrite. Subclasses must have 2 constructors that forward to
  * constructors with the same signature as this class's constructors.
@@ -70,8 +86,10 @@
 
 	/** @deprecated using deprecated code */
 	private final static int JLS10_INTERNAL = AST.JLS10;
+	
+	private final static int JLS12_INTERNAL = AST.JLS12;
 
-	private final static int[] JLS_LEVELS = { JLS2_INTERNAL, JLS3_INTERNAL, JLS4_INTERNAL, JLS8_INTERNAL, JLS9_INTERNAL, JLS10_INTERNAL };
+	private final static int[] JLS_LEVELS = { JLS2_INTERNAL, JLS3_INTERNAL, JLS4_INTERNAL, JLS8_INTERNAL, JLS9_INTERNAL, JLS10_INTERNAL, JLS12_INTERNAL };
 
 	private static final String ONLY_AST_STRING = "_only";
 	private static final String SINCE_AST_STRING = "_since";
@@ -108,26 +126,31 @@
 
 	public static Test suite() {
 		TestSuite suite= new TestSuite(ASTRewritingTest.class.getName());
-		suite.addTest(ASTRewritingExpressionsTest.suite());
-		suite.addTest(ASTRewritingInsertBoundTest.suite());
-		suite.addTest(ASTRewritingMethodDeclTest.suite());
-		suite.addTest(ASTRewritingMoveCodeTest.suite());
-		suite.addTest(ASTRewritingStatementsTest.suite());
-		suite.addTest(ASTRewritingTrackingTest.suite());
-		suite.addTest(ASTRewritingJavadocTest.suite());
-		suite.addTest(ASTRewritingTypeAnnotationsTest.suite());
-		suite.addTest(ASTRewritingTypeDeclTest.suite());
-		suite.addTest(ASTRewritingGroupNodeTest.suite());
-		suite.addTest(ASTRewritingRevertTest.suite());
-		suite.addTest(LineCommentOffsetsTest.suite());
-		suite.addTest(ASTRewritingWithStatementsRecoveryTest.suite());
-		suite.addTest(ASTRewritePropertyTest.suite());
-		suite.addTest(ASTRewritingPackageDeclTest.suite());
-		suite.addTest(ASTRewritingLambdaExpressionTest.suite());		
-		suite.addTest(ASTRewritingReferenceExpressionTest.suite());		
-		suite.addTest(SourceModifierTest.suite());
-		suite.addTest(ImportRewriteTest.suite());
-		suite.addTest(ImportRewrite18Test.suite());
+		
+		
+		  suite.addTest(ASTRewritingExpressionsTest.suite());
+		  suite.addTest(ASTRewritingInsertBoundTest.suite());
+		  suite.addTest(ASTRewritingMethodDeclTest.suite());
+		  suite.addTest(ASTRewritingMoveCodeTest.suite());
+		  suite.addTest(ASTRewritingStatementsTest.suite());
+		  suite.addTest(ASTRewritingSwitchExpressionsTest.suite());
+		
+		  suite.addTest(ASTRewritingTrackingTest.suite());
+		  suite.addTest(ASTRewritingJavadocTest.suite());
+		  suite.addTest(ASTRewritingTypeAnnotationsTest.suite());
+		  suite.addTest(ASTRewritingTypeDeclTest.suite());
+		  suite.addTest(ASTRewritingGroupNodeTest.suite());
+		  suite.addTest(ASTRewritingRevertTest.suite());
+		  suite.addTest(LineCommentOffsetsTest.suite());
+		  suite.addTest(ASTRewritingWithStatementsRecoveryTest.suite());
+		  suite.addTest(ASTRewritePropertyTest.suite());
+		  suite.addTest(ASTRewritingPackageDeclTest.suite());
+		  suite.addTest(ASTRewritingLambdaExpressionTest.suite());
+		  suite.addTest(ASTRewritingReferenceExpressionTest.suite());
+		  suite.addTest(SourceModifierTest.suite());
+		  suite.addTest(ImportRewriteTest.suite());
+		  suite.addTest(ImportRewrite18Test.suite());
+		 
 		return suite;
 	}
 
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath
new file mode 100644
index 0000000..3522bc0
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="var" path="CONVERTER_JCL18_LIB" sourcepath="CONVERTER_JCL18_SRC" rootpath="CONVERTER_JCL_SRCROOT"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project
new file mode 100644
index 0000000..663fb8d
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>Converter18</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java b/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java
new file mode 100644
index 0000000..5a1a888
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter12/src/X.java
@@ -0,0 +1,4 @@
+public class X {
+	public void foo(X this) {
+	}
+}
diff --git a/org.eclipse.jdt.core/.settings/.api_filters b/org.eclipse.jdt.core/.settings/.api_filters
new file mode 100644
index 0000000..605b445
--- /dev/null
+++ b/org.eclipse.jdt.core/.settings/.api_filters
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<component id="org.eclipse.jdt.core" version="2">
+    <resource path="META-INF/MANIFEST.MF">
+        <filter id="924844039">
+            <message_arguments>
+                <message_argument value="3.16.0"/>
+                <message_argument value="3.16.0"/>
+            </message_arguments>
+        </filter>
+        <filter comment="Address this while merging BETA_JAVA_12" id="924844039">
+            <message_arguments>
+                <message_argument value="3.17.0"/>
+                <message_argument value="3.17.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java" type="org.eclipse.jdt.core.compiler.CategorizedProblem">
+        <filter comment="To be addressed while merging BETA_JAVA_12" id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.compiler.CategorizedProblem"/>
+                <message_argument value="CAT_COMPLIANCE"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="compiler/org/eclipse/jdt/core/compiler/IProblem.java" type="org.eclipse.jdt.core.compiler.IProblem">
+        <filter id="388194388">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.compiler.IProblem"/>
+                <message_argument value="IgnoreCategoriesMask"/>
+                <message_argument value="8388607"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="dom/org/eclipse/jdt/core/dom/BreakStatement.java" type="org.eclipse.jdt.core.dom.BreakStatement">
+        <filter comment="For Java 12 support." id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.dom.BreakStatement"/>
+                <message_argument value="EXPRESSION_PROPERTY"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="dom/org/eclipse/jdt/core/dom/SwitchCase.java" type="org.eclipse.jdt.core.dom.SwitchCase">
+        <filter comment="For Java 12" id="336658481">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.dom.SwitchCase"/>
+                <message_argument value="EXPRESSIONS2_PROPERTY"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="model/org/eclipse/jdt/core/util/IClassFileReader.java" type="org.eclipse.jdt.core.util.IClassFileReader">
+        <filter comment="default method added for getting nest members" id="404000815">
+            <message_arguments>
+                <message_argument value="org.eclipse.jdt.core.util.IClassFileReader"/>
+                <message_argument value="getNestMembersAttribute()"/>
+            </message_arguments>
+        </filter>
+    </resource>
+</component>
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
index 8aad546..8dfa35f 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247.java
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v20.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -160,7 +164,7 @@
 									if (content == null)
 										return FileVisitResult.CONTINUE;
 									ClasspathJep247.this.acceptModule(content);
-									ClasspathJep247.this.moduleNamesCache.add(f.getFileName().toString());
+									ClasspathJep247.this.moduleNamesCache.add(JRTUtil.sanitizedFileName(f));
 								}
 								return FileVisitResult.CONTINUE;
 							}
@@ -217,7 +221,7 @@
 		List<String> sub = new ArrayList<>();
 		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
 			for (final java.nio.file.Path subdir: stream) {
-				String rel = subdir.getFileName().toString();
+				String rel = JRTUtil.sanitizedFileName(subdir);
 				if (rel.contains(this.releaseInHex)) {
 					sub.add(rel);
 				} else {
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
index 52a8398..917fde6 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJep247Jdk12.java
@@ -5,6 +5,10 @@
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v20.html
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -70,7 +74,7 @@
 						Path p = this.fs.getPath(rel);
 						try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(p)) {
 							for (final java.nio.file.Path subdir: stream) {
-								Path f = this.fs.getPath(rel, subdir.getFileName().toString(), qualifiedBinaryFileName);
+								Path f = this.fs.getPath(rel, JRTUtil.sanitizedFileName(subdir), qualifiedBinaryFileName);
 								if (Files.exists(f)) {
 									content = JRTUtil.safeReadBytes(f);
 									if (content != null)
@@ -134,7 +138,7 @@
 		List<String> sub = new ArrayList<>();
 		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
 			for (final java.nio.file.Path subdir: stream) {
-				String rel = subdir.getFileName().toString();
+				String rel = JRTUtil.sanitizedFileName(subdir);
 				if (rel.contains(this.releaseInHex))
 					sub.add(rel);
 			}
@@ -157,7 +161,7 @@
 		if (this.modules == null) {
 			try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
 				for (final java.nio.file.Path subdir: stream) {
-					String rel = subdir.getFileName().toString();
+					String rel = JRTUtil.sanitizedFileName(subdir);
 					if (!rel.contains(this.releaseInHex)) {
 						continue;
 					}
@@ -179,8 +183,9 @@
 								if (content == null)
 									return FileVisitResult.CONTINUE;
 								Path m = f.subpath(1, f.getNameCount() - 1);
-								ClasspathJep247Jdk12.this.acceptModule(m.getFileName().toString(), content);
-								ClasspathJep247Jdk12.this.moduleNamesCache.add(m.getFileName().toString());
+								String name = JRTUtil.sanitizedFileName(m);
+								ClasspathJep247Jdk12.this.acceptModule(name, content);
+								ClasspathJep247Jdk12.this.moduleNamesCache.add(name);
 							}
 							return FileVisitResult.SKIP_SIBLINGS;
 						}
@@ -260,7 +265,7 @@
 		this.packageCache.add(Util.EMPTY_STRING);
 		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(this.releasePath)) {
 			for (final java.nio.file.Path subdir: stream) {
-				String rel = subdir.getFileName().toString();
+				String rel = JRTUtil.sanitizedFileName(subdir);
 				if (!rel.contains(this.releaseInHex)) {
 					continue;
 				}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java
index e76860d..117ba47 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJrt.java
@@ -156,10 +156,10 @@
 				}
 
 				@Override
-				public FileVisitResult visitModule(java.nio.file.Path modPath) throws IOException {
+				public FileVisitResult visitModule(Path p, String name) throws IOException {
 					if (moduleName == null)
 						return FileVisitResult.CONTINUE;
-					if (!moduleName.equals(modPath.toString())) {
+					if (!moduleName.equals(name)) {
 						return FileVisitResult.SKIP_SUBTREE;
 					}
 					return FileVisitResult.CONTINUE;
@@ -219,10 +219,10 @@
 					}
 
 					@Override
-					public FileVisitResult visitModule(Path mod) throws IOException {
+					public FileVisitResult visitModule(Path p, String name) throws IOException {
 						try {
-							ClasspathJrt.this.acceptModule(JRTUtil.getClassfileContent(ClasspathJrt.this.file, IModule.MODULE_INFO_CLASS, mod.toString()));
-							ClasspathJrt.this.moduleNamesCache.add(mod.getFileName().toString());
+							ClasspathJrt.this.acceptModule(JRTUtil.getClassfileContent(ClasspathJrt.this.file, IModule.MODULE_INFO_CLASS, name));
+							ClasspathJrt.this.moduleNamesCache.add(name);
 						} catch (ClassFormatException e) {
 							e.printStackTrace();
 						}
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index 060351e..2e82e50 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
@@ -170,7 +174,7 @@
 	Map<String,UpdatesByKind> moduleUpdates = new HashMap<>();
 	static final boolean isJRE12Plus;
 	static {
-		isJRE12Plus = "12".equals(System.getProperty("java.specification.version")); //$NON-NLS-1$ //$NON-NLS-2$
+		isJRE12Plus = CompilerOptions.VERSION_12.equals(System.getProperty("java.specification.version")); //$NON-NLS-1$
 	}
 
 /*
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 18957ea..26e1fc9 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -2179,6 +2179,16 @@
 					mode = DEFAULT;
 					continue;
 				}
+				if (currentArg.equals("-12") || currentArg.equals("-12.0")) { //$NON-NLS-1$ //$NON-NLS-2$
+					if (didSpecifyCompliance) {
+						throw new IllegalArgumentException(
+							this.bind("configure.duplicateCompliance", currentArg)); //$NON-NLS-1$
+					}
+					didSpecifyCompliance = true;
+					this.options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
+					mode = DEFAULT;
+					continue;
+				}
 				if (currentArg.equals("-d")) { //$NON-NLS-1$
 					if (this.destinationPath != null) {
 						StringBuffer errorMessage = new StringBuffer();
@@ -2726,6 +2736,8 @@
 					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
 				} else if (currentArg.equals("11") || currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$
 					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
+				} else if (currentArg.equals("12") || currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$
+					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
 				}
 				else if (currentArg.equals("jsr14")) { //$NON-NLS-1$
 					this.options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_JSR14);
@@ -2815,6 +2827,8 @@
 					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
 				} else if (currentArg.equals("11") ||  currentArg.equals("11.0")) { //$NON-NLS-1$//$NON-NLS-2$
 					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
+				} else if (currentArg.equals("12") ||  currentArg.equals("12.0")) { //$NON-NLS-1$//$NON-NLS-2$
+					this.options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
 				} else {
 					throw new IllegalArgumentException(this.bind("configure.source", currentArg)); //$NON-NLS-1$
 				}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index 0aa6f16..60065a5 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  * 
  * Contributors:
@@ -2512,6 +2516,14 @@
 	super.consumeCompilationUnit();
 }
 @Override
+protected void consumeSwitchExpression() {
+	super.consumeSwitchExpression();
+	if (this.assistNode != null) {
+		SwitchExpression expr = (SwitchExpression) this.expressionStack[this.expressionPtr];
+		expr.resolveAll = true;
+	}
+}
+@Override
 protected void consumeConditionalExpression(int op) {
 	popElement(K_CONDITIONAL_OPERATOR);
 	super.consumeConditionalExpression(op);
@@ -4268,6 +4280,16 @@
 					pushOnElementStack(K_CONDITIONAL_OPERATOR, QUESTION);
 				}
 				break;
+			case TokenNameARROW:
+				switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+					case K_BETWEEN_CASE_AND_COLON:
+						popElement(K_BETWEEN_CASE_AND_COLON);
+						break;
+					case K_BETWEEN_DEFAULT_AND_COLON:
+						popElement(K_BETWEEN_DEFAULT_AND_COLON);
+						break;
+				}
+				break;
 			case TokenNameCOLON:
 				switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
 					case K_CONDITIONAL_OPERATOR:
@@ -4314,6 +4336,17 @@
 			case TokenNamecase :
 				pushOnElementStack(K_BETWEEN_CASE_AND_COLON);
 				break;
+			case TokenNameCOMMA :
+				switch (topKnownElementKind(COMPLETION_OR_ASSIST_PARSER)) {
+					// for multi constant case stmt
+					// case MONDAY, FRI
+					// if there's a comma, ignore the previous expression (constant)
+					// Which doesn't matter for completing the next constant
+					case K_BETWEEN_CASE_AND_COLON:
+						this.expressionPtr--;
+						this.expressionLengthStack[this.expressionLengthPtr]--;
+				}
+				break;
 			case TokenNamedefault :
 				pushOnElementStack(K_BETWEEN_DEFAULT_AND_COLON);
 				break;
@@ -4885,6 +4918,9 @@
 				if (kind == K_LOCAL_INITIALIZER_DELIMITER && this.options.complianceLevel >= ClassFileConstants.JDK11) {
 					keywords[count++]= Keywords.VAR;
 				}
+				if (kind == K_SELECTOR_QUALIFIER && this.options.complianceLevel >= ClassFileConstants.JDK12) {
+					keywords[count++] = Keywords.SWITCH;
+				}
 				keywords[count++]= Keywords.TRUE;
 				keywords[count++]= Keywords.FALSE;
 				keywords[count++]= Keywords.NULL;
@@ -5090,6 +5126,15 @@
 	return nameReference;
 }
 @Override
+protected void consumePostfixExpression() {
+	// PostfixExpression ::= Name
+	if(this.topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_INSIDE_BREAK_STATEMENT) {
+		// Do nothing, just let checkLabelStatement() do the job
+	} else {
+		super.consumePostfixExpression();
+	}
+}
+@Override
 protected NameReference getUnspecifiedReferenceOptimized() {
 	if (this.identifierLengthStack[this.identifierLengthPtr] > 1) { // reducing a qualified name
 		// potential receiver is being poped, so reset potential receiver
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
index 08f7336..4e35ca3 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -508,6 +512,8 @@
 		if (this.elementKindStack[i] != K_LAMBDA_EXPRESSION_DELIMITER)
 			continue;
 		LambdaExpression expression = (LambdaExpression) this.elementObjectInfoStack[i];
+		if (expression == null)
+			return false;
 		if (expression.sourceStart >= statementStart && expression.sourceEnd <= statementEnd) {
 			this.elementPtr = i - 1;
 			lambdaClosed = true;
@@ -1278,8 +1284,11 @@
 			break;
 	}
 }
+private boolean lastArrowAssociatedWithCase = false;
 @Override
 protected void consumeToken(int token) {
+	if (TokenNameARROW == token)
+		this.lastArrowAssociatedWithCase = this.caseFlagSet; // remember the arrow association before reset.
 	super.consumeToken(token);
 
 	if(this.isFirst) {
@@ -1312,7 +1321,7 @@
 				}
 				break;
 			case TokenNameLBRACE:
-				if (this.previousToken == TokenNameARROW) {
+				if (this.previousToken == TokenNameARROW && !this.lastArrowAssociatedWithCase) {
 					popElement(K_LAMBDA_EXPRESSION_DELIMITER);
 					pushOnElementStack(K_LAMBDA_EXPRESSION_DELIMITER, BLOCK_BODY, this.previousObjectInfo);
 				}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
index 1b4e6f6..404d3b3 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Jesper Steen Møller <jesper@selskabet.org> - contributions for:	
@@ -77,7 +81,7 @@
 	protected static final int SELECTION_OR_ASSIST_PARSER = ASSIST_PARSER + SELECTION_PARSER;
 
 	// KIND : all values known by SelectionParser are between 1025 and 1549
-	protected static final int K_BETWEEN_CASE_AND_COLON = SELECTION_PARSER + 1; // whether we are inside a block
+	protected static final int K_BETWEEN_CASE_AND_COLONORARROW = SELECTION_PARSER + 1; // whether we are inside a block
 	protected static final int K_INSIDE_RETURN_STATEMENT = SELECTION_PARSER + 2; // whether we are between the keyword 'return' and the end of a return statement
 	protected static final int K_CAST_STATEMENT = SELECTION_PARSER + 3; // whether we are between ')' and the end of a cast statement
 
@@ -150,7 +154,7 @@
 	if(kind != 0) {
 		int info = topKnownElementInfo(SELECTION_OR_ASSIST_PARSER);
 		nextElement : switch (kind) {
-			case K_BETWEEN_CASE_AND_COLON :
+			case K_BETWEEN_CASE_AND_COLONORARROW :
 				if(this.expressionPtr > 0) {
 					SwitchStatement switchStatement = new SwitchStatement();
 					switchStatement.expression = this.expressionStack[this.expressionPtr - 1];
@@ -1250,11 +1254,26 @@
 	if (isInsideMethod() || isInsideFieldInitialization()) {
 		switch (token) {
 			case TokenNamecase :
-				pushOnElementStack(K_BETWEEN_CASE_AND_COLON);
+				pushOnElementStack(K_BETWEEN_CASE_AND_COLONORARROW);
 				break;
+			case TokenNameCOMMA :
+				switch (topKnownElementKind(SELECTION_OR_ASSIST_PARSER)) {
+					// for multi constant case stmt
+					// case MONDAY, FRIDAY
+					// if there's a comma, ignore the previous expression (constant)
+					// Which doesn't matter for the next constant
+					case K_BETWEEN_CASE_AND_COLONORARROW:
+						this.expressionPtr--;
+						this.expressionLengthStack[this.expressionLengthPtr]--;
+				}
+				break;
+			case TokenNameARROW:
+				// TODO: Uncomment the line below
+				//if (this.options.sourceLevel < ClassFileConstants.JDK13) break;
+				// else FALL-THROUGH
 			case TokenNameCOLON:
-				if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLON) {
-					popElement(K_BETWEEN_CASE_AND_COLON);
+				if(topKnownElementKind(SELECTION_OR_ASSIST_PARSER) == K_BETWEEN_CASE_AND_COLONORARROW) {
+					popElement(K_BETWEEN_CASE_AND_COLONORARROW);
 				}
 				break;
 			case TokenNamereturn:
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
index 6b13fee..55cb6c5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/CategorizedProblem.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -103,6 +107,10 @@
 	 * @since 3.14
 	 */
 	public static final int CAT_MODULE = 160;
+	/**
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final int CAT_COMPLIANCE = 170;
 
 /**
  * Returns an integer identifying the category of this problem. Categories, like problem IDs are
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index fff5883..fc4f419 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     IBM Corporation - added the following constants
@@ -373,11 +377,13 @@
 	int Javadoc = 0x80000000;
 	/** @since 3.14 */
 	int ModuleRelated = 0x00800000;
+	/** @since 3.17 BETA_JAVA_12 */
+	int Compliance = 0x00400000;
 
 	/**
 	 * Mask to use in order to filter out the category portion of the problem ID.
 	 */
-	int IgnoreCategoriesMask = 0x7FFFFF;
+	int IgnoreCategoriesMask = 0x3FFFFF;
 
 	/*
 	 * Below are listed all available problem IDs. Note that this list could be augmented in the future,
@@ -2045,6 +2051,12 @@
 	int LambdaShapeComputationError = 1101;
 	/** @since 3.13 */
 	int ProblemNotAnalysed = 1102;
+	/** @since 3.17 BETA_JAVA_12 */
+	int PreviewFeatureDisabled = Compliance + 1103;
+	/** @since 3.17 BETA_JAVA_12 */
+	int PreviewFeatureUsed = Compliance + 1104;
+	/** @since 3.17 BETA_JAVA_12 */
+	int PreviewFeatureNotSupported = Compliance + 1105;
 	
 	/** @since 3.13 */
 	int UnlikelyCollectionMethodArgumentType = 1200;
@@ -2078,5 +2090,24 @@
 	int VarIsNotAllowedHere = Syntax + 1511; // ''var'' is not allowed here
 	/** @since 3.16 */
 	int VarCannotBeMixedWithNonVarParams = Syntax + 1512; // ''var'' cannot be mixed with explicit or implicit parameters
-	
-}
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionsIncompatibleResultExpressionTypes = TypeRelated + 1600;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionsEmptySwitchBlock = Internal + 1601;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionsNoResultExpression = TypeRelated + 1602;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionSwitchLabeledBlockCompletesNormally = Internal + 1603;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionLastStatementCompletesNormally = Internal + 1604;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionTrailingSwitchLabels = Internal + 1605;
+	/** @since 3.17 BETA_JAVA_12 */
+	int switchMixedCase = Syntax + 1606;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionMissingDefaultCase = Internal + 1607;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionBreakMissingValue = Internal + 1610;
+	/** @since 3.17 BETA_JAVA_12 */
+	int SwitchExpressionMissingEnumConstantCase = Internal + 1611;
+	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
index 869dc48..c9cba84 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -508,6 +512,9 @@
 	public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
 		// do nothing by default
 	}
+	public void endVisit(SwitchExpression switchExpression,	BlockScope scope) {
+		// do nothing by default
+	}
 	public boolean visit(
     		AllocationExpression allocationExpression,
     		BlockScope scope) {
@@ -999,4 +1006,7 @@
 	public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) {
 		return true; // do nothing by default, keep traversing
 	}
+	public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) {
+		return true; // do nothing by default, keep traversing
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 78b31cc..9ec29d3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995
@@ -108,7 +112,7 @@
 	public final static int Bit18 = 0x20000;			// non null (expression) | onDemand (import reference)
 	public final static int Bit19 = 0x40000;			// didResolve (parameterized qualified type ref/parameterized single type ref)  | empty (javadoc return statement) | needReceiverGenericCast (msg/fieldref)
 	public final static int Bit20 = 0x80000;			// contains syntax errors (method declaration, type declaration, field declarations, initializer), typeref: <> name ref: lambda capture)
-	public final static int Bit21 = 0x100000;
+	public final static int Bit21 = 0x100000;			// for all declarations that can contain type references that have type annotations | insideExpressionStatement
 	public final static int Bit22 = 0x200000;			// parenthesis count (expression) | used (import reference) shadows outer local (local declarations)
 	public final static int Bit23 = 0x400000;			// parenthesis count (expression) | second or later declarator in declaration (local declarations)
 	public final static int Bit24 = 0x800000;			// parenthesis count (expression)
@@ -325,7 +329,7 @@
 	public static final int IsDiamond = Bit20;
 
 	// this is only used for method invocation as the expression inside an expression statement
-	public static final int InsideExpressionStatement = Bit5;
+	public static final int InsideExpressionStatement = Bit21;
 
 	// for annotation reference, signal if annotation was created from a default:
 	public static final int IsSynthetic = ASTNode.Bit7;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
index 08869f0..ece451e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -32,6 +36,12 @@
 	this.sourceEnd = sourceEnd;
 }
 
+protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) {
+	// do nothing here
+}
+protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) {
+	// do nothing here
+}
 /**
  * Branch code generation
  *
@@ -42,6 +52,7 @@
 	if ((this.bits & ASTNode.IsReachable) == 0) {
 		return;
 	}
+	generateExpressionResultCode(currentScope, codeStream);
 	int pc = codeStream.position;
 
 	// generation of code responsible for invoking the finally
@@ -62,6 +73,7 @@
 		}
 	}
 	codeStream.goto_(this.targetLabel);
+	adjustStackSize(currentScope, codeStream);
 	codeStream.recordPositionsFrom(pc, this.sourceStart);
 	SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream);
 	if (this.initStateIndex != -1) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
index b17194a..7d1e82a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
@@ -16,15 +20,19 @@
 package org.eclipse.jdt.internal.compiler.ast;
 
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
 import org.eclipse.jdt.internal.compiler.flow.*;
 import org.eclipse.jdt.internal.compiler.lookup.*;
 
 public class BreakStatement extends BranchStatement {
 
+	public Expression expression;
+	public SwitchExpression switchExpression;
+	public boolean isImplicit;
+
 public BreakStatement(char[] label, int sourceStart, int e) {
 	super(label, sourceStart, e);
 }
-
 @Override
 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 
@@ -40,11 +48,19 @@
 		if (this.label == null) {
 			currentScope.problemReporter().invalidBreak(this);
 		} else {
-			currentScope.problemReporter().undefinedLabel(this);
+			if (this.switchExpression == null)
+				currentScope.problemReporter().undefinedLabel(this);
 		}
 		return flowInfo; // pretend it did not break since no actual target
 	}
 
+	if (this.switchExpression != null && this.expression != null) {
+		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
+		this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
+		if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
+			checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression);
+	}
+
 	targetContext.recordAbruptExit();
 	targetContext.expireNullCheckedFieldInfo();
 
@@ -89,17 +105,72 @@
 	}
 	return FlowInfo.DEAD_END;
 }
+@Override
+protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) {
+	if (this.label == null && this.expression != null) {
+		this.expression.generateCode(currentScope, codeStream, this.switchExpression != null);
+	}
+}
+@Override
+protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) {
+	if (this.label == null && this.expression != null && this.switchExpression != null) {
+		TypeBinding postConversionType = this.expression.postConversionType(currentScope);
+		switch(postConversionType.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				codeStream.decrStackSize(2);
+				break;
+			case TypeIds.T_void :
+				break;
+			default :
+				codeStream.decrStackSize(1);
+				break;
+		}
+	}
+}
+@Override
+public void resolve(BlockScope scope) {
+	super.resolve(scope);
+	if  (this.expression != null && (this.switchExpression != null || this.isImplicit)) {
+		if (this.switchExpression == null && this.isImplicit && !this.expression.statementExpression()) {
+			if (scope.compilerOptions().enablePreviewFeatures) {
+				/* JLS 12 14.11.2
+				Switch labeled rules in switch statements differ from those in switch expressions (15.28).
+				In switch statements they must be switch labeled statement expressions, ... */
+				scope.problemReporter().invalidExpressionAsStatement(this.expression);
+				return;
+			}
+		}
+		this.expression.resolveType(scope);
+	} else if (this.expression == null && this.switchExpression != null) {
+		scope.problemReporter().switchExpressionBreakMissingValue(this);
+	}
+}
+
+@Override
+public TypeBinding resolveExpressionType(BlockScope scope) {
+	return this.expression != null ? this.expression.resolveType(scope) : null;
+}
 
 @Override
 public StringBuffer printStatement(int tab, StringBuffer output) {
-	printIndent(tab, output).append("break"); //$NON-NLS-1$
-	if (this.label != null) output.append(' ').append(this.label);
+	if (!this.isImplicit) // implicit for SwitchLabeledExpressions
+		printIndent(tab, output).append("break"); //$NON-NLS-1$
+	if (this.label != null) 
+		output.append(' ').append(this.label);
+	if (this.expression != null) {
+		output.append(' ');
+		this.expression.printExpression(tab, output);
+	}
 	return output.append(';');
 }
 
 @Override
 public void traverse(ASTVisitor visitor, BlockScope blockscope) {
-	visitor.visit(this, blockscope);
+	if (visitor.visit(this, blockscope)) {
+		if (this.expression != null)
+			this.expression.traverse(visitor, blockscope);
+	}
 	visitor.endVisit(this, blockscope);
 }
 @Override
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
index 85e0f21..5ad0916 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,11 +8,18 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.codegen.BranchLabel;
@@ -21,6 +28,7 @@
 import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
 import org.eclipse.jdt.internal.compiler.impl.Constant;
 import org.eclipse.jdt.internal.compiler.impl.IntConstant;
+//import org.eclipse.jdt.internal.compiler.impl.IntConstant;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
@@ -31,6 +39,8 @@
 
 	public Expression constantExpression;
 	public BranchLabel targetLabel;
+	public Expression[] constantExpressions; // case with multiple expressions
+	public boolean isExpr = false;
 
 public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
 	this.constantExpression = constantExpression;
@@ -43,13 +53,23 @@
 	BlockScope currentScope,
 	FlowContext flowContext,
 	FlowInfo flowInfo) {
-
-	if (this.constantExpression != null) {
-		if (this.constantExpression.constant == Constant.NotAConstant
-				&& !this.constantExpression.resolvedType.isEnum()) {
-			currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression);
+	if (this.constantExpressions != null && this.constantExpressions.length > 1) {
+		for (Expression e : this.constantExpressions) {
+			if (e.constant == Constant.NotAConstant
+					&& !e.resolvedType.isEnum()) {
+				currentScope.problemReporter().caseExpressionMustBeConstant(e);
+			}
+			this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
 		}
-		this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
+		
+	} else {
+		if (this.constantExpression != null) {
+			if (this.constantExpression.constant == Constant.NotAConstant
+					&& !this.constantExpression.resolvedType.isEnum()) {
+				currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression);
+			}
+			this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
+		}
 	}
 	return flowInfo;
 }
@@ -58,10 +78,19 @@
 public StringBuffer printStatement(int tab, StringBuffer output) {
 	printIndent(tab, output);
 	if (this.constantExpression == null) {
-		output.append("default :"); //$NON-NLS-1$
+		output.append("default "); //$NON-NLS-1$
+		output.append(this.isExpr ? "->" : ":"); //$NON-NLS-1$ //$NON-NLS-2$
 	} else {
 		output.append("case "); //$NON-NLS-1$
-		this.constantExpression.printExpression(0, output).append(" :"); //$NON-NLS-1$
+		if (this.constantExpressions != null && this.constantExpressions.length > 0) {
+			for (int i = 0, l = this.constantExpressions.length; i < l; ++i) {
+				this.constantExpressions[i].printExpression(0, output);
+				if (i < l -1) output.append(',');
+			}
+		} else {
+			this.constantExpression.printExpression(0, output);
+		}
+		output.append(this.isExpr ? " ->" : " :"); //$NON-NLS-1$ //$NON-NLS-2$
 	}
 	return output;
 }
@@ -90,10 +119,10 @@
 
 /**
  * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE
- * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement)
+ * see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement)
  */
 @Override
-public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) {
+public Constant[] resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) {
 	// switchExpressionType maybe null in error case
 	scope.enclosingCase = this; // record entering in a switch case block
 
@@ -104,26 +133,55 @@
 
 		// on error the last default will be the selected one ...
 		switchStatement.defaultCase = this;
-		return Constant.NotAConstant;
+		return Constant.NotAConstantList;
 	}
 	// add into the collection of cases of the associated switch statement
 	switchStatement.cases[switchStatement.caseCount++] = this;
-	// tag constant name with enum type for privileged access to its members
 	if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) {
 		((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType);
 	}
 	TypeBinding caseType = this.constantExpression.resolveType(scope);
-	if (caseType == null || switchExpressionType == null) return Constant.NotAConstant;
-	if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType)
+	if (caseType == null || switchExpressionType == null) return Constant.NotAConstantList;
+	// tag constant name with enum type for privileged access to its members
+
+	if (this.constantExpressions != null && this.constantExpressions.length > 1) {
+		List<Constant> cases = new ArrayList<>();
+		for (Expression e : this.constantExpressions) {
+			if (e != this.constantExpression) {
+				if (switchExpressionType.isEnum() && (e instanceof SingleNameReference)) {
+					((SingleNameReference) e).setActualReceiverType((ReferenceBinding)switchExpressionType);
+				}
+				e.resolveType(scope);
+			}
+			Constant con = resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, e);
+			if (con != Constant.NotAConstant) {
+				cases.add(con);
+			}
+		}
+		if (cases.size() > 0) {
+			return cases.toArray(new Constant[cases.size()]);
+		}
+	} else {
+		return new Constant[] { resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, this.constantExpression) };
+	}
+	return Constant.NotAConstantList;
+}
+public Constant resolveConstantExpression(BlockScope scope, 
+											TypeBinding caseType, 
+											TypeBinding switchExpressionType, 
+											SwitchStatement switchStatement, 
+											Expression expression) {
+	
+	if (expression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType)
 			|| caseType.isCompatibleWith(switchExpressionType)) {
 		if (caseType.isEnum()) {
-			if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
-				scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression);
+			if (((expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) {
+				scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(expression);
 			}
 
-			if (this.constantExpression instanceof NameReference
-					&& (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) {
-				NameReference reference = (NameReference) this.constantExpression;
+			if (expression instanceof NameReference
+					&& (expression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) {
+				NameReference reference = (NameReference) expression;
 				FieldBinding field = reference.fieldBinding();
 				if ((field.modifiers & ClassFileConstants.AccEnum) == 0) {
 					 scope.problemReporter().enumSwitchCannotTargetField(reference, field);
@@ -133,11 +191,11 @@
 				return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810
 			}
 		} else {
-			return this.constantExpression.constant;
+			return expression.constant;
 		}
-	} else if (isBoxingCompatible(caseType, switchExpressionType, this.constantExpression, scope)) {
+	} else if (isBoxingCompatible(caseType, switchExpressionType, expression, scope)) {
 		// constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion
-		return this.constantExpression.constant;
+		return expression.constant;
 	}
 	scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression, switchStatement.expression);
 	return Constant.NotAConstant;
@@ -146,7 +204,14 @@
 @Override
 public void traverse(ASTVisitor visitor, 	BlockScope blockScope) {
 	if (visitor.visit(this, blockScope)) {
-		if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope);
+		if (this.constantExpressions != null && this.constantExpressions.length > 1) {
+			for (Expression e : this.constantExpressions) {
+				e.traverse(visitor, blockScope);
+			}
+		} else {
+			if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope);
+		}
+		
 	}
 	visitor.endVisit(this, blockScope);
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
index df72bd0..00632c9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephen Herrmann <stephan@cs.tu-berlin.de> -  Contributions for
@@ -223,14 +227,8 @@
 
 		// is there a chance of null (or non-null)? -> potentially null etc.
 		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
-		int status = 0;
 		int combinedStatus = this.ifTrueNullStatus|this.ifFalseNullStatus;
-		if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
-			status |= FlowInfo.POTENTIALLY_NULL;
-		if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
-			status |= FlowInfo.POTENTIALLY_NON_NULL;
-		if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
-			status |= FlowInfo.POTENTIALLY_UNKNOWN;
+		int status = Expression.computeNullStatus(0, combinedStatus);
 		if (status > 0)
 			this.nullStatus = status;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
index 56b6f8f..5b8054c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for 
@@ -732,6 +736,15 @@
 	}
 }
 
+public static int computeNullStatus(int status, int combinedStatus) {
+	if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
+		status |= FlowInfo.POTENTIALLY_NULL;
+	if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
+		status |= FlowInfo.POTENTIALLY_NON_NULL;
+	if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
+		status |= FlowInfo.POTENTIALLY_UNKNOWN;
+	return status;
+}
 /**
  * Expression statements are plain expressions, however they generate like
  * normal expressions with no value required.
@@ -1057,6 +1070,10 @@
 	this.resolveType(scope);
 	return;
 }
+@Override
+public TypeBinding resolveExpressionType(BlockScope scope) {
+	return resolveType(scope);
+}
 
 /**
  * Resolve the type of this expression in the context of a blockScope
@@ -1161,6 +1178,12 @@
 		if (ternary.valueIfTrue.forcedToBeRaw(referenceContext) || ternary.valueIfFalse.forcedToBeRaw(referenceContext)) {
 			return true;
 		}
+	} else if (this instanceof SwitchExpression) {
+		SwitchExpression se = (SwitchExpression) this;
+		for (Expression e : se.resultExpressions) {
+			if (e.forcedToBeRaw(referenceContext))
+				return true;
+		}
 	}
 	return false;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
index 8498b31..c42d403 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2011, 2016 GK Software AG and others.
+ * Copyright (c) 2011, 2019 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     Nikolay Metchev (nikolaymetchev@gmail.com) - Contributions for
@@ -180,6 +184,14 @@
 					return falseTrackingVariable;
 				}
 				return getCloseTrackingVariable(((ConditionalExpression)expression).valueIfTrue, flowInfo, flowContext);
+			} else if (expression instanceof SwitchExpression) {
+				for (Expression re : ((SwitchExpression) expression).resultExpressions) {
+					FakedTrackingVariable fakedTrackingVariable = getCloseTrackingVariable(re, flowInfo, flowContext);
+					if (fakedTrackingVariable != null) {
+						return fakedTrackingVariable;
+					}
+				}
+				return null;
 			}
 			else
 				break;
@@ -242,12 +254,21 @@
 		}
 	}
 
+	private static boolean containsAllocation(SwitchExpression location) {
+		for (Expression re : location.resultExpressions) {
+			if (containsAllocation(re))
+				return true;
+		}
+		return false;
+	}
 	private static boolean containsAllocation(ASTNode location) {
 		if (location instanceof AllocationExpression)
 			return true;
 		if (location instanceof ConditionalExpression) {
 			ConditionalExpression conditional = (ConditionalExpression) location;
 			return containsAllocation(conditional.valueIfTrue) || containsAllocation(conditional.valueIfFalse);
+		} else if (location instanceof SwitchExpression) {
+			return containsAllocation((SwitchExpression) location);
 		}
 		if (location instanceof CastExpression)
 			return containsAllocation(((CastExpression) location).expression);
@@ -260,6 +281,8 @@
 			preConnectTrackerAcrossAssignment(location, local, flowInfo, (AllocationExpression) expression, closeTracker);
 		} else if (expression instanceof ConditionalExpression) {
 			preConnectTrackerAcrossAssignment(location, local, flowInfo, (ConditionalExpression) expression, closeTracker);
+		}  else if (expression instanceof SwitchExpression) {
+			preConnectTrackerAcrossAssignment(location, local, flowInfo, (SwitchExpression) expression, closeTracker);
 		} else if (expression instanceof CastExpression) {
 			preConnectTrackerAcrossAssignment(location, local, ((CastExpression) expression).expression, flowInfo);
 		}
@@ -272,6 +295,13 @@
 	}
 
 	private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo,
+			SwitchExpression se, FakedTrackingVariable closeTracker) {
+		for (Expression re : se.resultExpressions) {
+			preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, re);
+		}
+	}
+
+	private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo,
 			AllocationExpression allocationExpression, FakedTrackingVariable closeTracker) {
 		allocationExpression.closeTracker = closeTracker;
 		if (allocationExpression.arguments != null && allocationExpression.arguments.length > 0) {
@@ -456,7 +486,7 @@
 						rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR);
 					}
 				} else {
-					if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) {
+					if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression || rhs instanceof SwitchExpression) {
 						if (rhsTrackVar == disconnectedTracker)
 							return;									// 		b.: self wrapper: res = new Wrap(res); -> done!
 						if (local.closeTracker == rhsTrackVar 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
index 1cd7e21..b67c1a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
@@ -245,6 +249,14 @@
 			}
 			if (candidate != null) return candidate;
 		}
+		if (e instanceof SwitchExpression) {
+			SwitchExpression se = (SwitchExpression)e;
+			se.collectResultExpressions();
+			for (Expression re : se.resultExpressions) {
+				Expression candidate = findPolyExpression(re);
+				if (candidate != null) return candidate;
+			}
+		}
 		return null;
 	}
 	
@@ -357,6 +369,7 @@
 				&& variableType != null && variableType.isValidBinding()) { 
 			resolveAnnotationsEarly = this.initialization instanceof Invocation
 					|| this.initialization instanceof ConditionalExpression
+					|| this.initialization instanceof SwitchExpression
 					|| this.initialization instanceof ArrayInitializer;
 		}
 		if (resolveAnnotationsEarly) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
index 4c47725..41b3888 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2016 GK Software AG and others.
+ * Copyright (c) 2013, 2019 GK Software AG and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     Till Brychcy - Contributions for
@@ -159,6 +163,19 @@
 				if (status1 == status2)
 					return status1;
 				return nullStatus; // if both branches disagree use the precomputed & merged nullStatus
+			} else if (expression instanceof SwitchExpression && expression.isPolyExpression()) {
+				// drill into all the branches:
+				SwitchExpression se = ((SwitchExpression) expression);
+				Expression[] resExprs = se.resultExpressions.toArray(new Expression[0]);
+				Expression re = resExprs[0];
+				int status0 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType);
+				boolean identicalStatus = true;
+				for (int i = 1, l = resExprs.length; i < l; ++i) {
+					re = resExprs[i];
+					int otherStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo,  re.nullStatus(flowInfo, flowContext), re, re.resolvedType);
+					identicalStatus &= status0 == otherStatus;		
+				}
+				return identicalStatus ? status0 : nullStatus; // if not all branches agree use the precomputed & merged nullStatus
 			}
 			lhsTagBits = var.type.tagBits & TagBits.AnnotationNullMASK;
 			NullAnnotationMatching annotationStatus = analyse(var.type, providedType, null, null, nullStatus, expression, CheckMode.COMPATIBLE);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index d5b9f6f..56b3ca3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -90,7 +90,7 @@
 		flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
 		this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
 		if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled)
-			checkAgainstNullAnnotation(currentScope, flowContext, flowInfo);
+			checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression);
 		if (currentScope.compilerOptions().analyseResourceLeaks) {
 			FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression, flowInfo, flowContext);
 			if (trackingVariable != null) {
@@ -182,29 +182,6 @@
 public boolean doesNotCompleteNormally() {
 	return true;
 }
-void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
-	int nullStatus = this.expression.nullStatus(flowInfo, flowContext);
-	long tagBits;
-	MethodBinding methodBinding = null;
-	boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations();
-	try {
-		methodBinding = scope.methodScope().referenceMethodBinding();
-		tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits;
-	} catch (NullPointerException npe) {
-		// chain of references in try-block has several potential nulls;
-		// any null means we cannot perform the following check
-		return;			
-	}
-	if (useTypeAnnotations) {
-		checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, this.expression, flowContext, flowInfo);
-	} else if (nullStatus != FlowInfo.NON_NULL) {
-		// if we can't prove non-null check against declared null-ness of the enclosing method:
-		if ((tagBits & TagBits.AnnotationNonNull) != 0) {
-			flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null);
-		}
-	}
-}
-
 /**
  * Retrun statement code generation
  *
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
index 35967ab..a4a9abb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
@@ -63,6 +67,7 @@
 	public char[] token;
 	public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor
 	public TypeBinding genericCast;
+	public boolean isLabel;// flagging for break expression when expression is SwitchExpression - java 12 preview-feature
 
 public SingleNameReference(char[] source, long pos) {
 	super();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 5bfb045..56991a4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for
@@ -176,7 +180,16 @@
 		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfTrue, flowInfo, ce.ifTrueNullStatus, expectedNonNullness, originalExpected);
 		ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfFalse, flowInfo, ce.ifFalseNullStatus, expectedNonNullness, originalExpected);
 		return;
+	} else 	if (argument instanceof SwitchExpression && argument.isPolyExpression()) {
+		SwitchExpression se = (SwitchExpression) argument;
+		for (int i = 0; i < se.resultExpressions.size(); i++) {
+			se.internalAnalyseOneArgument18(currentScope, flowContext, expectedType,
+					se.resultExpressions.get(i), flowInfo,
+					se.resultExpressionNullStatus.get(i), expectedNonNullness, originalExpected);
+		}
+		return;
 	}
+
 	int nullStatus = argument.nullStatus(flowInfo, flowContext);
 	internalAnalyseOneArgument18(currentScope, flowContext, expectedType, argument, flowInfo,
 									nullStatus, expectedNonNullness, originalExpected);
@@ -204,6 +217,28 @@
 		flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus, annotationStatus);
 	}
 }
+/* package */ void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, Expression expr) {
+	int nullStatus = expr.nullStatus(flowInfo, flowContext);
+	long tagBits;
+	MethodBinding methodBinding = null;
+	boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations();
+	try {
+		methodBinding = scope.methodScope().referenceMethodBinding();
+		tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits;
+	} catch (NullPointerException npe) {
+		// chain of references in try-block has several potential nulls;
+		// any null means we cannot perform the following check
+		return;			
+	}
+	if (useTypeAnnotations) {
+		checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, expr, flowContext, flowInfo);
+	} else if (nullStatus != FlowInfo.NON_NULL) {
+		// if we can't prove non-null check against declared null-ness of the enclosing method:
+		if ((tagBits & TagBits.AnnotationNonNull) != 0) {
+			flowContext.recordNullityMismatch(scope, expr, expr.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null);
+		}
+	}
+}
 
 protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requiredType, Expression expression, FlowContext flowContext, FlowInfo flowInfo) {
 	if (expression instanceof ConditionalExpression && expression.isPolyExpression()) {
@@ -212,6 +247,14 @@
 		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfTrue, ce.ifTrueNullStatus, flowContext, flowInfo);
 		internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfFalse, ce.ifFalseNullStatus, flowContext, flowInfo);
 		return;
+	} else 	if (expression instanceof SwitchExpression && expression.isPolyExpression()) {
+		SwitchExpression se = (SwitchExpression) expression;
+		for (int i = 0; i < se.resultExpressions.size(); i++) {
+			internalCheckAgainstNullTypeAnnotation(scope, requiredType, 
+					se.resultExpressions.get(i), 
+					se.resultExpressionNullStatus.get(i), flowContext, flowInfo);
+		}
+		return;
 	}
 	int nullStatus = expression.nullStatus(flowInfo, flowContext);
 	internalCheckAgainstNullTypeAnnotation(scope, requiredType, expression, nullStatus, flowContext, flowInfo);
@@ -423,11 +466,19 @@
 
 /**
  * Returns case constant associated to this statement (NotAConstant if none)
+ * parameter statement has to be either a SwitchStatement or a SwitchExpression
  */
-public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
+public Constant[] resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
 	// statement within a switch that are not case are treated as normal statement....
 	resolve(scope);
-	return Constant.NotAConstant;
+	return new Constant[] {Constant.NotAConstant};
+}
+/**
+ * Returns the resolved expression if any associated to this statement - used
+ * parameter statement has to be either a SwitchStatement or a SwitchExpression
+ */
+public TypeBinding resolveExpressionType(BlockScope scope) {
+	return null;
 }
 /** 
  * Implementation of {@link org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java
new file mode 100644
index 0000000..0860ac3
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java
@@ -0,0 +1,696 @@
+/*******************************************************************************
+ * Copyright (c) 2018, 2019 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.ast;
+
+import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.ASSIGNMENT_CONTEXT;
+import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.INVOCATION_CONTEXT;
+import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.VANILLA_CONTEXT;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
+import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.Constant;
+import org.eclipse.jdt.internal.compiler.lookup.Binding;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
+import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
+
+public class SwitchExpression extends SwitchStatement implements IPolyExpression {
+
+	/* package */ TypeBinding expectedType;
+	private ExpressionContext expressionContext = VANILLA_CONTEXT;
+	private boolean isPolyExpression = false;
+	private TypeBinding[] originalValueResultExpressionTypes;
+	private TypeBinding[] finalValueResultExpressionTypes;
+
+	private int nullStatus = FlowInfo.UNKNOWN;
+	public List<Expression> resultExpressions;
+	public boolean resolveAll;
+	/* package */ List<Integer> resultExpressionNullStatus;
+	private static Map<TypeBinding, TypeBinding[]> type_map;
+
+	static {
+		type_map = new HashMap<TypeBinding, TypeBinding[]>();
+		type_map.put(TypeBinding.CHAR, new TypeBinding[] {TypeBinding.CHAR, TypeBinding.BYTE, TypeBinding.INT});
+		type_map.put(TypeBinding.SHORT, new TypeBinding[] {TypeBinding.SHORT, TypeBinding.BYTE, TypeBinding.INT});
+		type_map.put(TypeBinding.BYTE, new TypeBinding[] {TypeBinding.BYTE, TypeBinding.INT});
+	}
+
+	@Override
+	public void setExpressionContext(ExpressionContext context) {
+		this.expressionContext = context;
+	}
+
+	@Override
+	public void setExpectedType(TypeBinding expectedType) {
+		this.expectedType = expectedType;
+	}
+
+	@Override
+	public ExpressionContext getExpressionContext() {
+		return this.expressionContext;
+	}
+	@Override
+	protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) {
+		return isEnumSwitch; // mandatory error if not enum in switch expressions
+	}
+	@Override
+	protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) {
+		upperScope.problemReporter().missingEnumConstantCase(this, enumConstant);
+	}
+	@Override
+	protected int getFallThroughState(Statement stmt, BlockScope blockScope) {
+		if (stmt instanceof Expression || stmt instanceof ThrowStatement)
+			return BREAKING;
+		if (this.switchLabeledRules // do this check for every block if '->' (Switch Labeled Rules) 
+				&& stmt instanceof Block) {
+			Block block = (Block) stmt;
+			if (block.doesNotCompleteNormally()) {
+				return BREAKING;
+			}
+			//JLS 12 15.28.1 Given a switch expression, if the switch block consists of switch labeled rules,
+			//then it is a compile-time error if any switch labeled block can complete normally.
+			blockScope.problemReporter().switchExpressionSwitchLabeledBlockCompletesNormally(block);
+		}
+		return FALLTHROUGH;
+	}
+	@Override
+	public boolean checkNPE(BlockScope skope, FlowContext flowContext, FlowInfo flowInfo, int ttlForFieldCheck) {
+		if ((this.nullStatus & FlowInfo.NULL) != 0)
+			skope.problemReporter().expressionNullReference(this);
+		else if ((this.nullStatus & FlowInfo.POTENTIALLY_NULL) != 0)
+			skope.problemReporter().expressionPotentialNullReference(this);
+		return true; // all checking done
+	}
+
+	private void computeNullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		 boolean precomputed = this.resultExpressionNullStatus.size() > 0;
+		 if (!precomputed)
+		         this.resultExpressionNullStatus.add(this.resultExpressions.get(0).nullStatus(flowInfo, flowContext));	int status =  this.resultExpressions.get(0).nullStatus(flowInfo, flowContext);
+		int combinedStatus = status;
+		boolean identicalStatus = true;
+		for (int i = 1, l = this.resultExpressions.size(); i < l; ++i) {
+		    if (!precomputed)
+	             this.resultExpressionNullStatus.add(this.resultExpressions.get(i).nullStatus(flowInfo, flowContext));
+		    int tmp = this.resultExpressions.get(i).nullStatus(flowInfo, flowContext);
+			identicalStatus &= status == tmp;
+			combinedStatus |= tmp;
+		}
+		if (identicalStatus) {
+			this.nullStatus = status;
+			return;
+		}
+		status = Expression.computeNullStatus(0, combinedStatus);
+		if (status > 0)
+			this.nullStatus = status;
+	}
+
+	@Override
+	protected void completeNormallyCheck(BlockScope blockScope) {
+		if (this.switchLabeledRules) return; // already taken care in getFallThroughState()
+		int sz = this.statements != null ? this.statements.length : 0;
+		if (sz == 0) return;
+		/* JLS 12 15.28.1
+		 * If, on the other hand, the switch block consists of switch labeled statement groups, then it is a
+		 * compile-time error if either the last statement in the switch block can complete normally, or the
+		 * switch block includes one or more switch labels at the end.
+		 */
+		Statement lastNonCaseStmt = null;
+		Statement firstTrailingCaseStmt = null;
+		for (int i = sz - 1; i >= 0; i--) {
+			Statement stmt = this.statements[sz - 1];
+			if (stmt instanceof CaseStatement)
+				firstTrailingCaseStmt = stmt;
+			else {
+				lastNonCaseStmt = stmt;
+				break;
+			}
+		}
+		if (lastNonCaseStmt != null && !lastNonCaseStmt.doesNotCompleteNormally()) {
+			blockScope.problemReporter().switchExpressionLastStatementCompletesNormally(lastNonCaseStmt);				
+		}
+		if (firstTrailingCaseStmt != null) {
+			blockScope.problemReporter().switchExpressionTrailingSwitchLabels(firstTrailingCaseStmt);				
+		}
+	}
+	@Override
+	public Expression[] getPolyExpressions() {
+		List<Expression> polys = new ArrayList<>();
+		for (Expression e : this.resultExpressions) {
+			Expression[] ea = e.getPolyExpressions();
+			if (ea == null || ea.length ==0) continue;
+			polys.addAll(Arrays.asList(ea));
+		}
+		return polys.toArray(new Expression[0]);
+	}
+	@Override
+	public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) {
+		for (Expression e : this.resultExpressions) {
+			if (!e.isPertinentToApplicability(targetType, method))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope1) {
+		for (Expression e : this.resultExpressions) {
+			if (!e.isPotentiallyCompatibleWith(targetType, scope1))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public boolean isFunctionalType() {
+		for (Expression e : this.resultExpressions) {
+			if (e.isFunctionalType()) // return true even for one functional type
+				return true;
+		}
+		return false;
+	}
+	@Override
+	public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) {
+		if ((this.implicitConversion & TypeIds.BOXING) != 0)
+			return FlowInfo.NON_NULL;
+		return this.nullStatus;
+	}
+	@Override
+	protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) {
+		if (!(statement instanceof Expression)
+				|| statement instanceof Assignment
+				|| statement instanceof MessageSend
+				|| (statement instanceof SwitchStatement && !(statement instanceof SwitchExpression))) {
+			super.statementGenerateCode(currentScope, codeStream, statement);
+			return;
+		}
+		Expression expression1 = (Expression) statement;
+		expression1.generateCode(currentScope, codeStream, true /* valueRequired */);
+	}
+	@Override
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		super.generateCode(currentScope, codeStream);
+		if (!valueRequired) {
+			// switch expression is saved to a variable that is not used. We need to pop the generated value from the stack
+			switch(postConversionType(currentScope).id) {
+				case TypeIds.T_long :
+				case TypeIds.T_double :
+					codeStream.pop2();
+					break;
+				case TypeIds.T_void :
+					break;
+				default :
+					codeStream.pop();
+					break;
+			}
+		}
+	}
+	protected boolean computeConversions(BlockScope blockScope, TypeBinding targetType) {
+		boolean ok = true;
+		for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) {
+			ok &= computeConversionsResultExpressions(blockScope, targetType, this.originalValueResultExpressionTypes[i], this.resultExpressions.get(i));
+		}
+		return ok;
+	}
+	private boolean computeConversionsResultExpressions(BlockScope blockScope, TypeBinding targetType, TypeBinding resultExpressionType,
+			Expression resultExpression) {
+		if (resultExpressionType != null && resultExpressionType.isValidBinding()) {
+			if (resultExpression.isConstantValueOfTypeAssignableToType(resultExpressionType, targetType)
+					|| resultExpressionType.isCompatibleWith(targetType)) {
+
+				resultExpression.computeConversion(blockScope, targetType, resultExpressionType);
+				if (resultExpressionType.needsUncheckedConversion(targetType)) {
+					blockScope.problemReporter().unsafeTypeConversion(resultExpression, resultExpressionType, targetType);
+				}
+				if (resultExpression instanceof CastExpression
+						&& (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
+					CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression);
+				}
+			} else if (isBoxingCompatible(resultExpressionType, targetType, resultExpression, blockScope)) {
+				resultExpression.computeConversion(blockScope, targetType, resultExpressionType);
+				if (resultExpression instanceof CastExpression
+						&& (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) {
+					CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression);
+				}
+			} else {
+				blockScope.problemReporter().typeMismatchError(resultExpressionType, targetType, resultExpression, null);
+				return false;
+			}
+		}
+		return true;
+	}
+	/* package */ void collectResultExpressions() {
+		if (this.resultExpressions != null)
+			return; // already calculated.
+
+		class ResultExpressionsCollector extends ASTVisitor {
+			Stack<SwitchExpression> targetSwitchExpressions;
+			public ResultExpressionsCollector(SwitchExpression se) {
+				if (this.targetSwitchExpressions == null)
+					this.targetSwitchExpressions = new Stack<>();
+				this.targetSwitchExpressions.push(se);
+			}
+			@Override
+			public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) {
+				if (switchExpression.resultExpressions == null)
+					switchExpression.resultExpressions = new ArrayList<>(0);
+				this.targetSwitchExpressions.push(switchExpression);
+				return true;
+			}
+			@Override
+			public void endVisit(SwitchExpression switchExpression,	BlockScope blockScope) {
+				this.targetSwitchExpressions.pop();
+			}
+			@Override
+			public boolean visit(BreakStatement breakStatement, BlockScope blockScope) {
+				SwitchExpression targetSwitchExpression = this.targetSwitchExpressions.peek();
+				if (breakStatement.expression != null) {
+					targetSwitchExpression.resultExpressions.add(breakStatement.expression);
+					breakStatement.switchExpression = this.targetSwitchExpressions.peek();
+					breakStatement.label = null; // not a label, but an expression
+					if (breakStatement.expression instanceof SingleNameReference) {
+						((SingleNameReference) breakStatement.expression).isLabel = false;
+					}
+				} else {
+					// flag an error while resolving
+					breakStatement.switchExpression = targetSwitchExpression;
+				}
+				return true;
+			}
+			@Override
+			public boolean visit(DoStatement stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(ForStatement stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(ForeachStatement stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(SwitchStatement stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(TypeDeclaration stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(WhileStatement stmt, BlockScope blockScope) {
+				return false;
+			}
+			@Override
+			public boolean visit(CaseStatement caseStatement, BlockScope blockScope) {
+				return true; // do nothing by default, keep traversing
+			}
+		}
+		this.resultExpressions = new ArrayList<>(0); // indicates processed
+		int l = this.statements == null ? 0 : this.statements.length;
+		for (int i = 0; i < l; ++i) {
+			Statement stmt = this.statements[i];
+			if (stmt instanceof CaseStatement) {
+				CaseStatement caseStatement = (CaseStatement) stmt;
+				if (!caseStatement.isExpr) continue;
+				stmt = this.statements[++i];
+				if (stmt instanceof Expression) {
+					this.resultExpressions.add((Expression) stmt);
+					continue;
+				} else if (stmt instanceof ThrowStatement) {
+					// TODO: Throw Expression Processing. Anything to be done here for resolve?
+					continue;
+				}
+			}
+			// break statement and block statement of SwitchLabelRule or block statement of ':'
+			ResultExpressionsCollector reCollector = new ResultExpressionsCollector(this);
+			stmt.traverse(reCollector, this.scope);
+		}
+	}
+	@Override
+	public TypeBinding resolveType(BlockScope upperScope) {
+		try {
+			int resultExpressionsCount;
+			if (this.constant != Constant.NotAConstant) {
+				this.constant = Constant.NotAConstant;
+	
+				// tag break statements and (alongwith in the same pass) collect the result expressions
+				collectResultExpressions();
+	
+				// A switch expression is a poly expression if it appears in an assignment context or an invocation context (5.2, 5.3). 
+				// Otherwise, it is a standalone expression.
+				if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) {
+					for (Expression e : this.resultExpressions) {
+						//Where a poly switch expression appears in a context of a particular kind with target type T,
+						//its result expressions similarly appear in a context of the same kind with target type T.
+						e.setExpressionContext(this.expressionContext);
+						e.setExpectedType(this.expectedType);
+					}
+				}
+	
+				resolve(upperScope);
+	
+				if (this.statements == null || this.statements.length == 0) {
+					//	Report Error JLS 12 15.28.1  The switch block must not be empty.
+					upperScope.problemReporter().switchExpressionEmptySwitchBlock(this);
+					return null;
+				}
+				
+				resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0;
+				if (resultExpressionsCount == 0) {
+					//  Report Error JLS 12 15.28.1 
+					// It is a compile-time error if a switch expression has no result expressions.
+					upperScope.problemReporter().switchExpressionNoResultExpressions(this);
+					return null;
+				}
+	
+				if (this.originalValueResultExpressionTypes == null) {
+					this.originalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount];
+					this.finalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount];
+					for (int i = 0; i < resultExpressionsCount; ++i) {
+						this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] =
+								this.resultExpressions.get(i).resolvedType;
+					}
+				}
+				if (isPolyExpression()) { //The type of a poly switch expression is the same as its target type.
+					if (this.expectedType == null || !this.expectedType.isProperType(true)) {
+						return new PolyTypeBinding(this);
+					}
+					return this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null;
+				}
+				// fall through
+			} else {
+				// re-resolving of poly expression:
+				resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0;
+				for (int i = 0; i < resultExpressionsCount; i++) {
+					Expression resultExpr = this.resultExpressions.get(i);
+					if (resultExpr.resolvedType == null || resultExpr.resolvedType.kind() == Binding.POLY_TYPE) {
+						this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = 
+							resultExpr.resolveTypeExpecting(upperScope, this.expectedType);
+					}
+					// This is a kludge and only way completion can tell this node to resolve all
+					// resultExpressions. Ideal solution is to remove all other expressions except
+					// the one that contain the completion node.
+					if (this.resolveAll) continue;
+					if (resultExpr.resolvedType == null || !resultExpr.resolvedType.isValidBinding())
+						return this.resolvedType = null;
+				}
+				this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null;
+				// fall through
+			}
+
+			if (resultExpressionsCount == 1)
+				return this.resolvedType = this.originalValueResultExpressionTypes[0];
+
+			boolean typeUniformAcrossAllArms = true;
+			TypeBinding tmp = this.originalValueResultExpressionTypes[0];
+			for (int i = 1, l = this.originalValueResultExpressionTypes.length; i < l; ++i) {
+				TypeBinding originalType = this.originalValueResultExpressionTypes[i];
+				if (originalType != null && TypeBinding.notEquals(tmp, originalType)) {
+					typeUniformAcrossAllArms = false;
+					break;
+				}
+			}
+			// If the result expressions all have the same type (which may be the null type), 
+			// then that is the type of the switch expression.
+			if (typeUniformAcrossAllArms) {
+				tmp = this.originalValueResultExpressionTypes[0];
+				for (int i = 1; i < resultExpressionsCount; ++i) {
+					if (this.originalValueResultExpressionTypes[i] != null)
+						tmp = NullAnnotationMatching.moreDangerousType(tmp, this.originalValueResultExpressionTypes[i]);
+				}
+				return this.resolvedType = tmp;
+			}
+			
+			boolean typeBbolean = true;
+			for (TypeBinding t : this.originalValueResultExpressionTypes) {
+				if (t != null)
+					typeBbolean &= t.id == T_boolean || t.id == T_JavaLangBoolean;
+			}
+			LookupEnvironment env = this.scope.environment();
+			/*
+			 * Otherwise, if the type of each result expression is boolean or Boolean,
+			 * an unboxing conversion (5.1.8) is applied to each result expression of type Boolean,
+			 * and the switch expression has type boolean.
+			 */
+			if (typeBbolean) {
+				for (int i = 0; i < resultExpressionsCount; ++i) {
+					if (this.originalValueResultExpressionTypes[i].id == T_boolean) continue;
+					this.finalValueResultExpressionTypes[i] = env.computeBoxingType(this.originalValueResultExpressionTypes[i]);
+					this.resultExpressions.get(i).computeConversion(this.scope, this.finalValueResultExpressionTypes[i], this.originalValueResultExpressionTypes[i]);
+				}
+				return this.resolvedType = TypeBinding.BOOLEAN;
+			}
+
+			/*
+			 * Otherwise, if the type of each result expression is convertible to a numeric type (5.1.8), the type
+			 * of the switch expression is given by numeric promotion (5.6.3) applied to the result expressions.
+			 */
+			boolean typeNumeric = true;
+			TypeBinding resultNumeric = null;
+			HashSet<TypeBinding> typeSet = new HashSet<>();
+			/*  JLS 12 5.6.3 Switch Numeric Promotion
+			 * When a switch expression applies numeric promotion to a set of result expressions, each of which
+			 * must denote a value that is convertible to a numeric type, the following rules apply, in order:
+			 *  If any result expression is of a reference type, it is subjected to unboxing conversion (5.1.8).
+			 */
+			for (int i = 0; i < resultExpressionsCount; ++i) {
+				TypeBinding originalType = this.originalValueResultExpressionTypes[i];
+				if (originalType == null) continue;
+				tmp = originalType.isNumericType() ? originalType : env.computeBoxingType(originalType);
+				if (!tmp.isNumericType()) {
+					typeNumeric = false;
+					break;
+				}
+				typeSet.add(TypeBinding.wellKnownType(this.scope, tmp.id));
+			}
+			if (typeNumeric) {
+				 /* If any result expression is of type double, then other result expressions that are not of type double
+				 *  are widened to double.
+				 *  Otherwise, if any result expression is of type float, then other result expressions that are not of
+				 *  type float are widened to float.
+				 *  Otherwise, if any result expression is of type long, then other result expressions that are not of 
+				 *  type long are widened to long.
+				 */
+				TypeBinding[] dfl = new TypeBinding[]{// do not change the order JLS 12 5.6.3
+						TypeBinding.DOUBLE,
+						TypeBinding.FLOAT,
+						TypeBinding.LONG};
+				for (TypeBinding binding : dfl) {
+					if (typeSet.contains(binding)) {
+						resultNumeric = binding;
+						break;
+					}
+				}
+
+				 /*  Otherwise, if any result expression is of type int and is not a constant expression, the other 
+				 *  result expressions that are not of type int are widened to int.
+				 */
+				resultNumeric = resultNumeric != null ? resultNumeric : check_nonconstant_int();
+
+				resultNumeric = resultNumeric != null ? resultNumeric : // one among the first few rules applied.
+					getResultNumeric(typeSet, this.originalValueResultExpressionTypes); // check the rest
+				typeSet = null; // hey gc!
+				for (int i = 0; i < resultExpressionsCount; ++i) {
+					// auto-unboxing and/or widening/narrrowing JLS 12 5.6.3
+					this.resultExpressions.get(i).computeConversion(this.scope,
+							resultNumeric, this.originalValueResultExpressionTypes[i]);
+					this.finalValueResultExpressionTypes[i] = resultNumeric;
+				}
+				// After the conversion(s), if any, value set conversion (5.1.13) is then applied to each result expression.
+				return this.resolvedType = resultNumeric;
+			}
+
+			/* Otherwise, boxing conversion (5.1.7) is applied to each result expression that has a primitive type,
+			 * after which the type of the switch expression is the result of applying capture conversion (5.1.10)
+			 * to the least upper bound (4.10.4) of the types of the result expressions.
+			 */
+			for (int i = 0; i < resultExpressionsCount; ++i) {
+				TypeBinding finalType = this.finalValueResultExpressionTypes[i];
+				if (finalType != null && finalType.isBaseType())
+					this.finalValueResultExpressionTypes[i] = env.computeBoxingType(finalType);
+			}
+			TypeBinding commonType = this.scope.lowerUpperBound(this.finalValueResultExpressionTypes);
+			if (commonType != null) {
+				for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) {
+					if (this.originalValueResultExpressionTypes[i] == null) continue;
+					this.resultExpressions.get(i).computeConversion(this.scope, commonType, this.originalValueResultExpressionTypes[i]);
+					this.finalValueResultExpressionTypes[i] = commonType;
+				}
+				return this.resolvedType = commonType.capture(this.scope, this.sourceStart, this.sourceEnd);
+			}
+			this.scope.problemReporter().switchExpressionIncompatibleResultExpressions(this);
+			return null;
+		} finally {
+			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
+		}
+	}
+	private TypeBinding check_nonconstant_int() {
+		for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) {
+			Expression e = this.resultExpressions.get(i);
+			TypeBinding type = this.originalValueResultExpressionTypes[i];
+			if (type != null && type.id == T_int && e.constant == Constant.NotAConstant)
+				return TypeBinding.INT;
+		}
+		return null;
+	}
+	private boolean areAllIntegerResultExpressionsConvertibleToTargetType(TypeBinding targetType) {
+		for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) {
+			Expression e = this.resultExpressions.get(i);
+			TypeBinding t = this.originalValueResultExpressionTypes[i];
+			if (!TypeBinding.equalsEquals(t, TypeBinding.INT)) continue;
+			if (!e.isConstantValueOfTypeAssignableToType(t, targetType))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
+		flowInfo = super.analyseCode(currentScope, flowContext, flowInfo);
+		this.resultExpressionNullStatus = new ArrayList<>(0);
+		final CompilerOptions compilerOptions = currentScope.compilerOptions();
+		if (compilerOptions.enableSyntacticNullAnalysisForFields) {
+			for (Expression re : this.resultExpressions) {
+				this.resultExpressionNullStatus.add(re.nullStatus(flowInfo, flowContext));
+				// wipe information that was meant only for this result expression:
+				flowContext.expireNullCheckedFieldInfo();
+			}
+		}
+		computeNullStatus(flowInfo, flowContext);
+		return flowInfo;
+	}
+	private TypeBinding check_csb(Set<TypeBinding> typeSet, TypeBinding candidate) {
+		if (!typeSet.contains(candidate))
+			return null;
+
+		TypeBinding[] allowedTypes = SwitchExpression.type_map.get(candidate);
+		Set<TypeBinding> allowedSet = Arrays.stream(allowedTypes).collect(Collectors.toSet());
+
+		if (!allowedSet.containsAll(typeSet))
+			return null;
+
+		return areAllIntegerResultExpressionsConvertibleToTargetType(candidate) ?
+				candidate : null;
+	}
+	private TypeBinding getResultNumeric(Set<TypeBinding> typeSet, TypeBinding[] armTypes) {
+		// note: if an expression has a type integer, then it will be a constant 
+		// since non-constant integers are already processed before reaching here.
+
+		/*
+		 * Otherwise, if any result expression is of type char, and every other result expression is either of
+		 * type char, or of type byte, or a constant expression of type int with a value that is representable
+		 * in the type char, then the byte results are widened to char and the int results are narrowed to char.
+		 */
+
+		 /*  Otherwise, if any result expression is of type short, and every other result expression is either of
+		 *  type short, or of type byte, or a constant expression of type int with a value that is representable
+		 *  in the type short, then the byte results are widened to short and the int results are narrowed to
+		 *  short.
+		 */
+		 /*  Otherwise, if any result expression is of type byte, and every other result expression is either of
+		 *  type byte or a constant expression of type int with a value that is representable in the type byte,
+		 *  then the int results are narrowed to byte.
+		 */
+
+		// DO NOT Change the order below [as per JLS 12 5.6.3 item 2, sub-items 5,6 and 7].
+		TypeBinding[] csb = new TypeBinding[] {TypeBinding.CHAR, TypeBinding.SHORT, TypeBinding.BYTE};
+		for (TypeBinding c : csb) {
+			TypeBinding result = check_csb(typeSet, c);
+			if (result != null)
+				return result;
+		}
+		 /*  Otherwise, all the result expressions that are not of type int are widened to int. */
+		return TypeBinding.INT;
+	}
+	@Override
+	public boolean isPolyExpression() {
+		if (this.isPolyExpression)
+			return true;
+		// JLS 12 15.28.1 A switch expression is a poly expression if it appears in an assignment context or
+		// an invocation context (5.2, 5.3). Otherwise, it is a standalone expression.
+		return this.isPolyExpression = this.expressionContext == ASSIGNMENT_CONTEXT || 
+				this.expressionContext == INVOCATION_CONTEXT;
+	}
+	@Override
+	public boolean isCompatibleWith(TypeBinding left, Scope skope) {
+		if (!isPolyExpression())
+			return super.isCompatibleWith(left, skope);
+
+		for (Expression e : this.resultExpressions) {
+			if (!e.isCompatibleWith(left, skope))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope skope) {
+		if (!isPolyExpression())
+			return super.isBoxingCompatibleWith(targetType, skope);
+
+		for (Expression e : this.resultExpressions) {
+			if (!(e.isCompatibleWith(targetType, skope) || e.isBoxingCompatibleWith(targetType, skope)))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope skope) {
+		if (super.sIsMoreSpecific(s, t, skope))
+			return true;
+		if (!isPolyExpression())
+			return false;
+		for (Expression e : this.resultExpressions) {
+			if (!e.sIsMoreSpecific(s, t, skope))
+				return false;
+		}
+		return true;
+	}
+	@Override
+	public TypeBinding expectedType() {
+		return this.expectedType;
+	}
+	@Override
+	public void traverse(
+			ASTVisitor visitor,
+			BlockScope blockScope) {
+
+		if (visitor.visit(this, blockScope)) {
+			this.expression.traverse(visitor, blockScope);
+			if (this.statements != null) {
+				int statementsLength = this.statements.length;
+				for (int i = 0; i < statementsLength; i++)
+					this.statements[i].traverse(visitor, this.scope);
+			}
+		}
+		visitor.endVisit(this, blockScope);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
index 15dbd6b..8670e38 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contributions for 
@@ -43,7 +47,7 @@
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
 
 @SuppressWarnings("rawtypes")
-public class SwitchStatement extends Statement {
+public class SwitchStatement extends Expression {
 
 	public Expression expression;
 	public Statement[] statements;
@@ -55,12 +59,15 @@
 	public int blockStart;
 	public int caseCount;
 	int[] constants;
+	int[] constMapping;
 	String[] stringConstants;
+	public boolean switchLabeledRules = false; // true if case ->, false if case :
 
 	// fallthrough
 	public final static int CASE = 0;
 	public final static int FALLTHROUGH = 1;
 	public final static int ESCAPING = 2;
+	public final static int BREAKING  = 3;
 	
 	// for switch on strings
 	private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$
@@ -76,6 +83,38 @@
 	int duplicateCaseStatementsCounter = 0;
 	private LocalVariableBinding dispatchStringCopy = null;
 
+	protected int getFallThroughState(Statement stmt, BlockScope blockScope) {
+		if (this.switchLabeledRules) {
+			if (stmt instanceof Expression || stmt instanceof ThrowStatement)
+				return BREAKING;
+			
+			if (stmt instanceof Block) {
+				Block block = (Block) stmt;
+				if (block.doesNotCompleteNormally()) {
+					return BREAKING;
+				}
+				// else add an implicit break
+				BreakStatement breakStatement = new BreakStatement(null, block.sourceEnd -1, block.sourceEnd);
+				breakStatement.isImplicit = true;
+
+				int l = block.statements == null ? 0 : block.statements.length;
+				if (l == 0) {
+					block.statements = new Statement[] {breakStatement};
+					block.scope = this.scope; // (upper scope) see Block.resolve() for similar
+				} else {
+					Statement[] newArray = new Statement[l + 1];
+					System.arraycopy(block.statements, 0, newArray, 0, l);
+					newArray[l] = breakStatement;
+					block.statements = newArray;
+				}
+				return BREAKING;
+			}
+		}
+		return FALLTHROUGH;
+	}
+	protected void completeNormallyCheck(BlockScope blockScope) {
+		// do nothing
+	}
 	@Override
 	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
 		try {
@@ -120,7 +159,7 @@
 						complaintLevel = initialComplaintLevel; // reset complaint
 						fallThroughState = CASE;
 					} else {
-						fallThroughState = FALLTHROUGH; // reset below if needed
+						fallThroughState = getFallThroughState(statement, currentScope); // reset below if needed
 					}
 					if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) {
 						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
@@ -130,6 +169,7 @@
 						switchContext.expireNullCheckedFieldInfo();
 					}
 				}
+				completeNormallyCheck(currentScope);
 			}
 
 			final TypeBinding resolvedTypeBinding = this.expression.resolvedType;
@@ -199,33 +239,60 @@
 					       "case " + this.hashCode + ":(" + this.string + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$	       
 				}
 			}
-
+			/*
+			 * With multi constant case statements, the number of case statements (hence branch labels)
+			 * and number of constants (hence hashcode labels) could be different. For e.g:
+			  
+			  switch(s) {
+			  	case "FB", "c":
+			  		System.out.println("A/C");
+			 		break;
+			  	case "Ea":
+					System.out.println("B");
+					break;
+					
+				With the above code, we will have 
+				2 branch labels for FB and c
+				3 stringCases for FB, c and Ea
+				2 hashCodeCaseLabels one for FB, Ea and one for c
+				
+				Should produce something like this: 
+				lookupswitch  { // 2
+                      99: 32
+                    2236: 44
+                 default: 87
+				
+				"FB" and "Ea" producing the same hashcode values, but still belonging in different case statements.
+				First, produce the two branch labels pertaining to the case statements
+				And the three string cases and use the this.constMapping to get the correct branch label.
+			 */
 			final boolean hasCases = this.caseCount != 0;
-
-			StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code.
+			int constSize = hasCases ? this.stringConstants.length : 0;
 			BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount];
-			CaseLabel [] hashCodeCaseLabels = new CaseLabel[this.caseCount];
-			this.constants = new int[this.caseCount];  // hashCode() values.
 			for (int i = 0, max = this.caseCount; i < max; i++) {
 				this.cases[i].targetLabel = (sourceCaseLabels[i] = new BranchLabel(codeStream));  // A branch label, not a case label.
 				sourceCaseLabels[i].tagBits |= BranchLabel.USED;
-				stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[i]);
+			}
+			StringSwitchCase [] stringCases = new StringSwitchCase[constSize]; // may have to shrink later if multiple strings hash to same code.
+			CaseLabel [] hashCodeCaseLabels = new CaseLabel[constSize];
+			this.constants = new int[constSize];  // hashCode() values.
+			for (int i = 0; i < constSize; i++) {
+				stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[this.constMapping[i]]);
 				hashCodeCaseLabels[i] = new CaseLabel(codeStream);
 				hashCodeCaseLabels[i].tagBits |= BranchLabel.USED;
-				
 			}
 			Arrays.sort(stringCases);
 
 			int uniqHashCount = 0;
 			int lastHashCode = 0; 
-			for (int i = 0, length = this.caseCount; i < length; ++i) {
+			for (int i = 0, length = constSize; i < length; ++i) {
 				int hashCode = stringCases[i].hashCode;
 				if (i == 0 || hashCode != lastHashCode) {
 					lastHashCode = this.constants[uniqHashCount++] = hashCode;
 				}
 			}
 				
-			if (uniqHashCount != this.caseCount) { // multiple keys hashed to the same value.
+			if (uniqHashCount != constSize) { // multiple keys hashed to the same value.
 				System.arraycopy(this.constants, 0, this.constants = new int[uniqHashCount], 0, uniqHashCount);
 				System.arraycopy(hashCodeCaseLabels, 0, hashCodeCaseLabels = new CaseLabel[uniqHashCount], 0, uniqHashCount);
 			}
@@ -252,7 +319,7 @@
 			codeStream.invokeStringHashCode();
 			if (hasCases) {
 				codeStream.lookupswitch(defaultCaseLabel, this.constants, sortedIndexes, hashCodeCaseLabels);
-				for (int i = 0, j = 0, max = this.caseCount; i < max; i++) {
+				for (int i = 0, j = 0, max = constSize; i < max; i++) {
 					int hashCode = stringCases[i].hashCode;
 					if (i == 0 || hashCode != lastHashCode) {
 						lastHashCode = hashCode;
@@ -291,7 +358,7 @@
 							}
 						}
 					}
-					statement.generateCode(this.scope, codeStream);
+					statementGenerateCode(currentScope, codeStream, statement);
 				}
 			}
 			
@@ -312,6 +379,13 @@
 				defaultCaseLabel.place();
 				defaultBranchLabel.place();
 			}
+			if (this.expectedType() != null) {
+				TypeBinding expectedType = this.expectedType().erasure();
+				boolean optimizedGoto = codeStream.lastAbruptCompletion == -1;
+				// if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the 
+				// stack depth to reflect the fact that there is an value on the stack (return type of the switch expression)
+				codeStream.recordExpressionType(expectedType, optimizedGoto ? 0 : 1, optimizedGoto);
+			}
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 		} finally {
 			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
@@ -339,6 +413,7 @@
 
 			// prepare the labels and constants
 			this.breakLabel.initialize(codeStream);
+			int constantCount = this.constants == null ? 0 : this.constants.length;
 			CaseLabel[] caseLabels = new CaseLabel[this.caseCount];
 			for (int i = 0, max = this.caseCount; i < max; i++) {
 				this.cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream));
@@ -351,19 +426,20 @@
 				this.defaultCase.targetLabel = defaultLabel;
 			}
 
-			final TypeBinding resolvedType = this.expression.resolvedType;
+			final TypeBinding resolvedType1 = this.expression.resolvedType;
 			boolean valueRequired = false;
-			if (resolvedType.isEnum()) {
+			if (resolvedType1.isEnum()) {
 				// go through the translation table
 				codeStream.invoke(Opcodes.OPC_invokestatic, this.synthetic, null /* default declaringClass */);
 				this.expression.generateCode(currentScope, codeStream, true);
 				// get enum constant ordinal()
-				codeStream.invokeEnumOrdinal(resolvedType.constantPoolName());
+				codeStream.invokeEnumOrdinal(resolvedType1.constantPoolName());
 				codeStream.iaload();
 				if (!hasCases) {
 					// we can get rid of the generated ordinal value
 					codeStream.pop();
 				}
+				valueRequired = hasCases;
 			} else {
 				valueRequired = this.expression.constant == Constant.NotAConstant || hasCases;
 				// generate expression
@@ -371,18 +447,18 @@
 			}
 			// generate the appropriate switch table/lookup bytecode
 			if (hasCases) {
-				int[] sortedIndexes = new int[this.caseCount];
+				int[] sortedIndexes = new int[constantCount];
 				// we sort the keys to be able to generate the code for tableswitch or lookupswitch
-				for (int i = 0; i < this.caseCount; i++) {
+				for (int i = 0; i < constantCount; i++) {
 					sortedIndexes[i] = i;
 				}
 				int[] localKeysCopy;
-				System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount);
-				CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes);
+				System.arraycopy(this.constants, 0, (localKeysCopy = new int[constantCount]), 0, constantCount);
+				CodeStream.sort(localKeysCopy, 0, constantCount - 1, sortedIndexes);
 
-				int max = localKeysCopy[this.caseCount - 1];
+				int max = localKeysCopy[constantCount - 1];
 				int min = localKeysCopy[0];
-				if ((long) (this.caseCount * 2.5) > ((long) max - (long) min)) {
+				if ((long) (constantCount * 2.5) > ((long) max - (long) min)) {
 
 					// work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode
 					// see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557
@@ -396,6 +472,7 @@
 							max,
 							this.constants,
 							sortedIndexes,
+							this.constMapping,
 							caseLabels);
 					}
 				} else {
@@ -411,7 +488,7 @@
 			if (this.statements != null) {
 				for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) {
 					Statement statement = this.statements[i];
-					if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case
+					if ((caseIndex < constantCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case
 						this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block
 						if (this.preSwitchInitStateIndex != -1) {
 							codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
@@ -425,9 +502,30 @@
 							}
 						}
 					}
-					statement.generateCode(this.scope, codeStream);
+					statementGenerateCode(currentScope, codeStream, statement);
 				}
 			}
+			boolean enumInSwitchExpression =  resolvedType1.isEnum() && this instanceof SwitchExpression;
+			boolean isEnumSwitchWithoutDefaultCase = this.defaultCase == null && enumInSwitchExpression;
+			if (isEnumSwitchWithoutDefaultCase) {
+				// we want to force an line number entry to get an end position after the switch statement
+				if (this.preSwitchInitStateIndex != -1) {
+					codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex);
+				}
+				defaultLabel.place();
+				/* a default case is not needed for enum if all enum values are used in the switch expression
+				 * we need to handle the default case to throw an error (IncompatibleClassChangeError) in order
+				 * to make the stack map consistent. All cases will return a value on the stack except the missing default
+				 * case.
+				 * There is no returned value for the default case so we handle it with an exception thrown. An
+				 * IllegalClassChangeError seems legitimate as this would mean the enum type has been recompiled with more 
+				 * enum constants and the class that is using the switch on the enum has not been recompiled
+				 */
+				codeStream.newJavaLangIncompatibleClassChangeError();
+				codeStream.dup();
+				codeStream.invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor();
+				codeStream.athrow();
+			}
 			// May loose some local variable initializations : affecting the local variable attributes
 			if (this.mergedInitStateIndex != -1) {
 				codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex);
@@ -438,18 +536,35 @@
 			}
 			// place the trailing labels (for break and default case)
 			this.breakLabel.place();
-			if (this.defaultCase == null) {
+			if (this.defaultCase == null && !enumInSwitchExpression) {
 				// we want to force an line number entry to get an end position after the switch statement
 				codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true);
 				defaultLabel.place();
 			}
+			if (this instanceof SwitchExpression) {
+				TypeBinding switchResolveType = this.resolvedType;
+				if (this.expectedType() != null) {
+					switchResolveType = this.expectedType().erasure();
+				}
+				boolean optimizedGoto = codeStream.lastAbruptCompletion == -1;
+				// if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the 
+				// stack depth to reflect the fact that there is an value on the stack (return type of the switch expression)
+				codeStream.recordExpressionType(switchResolveType, optimizedGoto ? 0 : 1, optimizedGoto || isEnumSwitchWithoutDefaultCase);
+			}
 			codeStream.recordPositionsFrom(pc, this.sourceStart);
 		} finally {
 			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
 		}
 	}
+	protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) {
+		statement.generateCode(this.scope, codeStream);
+	}
 
 	@Override
+	public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+		generateCode(currentScope, codeStream); // redirecting to statement part
+	}
+	@Override
 	public StringBuffer printStatement(int indent, StringBuffer output) {
 
 		printIndent(indent, output).append("switch ("); //$NON-NLS-1$
@@ -519,32 +634,52 @@
 				this.cases = new CaseStatement[length = this.statements.length];
 				if (!isStringSwitch) {
 					this.constants = new int[length];
+					this.constMapping = new int[length];
 				} else {
 					this.stringConstants = new String[length];
+					this.constMapping = new int[length];
 				}
 				int counter = 0;
 				for (int i = 0; i < length; i++) {
-					Constant constant;
+					Constant[] constantsList;
 					final Statement statement = this.statements[i];
-					if ((constant = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) {
-						if (!isStringSwitch) {
-							int key = constant.intValue();
-							//----check for duplicate case statement------------
-							for (int j = 0; j < counter; j++) {
-								if (this.constants[j] == key) {
-									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+					if (!(statement instanceof CaseStatement))  {
+						statement.resolve(this.scope);
+						continue;
+					}
+					if ((constantsList = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstantList) {
+						for (Constant con : constantsList) {
+							if (con == Constant.NotAConstant) 
+								continue;
+							if (!isStringSwitch) {
+								int key = con.intValue();
+								//----check for duplicate case statement------------
+								for (int j = 0; j < counter; j++) {
+									if (this.constants[j] == key) {
+										reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+									}
 								}
-							}
-							this.constants[counter++] = key;
-						} else {
-							String key = constant.stringValue();
-							//----check for duplicate case statement------------
-							for (int j = 0; j < counter; j++) {
-								if (this.stringConstants[j].equals(key)) {
-									reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+								if (this.constants.length == counter) {
+									System.arraycopy(this.constants, 0, this.constants = new int[counter+1], 0, counter);
+									System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter);
 								}
+								this.constants[counter] = key;
+								this.constMapping[counter++] = this.caseCount - 1;
+							} else {
+								String key = con.stringValue();
+								//----check for duplicate case statement------------
+								for (int j = 0; j < counter; j++) {
+									if (this.stringConstants[j].equals(key)) {
+										reportDuplicateCase((CaseStatement) statement, this.cases[j], length);
+									}
+								}
+								if (this.stringConstants.length == counter) {
+									System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter+1], 0, counter);
+									System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter);
+								}
+								this.stringConstants[counter] = key;
+								this.constMapping[counter++] = this.caseCount - 1;
 							}
-							this.stringConstants[counter++] = key;			
 						}
 					}
 				}
@@ -554,15 +689,17 @@
 					} else {
 						System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter], 0, counter);
 					}
+					System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter], 0, counter);
 				}
 			} else {
 				if ((this.bits & UndocumentedEmptyBlock) != 0) {
 					upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd);
 				}
 			}
+			reportMixingCaseTypes();
 			// check default case for all kinds of switch:
 			if (this.defaultCase == null) {
-				if (compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore) {
+				if (ignoreMissingDefaultCase(compilerOptions, isEnumSwitch)) {
 					if (isEnumSwitch) {
 						upperScope.methodScope().hasMissingSwitchDefault = true;
 					}
@@ -574,21 +711,21 @@
 			if (isEnumSwitch && compilerOptions.complianceLevel >= ClassFileConstants.JDK1_5) {
 				if (this.defaultCase == null || compilerOptions.reportMissingEnumCaseDespiteDefault) {
 					int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement
-					if (constantCount == this.caseCount
-							&& this.caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) {
+					if (constantCount >= this.caseCount
+							&& constantCount != ((ReferenceBinding)expressionType).enumConstantCount()) {
 						FieldBinding[] enumFields = ((ReferenceBinding)expressionType.erasure()).fields();
 						for (int i = 0, max = enumFields.length; i <max; i++) {
 							FieldBinding enumConstant = enumFields[i];
 							if ((enumConstant.modifiers & ClassFileConstants.AccEnum) == 0) continue;
 							findConstant : {
-								for (int j = 0; j < this.caseCount; j++) {
+								for (int j = 0; j < constantCount; j++) {
 									if ((enumConstant.id + 1) == this.constants[j]) // zero should not be returned see bug 141810
 										break findConstant;
 								}
 								// enum constant did not get referenced from switch
 								boolean suppress = (this.defaultCase != null && (this.defaultCase.bits & DocumentedCasesOmitted) != 0);
 								if (!suppress) {
-									upperScope.problemReporter().missingEnumConstantCase(this, enumConstant);
+									reportMissingEnumConstantCase(upperScope, enumConstant);
 								}
 							}
 						}
@@ -599,7 +736,29 @@
 			if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block
 		}
 	}
+	protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) {
+		upperScope.problemReporter().missingEnumConstantCase(this, enumConstant);
+	}
+	protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) {
+		return compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore;
+	}
 
+	private void reportMixingCaseTypes() {
+		if (this.caseCount == 0) {
+			this.switchLabeledRules = this.defaultCase != null ? this.defaultCase.isExpr : this.switchLabeledRules;
+			return;
+		}
+		boolean isExpr = this.switchLabeledRules = this.cases[0].isExpr;
+		for (int i = 1, l = this.caseCount; i < l; ++i) {
+			if (this.cases[i].isExpr != isExpr) {
+				this.scope.problemReporter().switchExpressionMixedCase(this.cases[i]);
+				return;
+			}
+		}
+		if (this.defaultCase != null && this.defaultCase.isExpr != isExpr) {
+			this.scope.problemReporter().switchExpressionMixedCase(this.defaultCase);
+		}
+	}
 	private void reportDuplicateCase(final CaseStatement duplicate, final CaseStatement original, int length) {
 		if (this.duplicateCaseStatements == null) {
 			this.scope.problemReporter().duplicateCase(original);
@@ -675,4 +834,9 @@
 		}
 		return false;
 	}
+
+	@Override
+	public StringBuffer printExpression(int indent, StringBuffer output) {
+		return printStatement(indent, output);
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
index bfcdf5e..8093adc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java
@@ -6,6 +6,10 @@
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -128,9 +132,10 @@
 	int MAJOR_VERSION_9 = 53;
 	int MAJOR_VERSION_10 = 54;
 	int MAJOR_VERSION_11 = 55;
+	int MAJOR_VERSION_12 = 56;
 
 	int MAJOR_VERSION_0 = 44;
-	int MAJOR_LATEST_VERSION = MAJOR_VERSION_11;
+	int MAJOR_LATEST_VERSION = MAJOR_VERSION_12;
 
 	int MINOR_VERSION_0 = 0;
 	int MINOR_VERSION_1 = 1;
@@ -152,6 +157,7 @@
 	long JDK9 = ((long)ClassFileConstants.MAJOR_VERSION_9 << 16) + ClassFileConstants.MINOR_VERSION_0;
 	long JDK10 = ((long)ClassFileConstants.MAJOR_VERSION_10 << 16) + ClassFileConstants.MINOR_VERSION_0;
 	long JDK11 = ((long)ClassFileConstants.MAJOR_VERSION_11 << 16) + ClassFileConstants.MINOR_VERSION_0;
+	long JDK12 = ((long)ClassFileConstants.MAJOR_VERSION_12 << 16) + ClassFileConstants.MINOR_VERSION_0;
 
 	public static long getLatestJDKLevel() {
 		return ((long)ClassFileConstants.MAJOR_LATEST_VERSION << 16) + ClassFileConstants.MINOR_VERSION_0;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
index 0c43198..5f4cc19 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java
@@ -4567,7 +4567,16 @@
 			ConstantPool.Init,
 			ConstantPool.DefaultConstructorSignature);
 }
-
+public void invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor() {
+	// invokespecial: java.lang.IncompatibleClassChangeError.<init>()V
+	invoke(
+			Opcodes.OPC_invokespecial,
+			1, // receiverAndArgsSize
+			0, // return type size
+			ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName,
+			ConstantPool.Init,
+			ConstantPool.DefaultConstructorSignature);
+}
 public void invokeJavaLangClassDesiredAssertionStatus() {
 	// invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
 	invoke(
@@ -6142,7 +6151,19 @@
 	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
 	writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName));
 }
-
+public void newJavaLangIncompatibleClassChangeError() {
+	// new: java.lang.Error
+	this.countLabels = 0;
+	this.stackDepth++;
+	if (this.stackDepth > this.stackMax)
+		this.stackMax = this.stackDepth;
+	if (this.classFileOffset + 2 >= this.bCodeStream.length) {
+		resizeByteArray();
+	}
+	this.position++;
+	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new;
+	writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName));
+}
 public void newNoClassDefFoundError() {
 	// new: java.lang.NoClassDefFoundError
 	this.countLabels = 0;
@@ -6297,7 +6318,9 @@
 public void recordExpressionType(TypeBinding typeBinding) {
 	// nothing to do
 }
-
+public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) {
+	// nothing to do
+}
 public void recordPositionsFrom(int startPC, int sourcePos) {
 	this.recordPositionsFrom(startPC, sourcePos, false);
 }
@@ -6895,7 +6918,7 @@
 	this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_swap;
 }
 
-public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
+public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, int[] mapping, CaseLabel[] casesLabel) {
 	this.countLabels = 0;
 	this.stackDepth--;
 	int length = casesLabel.length;
@@ -6926,7 +6949,7 @@
 		int index;
 		int key = keys[index = sortedIndexes[j - low]];
 		if (key == i) {
-			casesLabel[index].branch();
+			casesLabel[mapping[index]].branch();
 			j++;
 			if (i == high) break; // if high is maxint, then avoids wrapping to minint.
 		} else {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
index 276c999..700a70d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -167,6 +167,7 @@
 	public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$
 	public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$
 	public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$
+	public static final char[] JavaLangIncompatibleClassChangeErrorConstantPoolName = "java/lang/IncompatibleClassChangeError".toCharArray(); //$NON-NLS-1$
 	public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$
 	public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$
 	public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
index 039f188..f49b793 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2006, 2016 IBM Corporation and others.
+ * Copyright (c) 2006, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -91,10 +91,17 @@
 			StringBuffer buffer = new StringBuffer();
 			buffer.append('(').append(this.pc).append(',').append(this.delta);
 			if (this.typeBinding != null) {
-				buffer
-					.append(',')
-					.append(this.typeBinding.qualifiedPackageName())
-					.append(this.typeBinding.qualifiedSourceName());
+				if (this.typeBinding.isBaseType()) {
+					buffer
+						.append(',')
+						.append(this.typeBinding.qualifiedSourceName());
+				} else {
+					buffer
+						.append(',')
+						.append(this.typeBinding.qualifiedPackageName())
+						.append('.')
+						.append(this.typeBinding.qualifiedSourceName());
+				}
 			}
 			buffer.append(')');
 			return String.valueOf(buffer);
@@ -226,6 +233,7 @@
 public void optimizeBranch(int oldPosition, BranchLabel lbl) {
 	super.optimizeBranch(oldPosition, lbl);
 	removeFramePosition(oldPosition);
+	removeStackMapMarkers(oldPosition);
 }
 public void removeFramePosition(int pc) {
 	Integer entry = Integer.valueOf(pc);
@@ -237,6 +245,17 @@
 		}
 	}
 }
+public void removeStackMapMarkers(int markerOldPosition) {
+	if (this.stackDepthMarkers != null) {
+		for (int i = this.stackDepthMarkers.size() - 1; i >= 0; i--) {
+			StackDepthMarker marker = (StackDepthMarker) this.stackDepthMarkers.get(i);
+			if (marker.pc == markerOldPosition) {
+				this.stackDepthMarkers.remove(i);
+				break;
+			}
+		}
+	}
+}
 @Override
 public void addVariable(LocalVariableBinding localBinding) {
 	if (localBinding.initializationPCs == null) {
@@ -284,6 +303,26 @@
 public void recordExpressionType(TypeBinding typeBinding) {
 	addStackDepthMarker(this.position, 0, typeBinding);
 }
+@Override
+public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) {
+	addStackDepthMarker(this.position, delta, typeBinding);
+	if (adjustStackDepth) {
+		// optimized goto
+		// the break label already adjusted the stack depth (-1 or -2 depending on the return type)
+		// we need to adjust back to what it was
+		switch(typeBinding.id) {
+			case TypeIds.T_long :
+			case TypeIds.T_double :
+				this.stackDepth+=2;
+				break;
+			case TypeIds.T_void :
+				break;
+			default :
+				this.stackDepth++;
+				break;
+		}
+	}
+}
 /**
  * Macro for building a class descriptor object
  */
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index 0aaaa13..c23712a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -6,6 +6,10 @@
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -202,7 +206,8 @@
 	public static final String OPTION_ReportAPILeak = "org.eclipse.jdt.core.compiler.problem.APILeak"; //$NON-NLS-1$
 	public static final String OPTION_ReportUnstableAutoModuleName = "org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName";   //$NON-NLS-1$
 
-	public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.EnablePreviews"; //$NON-NLS-1$
+	public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"; //$NON-NLS-1$
+	public static final String OPTION_ReportPreviewFeatures = "org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures"; //$NON-NLS-1$
 
 	/**
 	 * Possible values for configurable options
@@ -224,6 +229,11 @@
 	public static final String VERSION_9 = "9"; //$NON-NLS-1$
 	public static final String VERSION_10 = "10"; //$NON-NLS-1$
 	public static final String VERSION_11 = "11"; //$NON-NLS-1$
+	public static final String VERSION_12 = "12"; //$NON-NLS-1$
+	/*
+	 * Note: Whenever a new version is added, make sure getLatestVersion()
+	 * is updated with it.
+	 */
 	public static final String ERROR = "error"; //$NON-NLS-1$
 	public static final String WARNING = "warning"; //$NON-NLS-1$
 	public static final String INFO = "info"; //$NON-NLS-1$
@@ -333,8 +343,7 @@
 	public static final int UsingTerminallyDeprecatedAPI = IrritantSet.GROUP2 | ASTNode.Bit24;
 	public static final int APILeak = IrritantSet.GROUP2 | ASTNode.Bit25;
 	public static final int UnstableAutoModuleName = IrritantSet.GROUP2 | ASTNode.Bit26;
-	// Dummy feature, but
-	//public static final int DummyPreviewFeatureWarning = IrritantSet.GROUP2 | ASTNode.Bit27;
+	public static final int PreviewFeatureUsed = IrritantSet.GROUP2 | ASTNode.Bit27;
 
 
 	// Severity level for handlers
@@ -583,6 +592,12 @@
 	}
 
 	/**
+	 * Return the latest Java language version supported by the Eclipse compiler
+	 */
+	public static String getLatestVersion() {
+		return VERSION_12;
+	}
+	/**
 	 * Return the most specific option key controlling this irritant. Note that in some case, some irritant is controlled by
 	 * other master options (e.g. javadoc, deprecation, etc.).
 	 * This information is intended for grouping purpose (several problems governed by a rule)
@@ -758,6 +773,8 @@
 				return OPTION_ReportAPILeak;
 			case UnstableAutoModuleName:
 				return OPTION_ReportUnstableAutoModuleName;
+			case PreviewFeatureUsed:
+				return OPTION_ReportPreviewFeatures;
 		}
 		return null;
 	}
@@ -998,6 +1015,7 @@
 			OPTION_ReportUnlikelyCollectionMethodArgumentType,
 			OPTION_ReportUnlikelyEqualsArgumentType,
 			OPTION_ReportAPILeak,
+			OPTION_ReportPreviewFeatures
 		};
 		return result;
 	}
@@ -1099,8 +1117,8 @@
 				return "exports"; //$NON-NLS-1$
 			case UnstableAutoModuleName:
 				return "module"; //$NON-NLS-1$
-			//case DummyPreviewFeatureWarning:
-			//	return "preview"; //$NON-NLS-1$
+			case PreviewFeatureUsed:
+				return "preview"; //$NON-NLS-1$
 		}
 		return null;
 	}
@@ -1351,6 +1369,7 @@
 		optionsMap.put(OPTION_ReportAPILeak, getSeverityString(APILeak));
 		optionsMap.put(OPTION_ReportUnstableAutoModuleName, getSeverityString(UnstableAutoModuleName));
 		optionsMap.put(OPTION_EnablePreviews, this.enablePreviewFeatures ? ENABLED : DISABLED);
+		optionsMap.put(OPTION_ReportPreviewFeatures, getSeverityString(PreviewFeatureUsed));
 		return optionsMap;
 	}
 
@@ -2070,6 +2089,8 @@
 				this.enablePreviewFeatures = false;
 			}
 		}
+		if ((optionValue = optionsMap.get(OPTION_ReportPreviewFeatures)) != null) 
+			updateSeverity(PreviewFeatureUsed, optionValue);
 	}
 
 	private String[] stringToNameList(String optionValue) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
index 3cda404..29a45a3 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java
@@ -21,6 +21,7 @@
 public abstract class Constant implements TypeIds, OperatorIds {
 
 	public static final Constant NotAConstant = DoubleConstant.fromValue(Double.NaN);
+	public static final Constant[] NotAConstantList = new Constant[] {DoubleConstant.fromValue(Double.NaN)};
 	
 	public boolean booleanValue() {
 		throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "boolean" })); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index 735f553..a12103c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -77,7 +77,7 @@
 	public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName);
 
 	public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
-	public static final IrritantSet PREVIEW = new IrritantSet(0);
+	public static final IrritantSet PREVIEW = new IrritantSet(CompilerOptions.PreviewFeatureUsed);
 	public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default	
 	public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
 	public static final IrritantSet COMPILER_DEFAULT_INFOS = new IrritantSet(0); // As of now, no default values
@@ -135,7 +135,8 @@
 				|CompilerOptions.UnlikelyCollectionMethodArgumentType
 				|CompilerOptions.UsingTerminallyDeprecatedAPI
 				|CompilerOptions.APILeak
-				|CompilerOptions.UnstableAutoModuleName);
+				|CompilerOptions.UnstableAutoModuleName
+				|CompilerOptions.PreviewFeatureUsed);
 		// default errors IF AnnotationBasedNullAnalysis is enabled:
 		COMPILER_DEFAULT_ERRORS.set(
 				CompilerOptions.NullSpecViolation
@@ -190,7 +191,6 @@
 
 		UNLIKELY_ARGUMENT_TYPE
 			.set(CompilerOptions.UnlikelyEqualsArgumentType);
-		//PREVIEW.set(CompilerOptions.DummyPreviewFeatureWarning);
 	}
 	// Internal state
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
index 75717b1..cb9dd27 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2017 GK Software AG.
+ * Copyright (c) 2013, 2019 GK Software AG.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     Lars Vogel <Lars.Vogel@vogella.com> - Contributions for
@@ -30,6 +34,7 @@
 import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
 import org.eclipse.jdt.internal.compiler.ast.MessageSend;
 import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
+import org.eclipse.jdt.internal.compiler.ast.SwitchExpression;
 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord;
 
@@ -144,6 +149,14 @@
 					new ConstraintExpressionFormula(conditional.valueIfTrue, this.right, this.relation, this.isSoft),
 					new ConstraintExpressionFormula(conditional.valueIfFalse, this.right, this.relation, this.isSoft)
 				};
+			}  else if (this.left instanceof SwitchExpression) {
+				SwitchExpression se = (SwitchExpression) this.left;
+				ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions.size()];
+				int i = 0;
+				for (Expression re : se.resultExpressions) {
+					cfs[i++] = new ConstraintExpressionFormula(re, this.right, this.relation, this.isSoft);
+				}
+				return cfs;
 			} else if (this.left instanceof LambdaExpression) {
 				LambdaExpression lambda = (LambdaExpression) this.left;
 				BlockScope scope = lambda.enclosingScope;
@@ -522,6 +535,13 @@
 			variables.addAll(new ConstraintExpressionFormula(expr.valueIfTrue, this.right, COMPATIBLE).inputVariables(context));
 			variables.addAll(new ConstraintExpressionFormula(expr.valueIfFalse, this.right, COMPATIBLE).inputVariables(context));
 			return variables;
+		} else if (this.left instanceof SwitchExpression && this.left.isPolyExpression()) {
+			SwitchExpression expr = (SwitchExpression) this.left;
+			Set<InferenceVariable> variables = new HashSet<>();
+			for (Expression re : expr.resultExpressions) {
+				variables.addAll(new ConstraintExpressionFormula(re, this.right, COMPATIBLE).inputVariables(context));
+			}
+			return variables;
 		}
 		return EMPTY_VARIABLE_LIST;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
index f65f5f4..563081f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2018 GK Software AG, and others.
+ * Copyright (c) 2013, 2019 GK Software AG, and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     Stephan Herrmann - initial API and implementation
  *     IBM Corporation - Bug fixes
@@ -32,6 +36,7 @@
 import org.eclipse.jdt.internal.compiler.ast.Invocation;
 import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
 import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
+import org.eclipse.jdt.internal.compiler.ast.SwitchExpression;
 import org.eclipse.jdt.internal.compiler.ast.Wildcard;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants.BoundCheckStatus;
 import org.eclipse.jdt.internal.compiler.util.Sorting;
@@ -573,6 +578,15 @@
 			if (addJDK_8153748ConstraintsFromExpression(ce.valueIfTrue, parameter, method, substitution) == ReductionResult.FALSE)
 				return ReductionResult.FALSE;
 			return addJDK_8153748ConstraintsFromExpression(ce.valueIfFalse, parameter, method, substitution);
+		} else if (argument instanceof SwitchExpression) {
+			SwitchExpression se = (SwitchExpression) argument;
+			ReductionResult result = ReductionResult.FALSE;
+			for (Expression re : se.resultExpressions) {
+				result = addJDK_8153748ConstraintsFromExpression(re, parameter, method, substitution);
+				if (result == ReductionResult.FALSE)
+					break;
+			}
+			return result;
 		}
 		return null;
 	}
@@ -709,6 +723,13 @@
 			ConditionalExpression ce = (ConditionalExpression) expri;
 			return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method)
 					&& addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method);
+		} else if (expri instanceof SwitchExpression) {
+			SwitchExpression se = (SwitchExpression) expri;
+			for (Expression re : se.resultExpressions) {
+				if (!addConstraintsToC_OneExpr(re, c, fsi, substF, method))
+					return false;
+			}
+			return true;
 		}
 		return true;
 	}
@@ -950,6 +971,13 @@
 		} else if (expri instanceof ConditionalExpression) {
 			ConditionalExpression cond = (ConditionalExpression) expri;
 			return  checkExpression(cond.valueIfTrue, u, r1, v, r2) && checkExpression(cond.valueIfFalse, u, r1, v, r2);
+		} else if (expri instanceof SwitchExpression) {
+			SwitchExpression se = (SwitchExpression) expri;
+			for (Expression re : se.resultExpressions) {
+				if (!checkExpression(re, u, r1, v, r2))
+					return false;
+			}
+			return true;
 		} else {
 			return false;
 		}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index 3817b6d..373a684 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -640,6 +644,9 @@
 				} else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) {
 					this.tagValue = TAG_SINCE_VALUE;
 					this.tagWaitingForDescription = this.tagValue;
+				} else if (length == TAG_SYSTEM_PROPERTY_LENGTH && CharOperation.equals(TAG_SYSTEM_PROPERTY, tagName, 0, length)) {
+					this.tagValue = TAG_SYSTEM_PROPERTY_VALUE;
+					this.tagWaitingForDescription = this.tagValue;
 				}
 				break;
 			case 't':
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java
index 10f540e..1e92374 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -44,6 +48,7 @@
 	public static final char[] TAG_SINCE = "since".toCharArray(); //$NON-NLS-1$
 	public static final char[] TAG_VERSION = "version".toCharArray(); //$NON-NLS-1$
 	public static final char[] TAG_CATEGORY = "category".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SYSTEM_PROPERTY = "systemProperty".toCharArray(); //$NON-NLS-1$
 	public static final char[] TAG_USES = "uses".toCharArray(); //$NON-NLS-1$
 	public static final char[] TAG_PROVIDES = "provides".toCharArray(); //$NON-NLS-1$
 
@@ -68,6 +73,7 @@
 	public static final int TAG_CODE_LENGTH = TAG_CODE.length;
 	public static final int TAG_LITERAL_LENGTH = TAG_LITERAL.length;
 	public static final int TAG_DOC_ROOT_LENGTH = TAG_DOC_ROOT.length;
+	public static final int TAG_SYSTEM_PROPERTY_LENGTH = TAG_SYSTEM_PROPERTY.length;
 	public static final int TAG_USES_LENGTH = TAG_USES.length;
 	public static final int TAG_PROVIDES_LENGTH = TAG_PROVIDES.length;
 
@@ -93,6 +99,7 @@
 	public static final int TAG_CODE_VALUE = 18;
 	public static final int TAG_LITERAL_VALUE = 19;
 	public static final int TAG_DOC_ROOT_VALUE = 20;
+	public static final int TAG_SYSTEM_PROPERTY_VALUE=21;
 	public static final int TAG_USES_VALUE=21;
 	public static final int TAG_PROVIDES_VALUE=22;
 	public static final int TAG_OTHERS_VALUE = 100;
@@ -119,6 +126,7 @@
 		TAG_CODE,					/* 18 */
 		TAG_LITERAL,				/* 19 */
 		TAG_DOC_ROOT,			/* 20 */
+		TAG_SYSTEM_PROPERTY     /* 21 */
 	};
 
 	// tags expected positions
@@ -162,6 +170,8 @@
 		// since 10
 		{},
 		// since 11
+		{},
+		//since 12
 		{}
 	};
 	public static final char[][][] INLINE_TAGS = {
@@ -188,7 +198,9 @@
 		// since 10
 		{},
 		// since 11
-		{}
+		{},
+		//since 12
+		{TAG_SYSTEM_PROPERTY}
 	};
 	public final static int INLINE_TAGS_LENGTH = INLINE_TAGS.length;
 	public final static int BLOCK_TAGS_LENGTH = BLOCK_TAGS.length;
@@ -197,7 +209,6 @@
 	public final static short TAG_TYPE_NONE = 0;
 	public final static short TAG_TYPE_INLINE = 1;
 	public final static short TAG_TYPE_BLOCK = 2;
-	
 	public static final short[] JAVADOC_TAG_TYPE = {
 		TAG_TYPE_NONE, 		// NO_TAG_VALUE = 0;
 		TAG_TYPE_BLOCK,		// TAG_DEPRECATED_VALUE = 1;
@@ -219,7 +230,8 @@
 		TAG_TYPE_BLOCK,		// TAG_VERSION_VALUE = 17;
 		TAG_TYPE_INLINE,	// TAG_CODE_VALUE = 18;
 		TAG_TYPE_INLINE,	// TAG_LITERAL_VALUE = 19;
-		TAG_TYPE_INLINE		// TAG_DOC_ROOT_VALUE = 20;
+		TAG_TYPE_INLINE,	// TAG_DOC_ROOT_VALUE = 20;
+		TAG_TYPE_INLINE	    // TAG_DOC_ROOT_VALUE = 21
 	};
 	/*
 	 * Tags usage
@@ -235,6 +247,7 @@
 		TAG_LINKPLAIN,
 		TAG_DOC_ROOT,
 		TAG_VALUE,
+		TAG_SYSTEM_PROPERTY
 	};
 	public static final char[][] COMPILATION_UNIT_TAGS = {};
 	public static final char[][] CLASS_TAGS = {
@@ -251,7 +264,8 @@
 		TAG_DOC_ROOT,
 		TAG_VALUE,
 		TAG_CODE,
-		TAG_LITERAL
+		TAG_LITERAL,
+		TAG_SYSTEM_PROPERTY
 	};
 	public static final char[][] FIELD_TAGS = {
 		TAG_SEE,
@@ -265,7 +279,8 @@
 		TAG_DOC_ROOT,
 		TAG_VALUE,
 		TAG_CODE,
-		TAG_LITERAL
+		TAG_LITERAL,
+		TAG_SYSTEM_PROPERTY
 	};
 	public static final char[][] METHOD_TAGS = {
 		TAG_SEE,
@@ -283,7 +298,8 @@
 		TAG_DOC_ROOT,
 		TAG_VALUE,
 		TAG_CODE,
-		TAG_LITERAL
+		TAG_LITERAL,
+		TAG_SYSTEM_PROPERTY
 	};
 	public static final char[][] MODULE_TAGS = {
 			TAG_SEE,
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index a9e2139..63c98f0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196
@@ -52,6 +56,7 @@
 import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.impl.IrritantSet;
 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
 import org.eclipse.jdt.internal.compiler.lookup.Binding;
 import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
@@ -941,6 +946,7 @@
 private int stateStackLengthStack[] = new int[0];
 protected boolean parsingJava8Plus;
 protected boolean parsingJava9Plus;
+protected boolean parsingJava12Plus;
 protected boolean parsingJava11Plus;
 protected int unstackedAct = ERROR_ACTION;
 private boolean haltOnSyntaxError = false;
@@ -960,6 +966,7 @@
 	initializeScanner();
 	this.parsingJava8Plus = this.options.sourceLevel >= ClassFileConstants.JDK1_8;
 	this.parsingJava9Plus = this.options.sourceLevel >= ClassFileConstants.JDK9;
+	this.parsingJava12Plus = this.options.sourceLevel >= ClassFileConstants.JDK12;
 	this.parsingJava11Plus = this.options.sourceLevel >= ClassFileConstants.JDK11;
 	this.astLengthStack = new int[50];
 	this.expressionLengthStack = new int[30];
@@ -2198,10 +2205,30 @@
 	concatNodeLists();
 }
 protected void consumeCaseLabel() {
-	// SwitchLabel ::= 'case' ConstantExpression ':'
-	this.expressionLengthPtr--;
-	Expression expression = this.expressionStack[this.expressionPtr--];
-	CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]);
+//	// SwitchLabel ::= 'case' ConstantExpression ':'
+//	this.expressionLengthPtr--;
+//	Expression expression = this.expressionStack[this.expressionPtr--];
+//	CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]);
+//	// Look for $fall-through$ tag in leading comment for case statement
+//	if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) {
+//		caseStatement.bits |= ASTNode.DocumentedFallthrough;
+//	}
+//	pushOnAstStack(caseStatement);
+	Expression[] constantExpressions = null;
+	int length = 0;
+	if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) {
+		this.expressionPtr -= length;
+		System.arraycopy(
+			this.expressionStack,
+			this.expressionPtr + 1,
+			constantExpressions = new Expression[length],
+			0,
+			length);
+	} else {
+		// TODO : ERROR
+	}
+	CaseStatement caseStatement = new CaseStatement(constantExpressions[0], constantExpressions[length - 1].sourceEnd, this.intStack[this.intPtr--]);
+	caseStatement.constantExpressions = constantExpressions;
 	// Look for $fall-through$ tag in leading comment for case statement
 	if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) {
 		caseStatement.bits |= ASTNode.DocumentedFallthrough;
@@ -7167,1319 +7194,1359 @@
 		    consumeSwitchBlockStatements() ;  
 			break;
  
-    case 388 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
+    case 389 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); }  //$NON-NLS-1$
 		    consumeSwitchBlockStatement() ;  
 			break;
  
-    case 390 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
+    case 391 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); }  //$NON-NLS-1$
 		    consumeSwitchLabels() ;  
 			break;
  
-     case 391 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); }  //$NON-NLS-1$
+     case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= SwitchLabelCaseLhs COLON"); }  //$NON-NLS-1$
 		    consumeCaseLabel();  
 			break;
  
-     case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
+     case 393 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); }  //$NON-NLS-1$
 		    consumeDefaultLabel();  
 			break;
  
-    case 393 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+    case 396 : if (DEBUG) { System.out.println("SwitchExpression ::= switch LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
+		    consumeSwitchExpression() ;  
+			break;
+ 
+     case 399 : if (DEBUG) { System.out.println("SwitchLabeledRule ::= SwitchLabeledThrowStatement"); }  //$NON-NLS-1$
+		    consumeSwitchLabeledRule();  
+			break;
+ 
+     case 400 : if (DEBUG) { System.out.println("SwitchLabeledExpression ::= SwitchLabelExpr Expression"); }  //$NON-NLS-1$
+		    consumeSwitchLabeledExpression();  
+			break;
+ 
+     case 401 : if (DEBUG) { System.out.println("SwitchLabeledBlock ::= SwitchLabelExpr Block"); }  //$NON-NLS-1$
+		    consumeSwitchLabeledBlock();  
+			break;
+ 
+     case 402 : if (DEBUG) { System.out.println("SwitchLabeledThrowStatement ::= SwitchLabelExpr..."); }  //$NON-NLS-1$
+		    consumeSwitchLabeledThrowStatement();  
+			break;
+ 
+     case 403 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= default ARROW"); }  //$NON-NLS-1$
+		    consumeDefaultLabelExpr();  
+			break;
+ 
+     case 404 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr..."); }  //$NON-NLS-1$
+		    consumeCaseLabelExpr();  
+			break;
+ 
+     case 405 : if (DEBUG) { System.out.println("SwitchLabelCaseLhs ::= case ConstantExpressions"); }  //$NON-NLS-1$
+		    consumeSwitchLabelCaseLhs();  
+			break;
+ 
+    case 406 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 394 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 407 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementWhile() ;  
 			break;
  
-    case 395 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
+    case 408 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); }  //$NON-NLS-1$
 		    consumeStatementDo() ;  
 			break;
  
-    case 396 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
+    case 409 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 397 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
+    case 410 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); }  //$NON-NLS-1$
 		    consumeStatementFor() ;  
 			break;
  
-    case 398 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
+    case 411 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); }  //$NON-NLS-1$
 		    consumeForInit() ;  
 			break;
  
-    case 402 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
+    case 415 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); }  //$NON-NLS-1$
 		    consumeStatementExpressionList() ;  
 			break;
  
-    case 403 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 416 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeSimpleAssertStatement() ;  
 			break;
  
-    case 404 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
+    case 417 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); }  //$NON-NLS-1$
 		    consumeAssertStatement() ;  
 			break;
  
-    case 405 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
+    case 418 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreak() ;  
 			break;
  
-    case 406 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 419 : if (DEBUG) { System.out.println("BreakStatement ::= break Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementBreakWithLabel() ;  
 			break;
  
-    case 407 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
+    case 420 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinue() ;  
 			break;
  
-    case 408 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
+    case 421 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementContinueWithLabel() ;  
 			break;
  
-    case 409 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
+    case 422 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementReturn() ;  
 			break;
  
-    case 410 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
+    case 423 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); }  //$NON-NLS-1$
 		    consumeStatementThrow();  
 			break;
  
-    case 411 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
+    case 424 : if (DEBUG) { System.out.println("ThrowExpression ::= throw Expression"); }  //$NON-NLS-1$
+		    consumeThrowExpression() ;  
+			break;
+ 
+    case 425 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); }  //$NON-NLS-1$
 		    consumeStatementSynchronized();  
 			break;
  
-    case 412 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
+    case 426 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); }  //$NON-NLS-1$
 		    consumeOnlySynchronized();  
 			break;
  
-    case 413 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
+    case 427 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); }  //$NON-NLS-1$
 		    consumeStatementTry(false, false);  
 			break;
  
-    case 414 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
+    case 428 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); }  //$NON-NLS-1$
 		    consumeStatementTry(true, false);  
 			break;
  
-    case 415 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+    case 429 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
 		    consumeStatementTry(false, true);  
 			break;
  
-    case 416 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
+    case 430 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); }  //$NON-NLS-1$
 		    consumeStatementTry(true, true);  
 			break;
  
-    case 417 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); }  //$NON-NLS-1$
+    case 431 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); }  //$NON-NLS-1$
 		    consumeResourceSpecification();  
 			break;
  
-    case 418 : if (DEBUG) { System.out.println(";opt ::="); }  //$NON-NLS-1$
+    case 432 : if (DEBUG) { System.out.println(";opt ::="); }  //$NON-NLS-1$
 		    consumeResourceOptionalTrailingSemiColon(false);  
 			break;
  
-    case 419 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 433 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeResourceOptionalTrailingSemiColon(true);  
 			break;
  
-    case 420 : if (DEBUG) { System.out.println("Resources ::= Resource"); }  //$NON-NLS-1$
+    case 434 : if (DEBUG) { System.out.println("Resources ::= Resource"); }  //$NON-NLS-1$
 		    consumeSingleResource();  
 			break;
  
-    case 421 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); }  //$NON-NLS-1$
+    case 435 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); }  //$NON-NLS-1$
 		    consumeMultipleResources();  
 			break;
  
-    case 422 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); }  //$NON-NLS-1$
+    case 436 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); }  //$NON-NLS-1$
 		    consumeResourceOptionalTrailingSemiColon(true);  
 			break;
  
-    case 423 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); }  //$NON-NLS-1$
+    case 437 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); }  //$NON-NLS-1$
 		    consumeResourceAsLocalVariableDeclaration();  
 			break;
  
-    case 424 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); }  //$NON-NLS-1$
+    case 438 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); }  //$NON-NLS-1$
 		    consumeResourceAsLocalVariableDeclaration();  
 			break;
  
-    case 425 : if (DEBUG) { System.out.println("Resource ::= Name"); }  //$NON-NLS-1$
+    case 439 : if (DEBUG) { System.out.println("Resource ::= Name"); }  //$NON-NLS-1$
 		    consumeResourceAsLocalVariable();  
 			break;
  
-    case 426 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); }  //$NON-NLS-1$
+    case 440 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); }  //$NON-NLS-1$
 		    consumeResourceAsFieldAccess();  
 			break;
  
-    case 428 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
+    case 442 : if (DEBUG) { System.out.println("ExitTryBlock ::="); }  //$NON-NLS-1$
 		    consumeExitTryBlock();  
 			break;
  
-    case 430 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
+    case 444 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); }  //$NON-NLS-1$
 		    consumeCatches();  
 			break;
  
-    case 431 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
+    case 445 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); }  //$NON-NLS-1$
 		    consumeStatementCatch() ;  
 			break;
  
-    case 433 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
+    case 447 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); }  //$NON-NLS-1$
 		    consumeLeftParen();  
 			break;
  
-    case 434 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
+    case 448 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); }  //$NON-NLS-1$
 		    consumeRightParen();  
 			break;
  
-    case 439 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
+    case 453 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayThis();  
 			break;
  
-    case 440 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
+    case 454 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArray();  
 			break;
  
-    case 441 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
+    case 455 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayWithName();  
 			break;
  
-    case 444 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
+    case 458 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayNameThis();  
 			break;
  
-    case 445 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); }  //$NON-NLS-1$
+    case 459 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); }  //$NON-NLS-1$
 		    consumeQualifiedSuperReceiver();  
 			break;
  
-    case 446 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
+    case 460 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayName();  
 			break;
  
-    case 447 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
+    case 461 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayArrayType();  
 			break;
  
-    case 448 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
+    case 462 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveArrayType();  
 			break;
  
-    case 449 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
+    case 463 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); }  //$NON-NLS-1$
 		    consumePrimaryNoNewArrayPrimitiveType();  
 			break;
  
-    case 455 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
+    case 469 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionTypeArgumentsAndTrunk(false);  
 			break;
  
-    case 456 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
+    case 470 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionTypeArgumentsAndTrunk(true);  
 			break;
  
-    case 457 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); }  //$NON-NLS-1$
+    case 471 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); }  //$NON-NLS-1$
 		    consumeReferenceExpressionTypeForm(true);  
 			break;
  
-    case 458 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); }  //$NON-NLS-1$
+    case 472 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionTypeForm(false);  
 			break;
  
-    case 459 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); }  //$NON-NLS-1$
+    case 473 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionGenericTypeForm();  
 			break;
  
-    case 460 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); }  //$NON-NLS-1$
+    case 474 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionPrimaryForm();  
 			break;
  
-    case 461 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); }  //$NON-NLS-1$
+    case 475 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionPrimaryForm();  
 			break;
  
-    case 462 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); }  //$NON-NLS-1$
+    case 476 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); }  //$NON-NLS-1$
 		    consumeReferenceExpressionSuperForm();  
 			break;
  
-    case 463 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); }  //$NON-NLS-1$
+    case 477 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyTypeArguments();  
 			break;
  
-    case 465 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); }  //$NON-NLS-1$
+    case 479 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); }  //$NON-NLS-1$
 		    consumeIdentifierOrNew(false);  
 			break;
  
-    case 466 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); }  //$NON-NLS-1$
+    case 480 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); }  //$NON-NLS-1$
 		    consumeIdentifierOrNew(true);  
 			break;
  
-    case 467 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); }  //$NON-NLS-1$
+    case 481 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); }  //$NON-NLS-1$
 		    consumeLambdaExpression();  
 			break;
  
-    case 468 : if (DEBUG) { System.out.println("NestedLambda ::="); }  //$NON-NLS-1$
+    case 482 : if (DEBUG) { System.out.println("NestedLambda ::="); }  //$NON-NLS-1$
 		    consumeNestedLambda();  
 			break;
  
-    case 469 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); }  //$NON-NLS-1$
+    case 483 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); }  //$NON-NLS-1$
 		    consumeTypeElidedLambdaParameter(false);  
 			break;
  
-    case 475 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); }  //$NON-NLS-1$
+    case 489 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); }  //$NON-NLS-1$
 		    consumeFormalParameterList();  
 			break;
  
-    case 476 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+    case 490 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
 		    consumeTypeElidedLambdaParameter(true);  
 			break;
  
-    case 479 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); }  //$NON-NLS-1$
+    case 493 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); }  //$NON-NLS-1$
 		    consumeElidedLeftBraceAndReturn();  
 			break;
  
-    case 480 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
+    case 494 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); }  //$NON-NLS-1$
 		    consumeAllocationHeader();  
 			break;
  
-    case 481 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
+    case 495 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionWithTypeArguments();  
 			break;
  
-    case 482 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); }  //$NON-NLS-1$
+    case 496 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpression();  
 			break;
  
-    case 483 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+    case 497 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 484 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
+    case 498 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualified() ;  
 			break;
  
-    case 485 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+    case 499 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualified() ;  
 			break;
  
-    case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
+    case 500 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ;  
 			break;
  
-    case 487 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); }  //$NON-NLS-1$
+    case 501 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); }  //$NON-NLS-1$
 		    consumeEnterInstanceCreationArgumentList();  
 			break;
  
-    case 488 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); }  //$NON-NLS-1$
+    case 502 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); }  //$NON-NLS-1$
 		    consumeClassInstanceCreationExpressionName() ;  
 			break;
  
-    case 489 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+    case 503 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); }  //$NON-NLS-1$
 		    consumeClassBodyopt();  
 			break;
  
-    case 491 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+    case 505 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
 		    consumeEnterAnonymousClassBody(false);  
 			break;
  
-    case 492 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); }  //$NON-NLS-1$
+    case 506 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); }  //$NON-NLS-1$
 		    consumeClassBodyopt();  
 			break;
  
-    case 494 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
+    case 508 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); }  //$NON-NLS-1$
 		    consumeEnterAnonymousClassBody(true);  
 			break;
  
-    case 496 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
+    case 510 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); }  //$NON-NLS-1$
 		    consumeArgumentList();  
 			break;
  
-    case 497 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
+    case 511 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
-    case 498 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
+    case 512 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); }  //$NON-NLS-1$
 		    consumeArrayCreationHeader();  
 			break;
  
-    case 499 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 513 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithoutInitializer();  
 			break;
  
-    case 500 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
+    case 514 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithInitializer();  
 			break;
  
-    case 501 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 515 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithoutInitializer();  
 			break;
  
-    case 502 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
+    case 516 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); }  //$NON-NLS-1$
 		    consumeArrayCreationExpressionWithInitializer();  
 			break;
  
-    case 504 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
+    case 518 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExprs();  
 			break;
  
-     case 506 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); }  //$NON-NLS-1$
+     case 520 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); }  //$NON-NLS-1$
 		    consumeDimWithOrWithOutExpr();  
 			break;
  
-     case 507 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
+     case 521 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); }  //$NON-NLS-1$
 		    consumeDims();  
 			break;
  
-     case 510 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 524 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeOneDimLoop(false);  
 			break;
  
-     case 511 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); }  //$NON-NLS-1$
+     case 525 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); }  //$NON-NLS-1$
 		    consumeOneDimLoop(true);  
 			break;
  
-    case 512 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
+    case 526 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(false);  
 			break;
  
-    case 513 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
+    case 527 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(true);  
 			break;
  
-    case 514 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); }  //$NON-NLS-1$
+    case 528 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); }  //$NON-NLS-1$
 		    consumeFieldAccess(false);  
 			break;
  
-    case 515 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeMethodInvocationName();  
 			break;
  
-    case 516 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 530 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationNameWithTypeArguments();  
 			break;
  
-    case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 531 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimaryWithTypeArguments();  
 			break;
  
-    case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 532 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimary();  
 			break;
  
-    case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); }  //$NON-NLS-1$
+    case 533 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimary();  
 			break;
  
-    case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); }  //$NON-NLS-1$
+    case 534 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationPrimaryWithTypeArguments();  
 			break;
  
-    case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
+    case 535 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuperWithTypeArguments();  
 			break;
  
-    case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
+    case 536 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); }  //$NON-NLS-1$
 		    consumeMethodInvocationSuper();  
 			break;
  
-    case 523 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
+    case 537 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); }  //$NON-NLS-1$
 		    consumeArrayAccess(true);  
 			break;
  
-    case 524 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
+    case 538 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 525 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
+    case 539 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); }  //$NON-NLS-1$
 		    consumeArrayAccess(false);  
 			break;
  
-    case 527 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
+    case 541 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); }  //$NON-NLS-1$
 		    consumePostfixExpression();  
 			break;
  
-    case 530 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
+    case 544 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,true);  
 			break;
  
-    case 531 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
+    case 545 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,true);  
 			break;
  
-    case 532 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
+    case 546 : if (DEBUG) { System.out.println("PushPosition ::="); }  //$NON-NLS-1$
 		    consumePushPosition();  
 			break;
  
-    case 535 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 549 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 536 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
+    case 550 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 538 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
+    case 552 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS,false);  
 			break;
  
-    case 539 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
+    case 553 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS,false);  
 			break;
  
-    case 541 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
+    case 555 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
 			break;
  
-    case 542 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
+    case 556 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.NOT);  
 			break;
  
-    case 544 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
+    case 558 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithPrimitiveType();  
 			break;
  
-    case 545 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 559 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithGenericsArray();  
 			break;
  
-    case 546 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
+    case 560 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithQualifiedGenericsArray();  
 			break;
  
-    case 547 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
+    case 561 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionLL1();  
 			break;
  
-    case 548 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); }  //$NON-NLS-1$
+    case 562 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); }  //$NON-NLS-1$
 		    consumeCastExpressionLL1WithBounds();  
 			break;
  
-    case 549 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); }  //$NON-NLS-1$
+    case 563 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); }  //$NON-NLS-1$
 		    consumeCastExpressionWithNameArray();  
 			break;
  
-    case 550 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); }  //$NON-NLS-1$
+    case 564 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); }  //$NON-NLS-1$
 		    consumeZeroAdditionalBounds();  
 			break;
  
-    case 554 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
+    case 568 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); }  //$NON-NLS-1$
 		    consumeOnlyTypeArgumentsForCastExpression();  
 			break;
  
-    case 555 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
+    case 569 : if (DEBUG) { System.out.println("InsideCastExpression ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpression();  
 			break;
  
-    case 556 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
+    case 570 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionLL1();  
 			break;
  
-    case 557 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); }  //$NON-NLS-1$
+    case 571 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionLL1WithBounds ();  
 			break;
  
-    case 558 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
+    case 572 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); }  //$NON-NLS-1$
 		    consumeInsideCastExpressionWithQualifiedGenerics();  
 			break;
  
-    case 560 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 574 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
 			break;
  
-    case 561 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 575 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.DIVIDE);  
 			break;
  
-    case 562 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
+    case 576 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.REMAINDER);  
 			break;
  
-    case 564 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
+    case 578 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 565 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
+    case 579 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 567 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
+    case 581 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 568 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 582 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 583 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 571 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
+    case 585 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS);  
 			break;
  
-    case 572 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
+    case 586 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER);  
 			break;
  
-    case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
+    case 587 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
+    case 588 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 576 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
+    case 590 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); }  //$NON-NLS-1$
 		    consumeInstanceOfExpression();  
 			break;
  
-    case 578 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
+    case 592 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 579 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
+    case 593 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 581 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
+    case 595 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND);  
 			break;
  
-    case 583 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
+    case 597 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.XOR);  
 			break;
  
-    case 585 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
+    case 599 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR);  
 			break;
  
-    case 587 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
+    case 601 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND_AND);  
 			break;
  
-    case 589 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 603 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR_OR);  
 			break;
  
-    case 591 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
+    case 605 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); }  //$NON-NLS-1$
 		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 594 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
+    case 608 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); }  //$NON-NLS-1$
 		    consumeAssignment();  
 			break;
  
-    case 596 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
+    case 610 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); }  //$NON-NLS-1$
 		    ignoreExpressionAssignment(); 
 			break;
  
-    case 597 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
+    case 611 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(EQUAL);  
 			break;
  
-    case 598 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
+    case 612 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MULTIPLY);  
 			break;
  
-    case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
+    case 613 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(DIVIDE);  
 			break;
  
-    case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
+    case 614 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(REMAINDER);  
 			break;
  
-    case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
+    case 615 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(PLUS);  
 			break;
  
-    case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
+    case 616 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(MINUS);  
 			break;
  
-    case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 617 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(LEFT_SHIFT);  
 			break;
  
-    case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 618 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(RIGHT_SHIFT);  
 			break;
  
-    case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
+    case 619 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
+    case 620 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(AND);  
 			break;
  
-    case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
+    case 621 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(XOR);  
 			break;
  
-    case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
+    case 622 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); }  //$NON-NLS-1$
 		    consumeAssignmentOperator(OR);  
 			break;
  
-    case 609 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); }  //$NON-NLS-1$
+    case 623 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); }  //$NON-NLS-1$
 		    consumeExpression();  
 			break;
  
-    case 612 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
+    case 626 : if (DEBUG) { System.out.println("Expressionopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyExpression();  
 			break;
  
-    case 617 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 629 : if (DEBUG) { System.out.println("ConstantExpressions ::= ConstantExpressions COMMA..."); }  //$NON-NLS-1$
+		    consumeConstantExpressions();  
+			break;
+ 
+    case 633 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyClassBodyDeclarationsopt();  
 			break;
  
-    case 618 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+    case 634 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeClassBodyDeclarationsopt();  
 			break;
  
-     case 619 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
+     case 635 : if (DEBUG) { System.out.println("Modifiersopt ::="); }  //$NON-NLS-1$
 		    consumeDefaultModifiers();  
 			break;
  
-    case 620 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
+    case 636 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); }  //$NON-NLS-1$
 		    consumeModifiers();  
 			break;
  
-    case 621 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
+    case 637 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyBlockStatementsopt();  
 			break;
  
-     case 623 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
+     case 639 : if (DEBUG) { System.out.println("Dimsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyDimsopt();  
 			break;
  
-     case 625 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
+     case 641 : if (DEBUG) { System.out.println("ArgumentListopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArgumentListopt();  
 			break;
  
-    case 629 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
+    case 645 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); }  //$NON-NLS-1$
 		    consumeFormalParameterListopt();  
 			break;
  
-     case 633 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+     case 649 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyInterfaceMemberDeclarationsopt();  
 			break;
  
-     case 634 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+     case 650 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeInterfaceMemberDeclarationsopt();  
 			break;
  
-    case 635 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
+    case 651 : if (DEBUG) { System.out.println("NestedType ::="); }  //$NON-NLS-1$
 		    consumeNestedType();  
 			break;
 
-     case 636 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
+     case 652 : if (DEBUG) { System.out.println("ForInitopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForInitopt();  
 			break;
  
-     case 638 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
+     case 654 : if (DEBUG) { System.out.println("ForUpdateopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyForUpdateopt();  
 			break;
  
-     case 642 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
+     case 658 : if (DEBUG) { System.out.println("Catchesopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyCatchesopt();  
 			break;
  
-     case 644 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
+     case 660 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); }  //$NON-NLS-1$
 		    consumeEnumDeclaration();  
 			break;
  
-     case 645 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
+     case 661 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); }  //$NON-NLS-1$
 		    consumeEnumHeader();  
 			break;
  
-     case 646 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
+     case 662 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); }  //$NON-NLS-1$
 		    consumeEnumHeaderName();  
 			break;
  
-     case 647 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); }  //$NON-NLS-1$
+     case 663 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); }  //$NON-NLS-1$
 		    consumeEnumHeaderNameWithTypeParameters();  
 			break;
  
-     case 648 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
+     case 664 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 649 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
+     case 665 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); }  //$NON-NLS-1$
 		    consumeEnumBodyNoConstants();  
 			break;
  
-     case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
+     case 666 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-     case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
+     case 667 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); }  //$NON-NLS-1$
 		    consumeEnumBodyWithConstants();  
 			break;
  
-    case 653 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
+    case 669 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); }  //$NON-NLS-1$
 		    consumeEnumConstants();  
 			break;
  
-    case 654 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
+    case 670 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); }  //$NON-NLS-1$
 		    consumeEnumConstantHeaderName();  
 			break;
  
-    case 655 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
+    case 671 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); }  //$NON-NLS-1$
 		    consumeEnumConstantHeader();  
 			break;
  
-    case 656 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
+    case 672 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); }  //$NON-NLS-1$
 		    consumeEnumConstantWithClassBody();  
 			break;
  
-    case 657 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
+    case 673 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); }  //$NON-NLS-1$
 		    consumeEnumConstantNoClassBody();  
 			break;
  
-    case 658 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
+    case 674 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); }  //$NON-NLS-1$
 		    consumeArguments();  
 			break;
  
-    case 659 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
+    case 675 : if (DEBUG) { System.out.println("Argumentsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyArguments();  
 			break;
  
-    case 661 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
+    case 677 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); }  //$NON-NLS-1$
 		    consumeEnumDeclarations();  
 			break;
  
-    case 662 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 678 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyEnumDeclarations();  
 			break;
  
-    case 664 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
+    case 680 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 665 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
+    case 681 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatement();  
 			break;
  
-    case 666 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); }  //$NON-NLS-1$
+    case 682 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeaderInit(false);  
 			break;
  
-    case 667 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); }  //$NON-NLS-1$
+    case 683 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeaderInit(true);  
 			break;
  
-    case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); }  //$NON-NLS-1$
+    case 684 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); }  //$NON-NLS-1$
 		    consumeEnhancedForStatementHeader();  
 			break;
  
-    case 669 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); }  //$NON-NLS-1$
+    case 685 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 670 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); }  //$NON-NLS-1$
+    case 686 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); }  //$NON-NLS-1$
 		    consumeSingleStaticImportDeclarationName();  
 			break;
  
-    case 671 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
+    case 687 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeImportDeclaration();  
 			break;
  
-    case 672 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); }  //$NON-NLS-1$
+    case 688 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); }  //$NON-NLS-1$
 		    consumeStaticImportOnDemandDeclarationName();  
 			break;
  
-    case 673 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+    case 689 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
 		    consumeTypeArguments();  
 			break;
  
-    case 674 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
+    case 690 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); }  //$NON-NLS-1$
 		    consumeOnlyTypeArguments();  
 			break;
  
-    case 676 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 692 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList1();  
 			break;
  
-    case 678 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); }  //$NON-NLS-1$
+    case 694 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); }  //$NON-NLS-1$
 		    consumeTypeArgumentList();  
 			break;
  
-    case 679 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); }  //$NON-NLS-1$
+    case 695 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); }  //$NON-NLS-1$
 		    consumeTypeArgument();  
 			break;
  
-    case 683 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); }  //$NON-NLS-1$
+    case 699 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); }  //$NON-NLS-1$
 		    consumeReferenceType1();  
 			break;
  
-    case 684 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+    case 700 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentReferenceType1();  
 			break;
  
-    case 686 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 702 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList2();  
 			break;
  
-    case 689 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 705 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeReferenceType2();  
 			break;
  
-    case 690 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
+    case 706 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentReferenceType2();  
 			break;
  
-    case 692 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
+    case 708 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeArgumentList3();  
 			break;
  
-    case 695 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 711 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeReferenceType3();  
 			break;
  
-    case 696 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); }  //$NON-NLS-1$
+    case 712 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); }  //$NON-NLS-1$
 		    consumeWildcard();  
 			break;
  
-    case 697 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); }  //$NON-NLS-1$
+    case 713 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); }  //$NON-NLS-1$
 		    consumeWildcardWithBounds();  
 			break;
  
-    case 698 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); }  //$NON-NLS-1$
+    case 714 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); }  //$NON-NLS-1$
 		    consumeWildcardBoundsExtends();  
 			break;
  
-    case 699 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); }  //$NON-NLS-1$
+    case 715 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); }  //$NON-NLS-1$
 		    consumeWildcardBoundsSuper();  
 			break;
  
-    case 700 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); }  //$NON-NLS-1$
+    case 716 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); }  //$NON-NLS-1$
 		    consumeWildcard1();  
 			break;
  
-    case 701 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+    case 717 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
 		    consumeWildcard1WithBounds();  
 			break;
  
-    case 702 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); }  //$NON-NLS-1$
+    case 718 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); }  //$NON-NLS-1$
 		    consumeWildcardBounds1Extends();  
 			break;
  
-    case 703 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); }  //$NON-NLS-1$
+    case 719 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); }  //$NON-NLS-1$
 		    consumeWildcardBounds1Super();  
 			break;
  
-    case 704 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); }  //$NON-NLS-1$
+    case 720 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); }  //$NON-NLS-1$
 		    consumeWildcard2();  
 			break;
  
-    case 705 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+    case 721 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
 		    consumeWildcard2WithBounds();  
 			break;
  
-    case 706 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); }  //$NON-NLS-1$
+    case 722 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); }  //$NON-NLS-1$
 		    consumeWildcardBounds2Extends();  
 			break;
  
-    case 707 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); }  //$NON-NLS-1$
+    case 723 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); }  //$NON-NLS-1$
 		    consumeWildcardBounds2Super();  
 			break;
  
-    case 708 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+    case 724 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
 		    consumeWildcard3();  
 			break;
  
-    case 709 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
+    case 725 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); }  //$NON-NLS-1$
 		    consumeWildcard3WithBounds();  
 			break;
  
-    case 710 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); }  //$NON-NLS-1$
+    case 726 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); }  //$NON-NLS-1$
 		    consumeWildcardBounds3Extends();  
 			break;
  
-    case 711 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); }  //$NON-NLS-1$
+    case 727 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); }  //$NON-NLS-1$
 		    consumeWildcardBounds3Super();  
 			break;
  
-    case 712 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); }  //$NON-NLS-1$
+    case 728 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); }  //$NON-NLS-1$
 		    consumeTypeParameterHeader();  
 			break;
  
-    case 713 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); }  //$NON-NLS-1$
+    case 729 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); }  //$NON-NLS-1$
 		    consumeTypeParameters();  
 			break;
  
-    case 715 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+    case 731 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeParameterList();  
 			break;
  
-    case 717 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 733 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameterWithExtends();  
 			break;
  
-    case 718 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 734 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameterWithExtendsAndBounds();  
 			break;
  
-    case 720 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+    case 736 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); }  //$NON-NLS-1$
 		    consumeAdditionalBoundList();  
 			break;
  
-    case 721 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); }  //$NON-NLS-1$
+    case 737 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); }  //$NON-NLS-1$
 		    consumeAdditionalBound();  
 			break;
  
-    case 723 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
+    case 739 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); }  //$NON-NLS-1$
 		    consumeTypeParameterList1();  
 			break;
  
-    case 724 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); }  //$NON-NLS-1$
+    case 740 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); }  //$NON-NLS-1$
 		    consumeTypeParameter1();  
 			break;
  
-    case 725 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 741 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameter1WithExtends();  
 			break;
  
-    case 726 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
+    case 742 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); }  //$NON-NLS-1$
 		    consumeTypeParameter1WithExtendsAndBounds();  
 			break;
  
-    case 728 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); }  //$NON-NLS-1$
+    case 744 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); }  //$NON-NLS-1$
 		    consumeAdditionalBoundList1();  
 			break;
  
-    case 729 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); }  //$NON-NLS-1$
+    case 745 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); }  //$NON-NLS-1$
 		    consumeAdditionalBound1();  
 			break;
  
-    case 735 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); }  //$NON-NLS-1$
+    case 751 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 736 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); }  //$NON-NLS-1$
+    case 752 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 739 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); }  //$NON-NLS-1$
+    case 755 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.TWIDDLE);  
 			break;
  
-    case 740 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); }  //$NON-NLS-1$
+    case 756 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); }  //$NON-NLS-1$
 		    consumeUnaryExpression(OperatorIds.NOT);  
 			break;
  
-    case 743 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 759 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MULTIPLY);  
 			break;
  
-    case 744 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); }  //$NON-NLS-1$
+    case 760 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.MULTIPLY);  
 			break;
  
-    case 745 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 761 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.DIVIDE);  
 			break;
  
-    case 746 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); }  //$NON-NLS-1$
+    case 762 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.DIVIDE);  
 			break;
  
-    case 747 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 763 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.REMAINDER);  
 			break;
  
-    case 748 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); }  //$NON-NLS-1$
+    case 764 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.REMAINDER);  
 			break;
  
-    case 750 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 766 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.PLUS);  
 			break;
  
-    case 751 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); }  //$NON-NLS-1$
+    case 767 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.PLUS);  
 			break;
  
-    case 752 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 768 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.MINUS);  
 			break;
  
-    case 753 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); }  //$NON-NLS-1$
+    case 769 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.MINUS);  
 			break;
  
-    case 755 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 771 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 756 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); }  //$NON-NLS-1$
+    case 772 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT);  
 			break;
  
-    case 757 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 773 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 758 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 774 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT);  
 			break;
  
-    case 759 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
+    case 775 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 760 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); }  //$NON-NLS-1$
+    case 776 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT);  
 			break;
  
-    case 762 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+    case 778 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS);  
 			break;
  
-    case 763 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); }  //$NON-NLS-1$
+    case 779 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LESS);  
 			break;
  
-    case 764 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
+    case 780 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER);  
 			break;
  
-    case 765 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); }  //$NON-NLS-1$
+    case 781 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.GREATER);  
 			break;
  
-    case 766 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 782 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 767 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); }  //$NON-NLS-1$
+    case 783 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL);  
 			break;
  
-    case 768 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 784 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 769 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); }  //$NON-NLS-1$
+    case 785 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL);  
 			break;
  
-    case 771 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); }  //$NON-NLS-1$
+    case 787 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); }  //$NON-NLS-1$
 		    consumeInstanceOfExpressionWithName();  
 			break;
  
-    case 772 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 788 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeInstanceOfExpression();  
 			break;
  
-    case 774 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 790 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 775 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); }  //$NON-NLS-1$
+    case 791 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL);  
 			break;
  
-    case 776 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 792 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeEqualityExpression(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 777 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); }  //$NON-NLS-1$
+    case 793 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); }  //$NON-NLS-1$
 		    consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL);  
 			break;
  
-    case 779 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); }  //$NON-NLS-1$
+    case 795 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND);  
 			break;
  
-    case 780 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); }  //$NON-NLS-1$
+    case 796 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.AND);  
 			break;
  
-    case 782 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 798 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.XOR);  
 			break;
  
-    case 783 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); }  //$NON-NLS-1$
+    case 799 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.XOR);  
 			break;
  
-    case 785 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 801 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR);  
 			break;
  
-    case 786 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); }  //$NON-NLS-1$
+    case 802 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.OR);  
 			break;
  
-    case 788 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 804 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.AND_AND);  
 			break;
  
-    case 789 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); }  //$NON-NLS-1$
+    case 805 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.AND_AND);  
 			break;
  
-    case 791 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 807 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeBinaryExpression(OperatorIds.OR_OR);  
 			break;
  
-    case 792 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); }  //$NON-NLS-1$
+    case 808 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); }  //$NON-NLS-1$
 		    consumeBinaryExpressionWithName(OperatorIds.OR_OR);  
 			break;
  
-    case 794 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); }  //$NON-NLS-1$
+    case 810 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); }  //$NON-NLS-1$
 		    consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 795 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); }  //$NON-NLS-1$
+    case 811 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); }  //$NON-NLS-1$
 		    consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ;  
 			break;
  
-    case 799 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
+    case 815 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderName() ;  
 			break;
  
-    case 800 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
+    case 816 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ;  
 			break;
  
-    case 801 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
+    case 817 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ;  
 			break;
  
-    case 802 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
+    case 818 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeaderName() ;  
 			break;
  
-    case 803 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); }  //$NON-NLS-1$
+    case 819 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclarationHeader() ;  
 			break;
  
-    case 804 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); }  //$NON-NLS-1$
+    case 820 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeDeclaration() ;  
 			break;
  
-    case 806 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); }  //$NON-NLS-1$
+    case 822 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyAnnotationTypeMemberDeclarationsopt() ;  
 			break;
  
-    case 807 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
+    case 823 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeMemberDeclarationsopt() ;  
 			break;
  
-    case 809 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); }  //$NON-NLS-1$
+    case 825 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeMemberDeclarations() ;  
 			break;
  
-    case 810 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); }  //$NON-NLS-1$
+    case 826 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderNameWithTypeParameters(true);  
 			break;
  
-    case 811 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 827 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeMethodHeaderName(true);  
 			break;
  
-    case 812 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); }  //$NON-NLS-1$
+    case 828 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyMethodHeaderDefaultValue() ;  
 			break;
  
-    case 813 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); }  //$NON-NLS-1$
+    case 829 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); }  //$NON-NLS-1$
 		    consumeMethodHeaderDefaultValue();  
 			break;
  
-    case 814 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); }  //$NON-NLS-1$
+    case 830 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
-    case 815 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); }  //$NON-NLS-1$
+    case 831 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); }  //$NON-NLS-1$
 		    consumeAnnotationTypeMemberDeclaration() ;  
 			break;
  
-    case 823 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); }  //$NON-NLS-1$
+    case 839 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); }  //$NON-NLS-1$
 		    consumeAnnotationName() ;  
 			break;
  
-    case 824 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
+    case 840 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
 		    consumeNormalAnnotation(false) ;  
 			break;
  
-    case 825 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); }  //$NON-NLS-1$
+    case 841 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); }  //$NON-NLS-1$
 		    consumeEmptyMemberValuePairsopt() ;  
 			break;
  
-    case 828 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); }  //$NON-NLS-1$
+    case 844 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); }  //$NON-NLS-1$
 		    consumeMemberValuePairs() ;  
 			break;
  
-    case 829 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); }  //$NON-NLS-1$
+    case 845 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); }  //$NON-NLS-1$
 		    consumeMemberValuePair() ;  
 			break;
  
-    case 830 : if (DEBUG) { System.out.println("EnterMemberValue ::="); }  //$NON-NLS-1$
+    case 846 : if (DEBUG) { System.out.println("EnterMemberValue ::="); }  //$NON-NLS-1$
 		    consumeEnterMemberValue() ;  
 			break;
  
-    case 831 : if (DEBUG) { System.out.println("ExitMemberValue ::="); }  //$NON-NLS-1$
+    case 847 : if (DEBUG) { System.out.println("ExitMemberValue ::="); }  //$NON-NLS-1$
 		    consumeExitMemberValue() ;  
 			break;
  
-    case 833 : if (DEBUG) { System.out.println("MemberValue ::= Name"); }  //$NON-NLS-1$
+    case 849 : if (DEBUG) { System.out.println("MemberValue ::= Name"); }  //$NON-NLS-1$
 		    consumeMemberValueAsName() ;  
 			break;
  
-    case 836 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+    case 852 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
 		    consumeMemberValueArrayInitializer() ;  
 			break;
  
-    case 837 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+    case 853 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
 		    consumeMemberValueArrayInitializer() ;  
 			break;
  
-    case 838 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+    case 854 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
 		    consumeEmptyMemberValueArrayInitializer() ;  
 			break;
  
-    case 839 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
+    case 855 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); }  //$NON-NLS-1$
 		    consumeEmptyMemberValueArrayInitializer() ;  
 			break;
  
-    case 840 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); }  //$NON-NLS-1$
+    case 856 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); }  //$NON-NLS-1$
 		    consumeEnterMemberValueArrayInitializer() ;  
 			break;
  
-    case 842 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); }  //$NON-NLS-1$
+    case 858 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); }  //$NON-NLS-1$
 		    consumeMemberValues() ;  
 			break;
  
-    case 843 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); }  //$NON-NLS-1$
+    case 859 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); }  //$NON-NLS-1$
 		    consumeMarkerAnnotation(false) ;  
 			break;
  
-    case 844 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); }  //$NON-NLS-1$
+    case 860 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); }  //$NON-NLS-1$
 		    consumeSingleMemberAnnotationMemberValue() ;  
 			break;
  
-    case 845 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
+    case 861 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); }  //$NON-NLS-1$
 		    consumeSingleMemberAnnotation(false) ;  
 			break;
  
-    case 846 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); }  //$NON-NLS-1$
+    case 862 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); }  //$NON-NLS-1$
 		    consumeRecoveryMethodHeaderNameWithTypeParameters();  
 			break;
  
-    case 847 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
+    case 863 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); }  //$NON-NLS-1$
 		    consumeRecoveryMethodHeaderName();  
 			break;
  
-    case 848 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); }  //$NON-NLS-1$
+    case 864 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); }  //$NON-NLS-1$
 		    consumeRecoveryMethodHeaderNameWithTypeParameters();  
 			break;
  
-    case 849 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); }  //$NON-NLS-1$
+    case 865 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); }  //$NON-NLS-1$
 		    consumeRecoveryMethodHeaderName();  
 			break;
  
-    case 850 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
+    case 866 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
-    case 851 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
+    case 867 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); }  //$NON-NLS-1$
 		    consumeMethodHeader();  
 			break;
  
@@ -9015,12 +9082,21 @@
 	// BreakStatement ::= 'break' Identifier ';'
 	// break pushs a position on this.intStack in case there is no label
 
-	pushOnAstStack(
-		new BreakStatement(
-			this.identifierStack[this.identifierPtr--],
-			this.intStack[this.intPtr--],
-			this.endStatementPosition));
-	this.identifierLengthPtr--;
+	// add the compliance check
+		if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) {
+			Expression expr = this.expressionStack[this.expressionPtr--];
+			char[] labelOrExpr = expr instanceof Literal ?
+					((Literal) expr).source() : expr instanceof SingleNameReference ? ((SingleNameReference) expr).token : null;
+			BreakStatement breakStatement = new BreakStatement(
+					labelOrExpr,
+					this.intStack[this.intPtr--],
+					this.endStatementPosition);
+			pushOnAstStack(breakStatement);
+			breakStatement.expression = expr; // need to figure out later whether this is a label or an expression.
+			if (expr instanceof SingleNameReference) {
+				((SingleNameReference) expr).isLabel = true;
+			}
+		}
 }
 protected void consumeStatementCatch() {
 	// CatchClause ::= 'catch' '(' FormalParameter ')'    Block
@@ -9198,25 +9274,25 @@
 		pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endStatementPosition));
 	}
 }
-protected void consumeStatementSwitch() {
-	// SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
-
+private void createSwitchStatementOrExpression(boolean isStmt) {
+	
 	//OpenBlock just makes the semantic action blockStart()
 	//the block is inlined but a scope need to be created
 	//if some declaration occurs.
+	this.nestedType--;
 
 	int length;
-	SwitchStatement switchStatement = new SwitchStatement();
+	SwitchStatement switchStatement = isStmt ? new SwitchStatement() : new SwitchExpression();
 	this.expressionLengthPtr--;
 	switchStatement.expression = this.expressionStack[this.expressionPtr--];
 	if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) {
 		this.astPtr -= length;
 		System.arraycopy(
-			this.astStack,
-			this.astPtr + 1,
-			switchStatement.statements = new Statement[length],
-			0,
-			length);
+				this.astStack,
+				this.astPtr + 1,
+				switchStatement.statements = new Statement[length],
+				0,
+				length);
 	}
 	switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--];
 	pushOnAstStack(switchStatement);
@@ -9225,7 +9301,11 @@
 	switchStatement.sourceEnd = this.endStatementPosition;
 	if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) {
 		switchStatement.bits |= ASTNode.UndocumentedEmptyBlock;
-	}
+	}	
+}
+protected void consumeStatementSwitch() {
+	// SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock
+	createSwitchStatementOrExpression(true);
 }
 protected void consumeStatementSynchronized() {
 	// SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
@@ -9422,6 +9502,7 @@
 protected void consumeSwitchBlock() {
 	// SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}'
 	concatNodeLists();
+	
 }
 protected void consumeSwitchBlockStatement() {
 	// SwitchBlockStatement ::= SwitchLabels BlockStatements
@@ -9435,6 +9516,109 @@
 	// SwitchLabels ::= SwitchLabels SwitchLabel
 	optimizedConcatNodeLists();
 }
+protected void consumeSwitchLabelCaseLhs() {
+//	System.out.println("consumeSwitchLabelCaseLhs");
+}
+protected void consumeCaseLabelExpr() {
+//	SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->'
+	consumeCaseLabel();
+	CaseStatement caseStatement = (CaseStatement) this.astStack[this.astPtr];
+	if (!this.parsingJava12Plus) {
+//		problemReporter().caseStatementWithArrowNotBelow12(caseStatement);
+		problemReporter().previewFeatureNotSupported(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$
+	} else if (!this.options.enablePreviewFeatures){
+		problemReporter().previewFeatureNotEnabled(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$
+	} else {
+		if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) {
+			problemReporter().previewFeatureUsed(caseStatement.sourceStart, caseStatement.sourceEnd);
+		}
+	}
+	caseStatement.isExpr = true;
+}
+protected void consumeDefaultLabelExpr() {
+//	SwitchLabelDefaultExpr ::= 'default' '->'
+	consumeDefaultLabel();
+	CaseStatement defaultStatement = (CaseStatement) this.astStack[this.astPtr];
+	if (!this.parsingJava12Plus) {
+//		problemReporter().caseStatementWithArrowNotBelow12(defaultStatement);
+		problemReporter().previewFeatureNotSupported(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$
+	} else if (!this.options.enablePreviewFeatures){
+		problemReporter().previewFeatureNotEnabled(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$
+	} else {
+		if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) {
+			problemReporter().previewFeatureUsed(defaultStatement.sourceStart, defaultStatement.sourceEnd);
+		}
+	}
+	defaultStatement.isExpr = true;
+}
+protected void consumeSwitchExpression() {
+// SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchExpressionBlock
+	createSwitchStatementOrExpression(false);
+	if (this.astLengthStack[this.astLengthPtr--] != 0) {
+		SwitchExpression s = (SwitchExpression) this.astStack[this.astPtr--];
+
+		if (!this.parsingJava12Plus) {
+			problemReporter().previewFeatureNotSupported(s.sourceStart, s.sourceEnd, "Switch Expressions", CompilerOptions.VERSION_12); //$NON-NLS-1$
+		} else if (!this.options.enablePreviewFeatures) {
+			problemReporter().previewFeatureNotEnabled(s.sourceStart, s.sourceEnd, "Switch Expressions"); //$NON-NLS-1$
+		} else {
+			if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) {
+				problemReporter().previewFeatureUsed(s.sourceStart, s.sourceEnd);
+			}
+		}
+
+		pushOnExpressionStack(s);
+	}
+}
+protected void consumeSwitchExprThrowDefaultArm() {
+//	SwitchExprThrowDefaultArm ::= SwitchLabelDefaultExpr Expression ';'
+	consumeStatementThrow();
+//	pushSwitchLabeledRule(SwitchLabeledRule.RULE_KIND.DEFAULT_THROW);
+}
+protected void consumeConstantExpression() {
+	// do nothing for now.
+}
+protected void consumeConstantExpressions() {
+	concatExpressionLists();
+}
+protected void consumeSwitchLabeledRules() {
+	concatNodeLists();
+}
+protected void consumeSwitchLabeledRule() {
+//	SwitchLabeledRule ::= SwitchLabeledExpression
+//	SwitchLabeledRule ::= SwitchLabeledBlock
+//	SwitchLabeledRule ::= SwitchLabeledThrowStatement
+//	concatNodeLists();
+
+	// do nothing explicit here
+}
+protected void consumeSwitchLabeledRuleToBlockStatement() {
+	// do nothing
+}
+protected void consumeSwitchLabeledExpression() {
+	consumeExpressionStatement();
+	Expression expr = (Expression) this.astStack[this.astPtr];
+	BreakStatement breakStatement = new BreakStatement(
+			null,
+			expr.sourceStart,
+			this.endStatementPosition);
+	breakStatement.isImplicit = true;
+	breakStatement.expression = expr;
+	this.astStack[this.astPtr] = breakStatement;
+	concatNodeLists();
+} 
+protected void consumeSwitchLabeledBlock() {
+	concatNodeLists();
+}  
+protected void consumeSwitchLabeledThrowStatement() {
+	// TODO: Semicolon not there - so we call this early
+	consumeStatementThrow(); 
+	concatNodeLists();
+}
+protected void consumeThrowExpression() {
+	// do nothing
+}
+protected boolean caseFlagSet = false;
 protected void consumeToken(int type) {
 	/* remember the last consumed value */
 	/* try to minimize the number of build values */
@@ -9458,11 +9642,16 @@
 	//System.out.println(this.scanner.toStringAction(type));
 	switch (type) {
 		case TokenNameARROW:
-			consumeLambdaHeader();
+			if (!this.caseFlagSet  && this.scanner.lookBack[0] != TokenNamedefault)
+				consumeLambdaHeader();
+			this.caseFlagSet = false;
 			break;
 		case TokenNameCOLON_COLON:
 			this.colonColonStart = this.scanner.currentPosition - 2;
 			break;
+		case TokenNameBeginCaseExpr:
+			this.caseFlagSet = true;
+			break;
 		case TokenNameBeginLambda:
 			flushCommentsDefinedPriorTo(this.scanner.currentPosition);
 			break;
@@ -9674,7 +9863,6 @@
 		case TokenNamethrow :
 		case TokenNamedo :
 		case TokenNameif :
-		case TokenNameswitch :
 		case TokenNametry :
 		case TokenNamewhile :
 		case TokenNamebreak :
@@ -9689,6 +9877,11 @@
 		case TokenNameprovides:
 			pushOnIntStack(this.scanner.startPosition);
 			break;
+		case TokenNameswitch :
+			consumeNestedType();
+			this.nestedMethod[this.nestedType] ++;
+			pushOnIntStack(this.scanner.startPosition);
+			break;
 		case TokenNamenew :
 			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954
 			resetModifiers();
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
index 20d477f..da927b5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- *  
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -19,22 +23,22 @@
 
 	public final static int
 
-	ERROR_SYMBOL = 128,
+	ERROR_SYMBOL = 129,
 					MAX_NAME_LENGTH = 41,
-					NUM_STATES = 1152,
+					NUM_STATES = 1166,
 
-					NT_OFFSET = 128,
-					SCOPE_UBOUND = 290,
-					SCOPE_SIZE = 291,
-					LA_STATE_OFFSET = 16451,
+					NT_OFFSET = 129,
+					SCOPE_UBOUND = 297,
+					SCOPE_SIZE = 298,
+					LA_STATE_OFFSET = 16966,
 					MAX_LA = 1,
-					NUM_RULES = 851,
-					NUM_TERMINALS = 128,
-					NUM_NON_TERMINALS = 388,
-					NUM_SYMBOLS = 516,
-					START_STATE = 895,
-					EOFT_SYMBOL = 60,
-					EOLT_SYMBOL = 60,
-					ACCEPT_ACTION = 16450,
-					ERROR_ACTION = 16451;
+					NUM_RULES = 867,
+					NUM_TERMINALS = 129,
+					NUM_NON_TERMINALS = 397,
+					NUM_SYMBOLS = 526,
+					START_STATE = 1124,
+					EOFT_SYMBOL = 61,
+					EOLT_SYMBOL = 61,
+					ACCEPT_ACTION = 16965,
+					ERROR_ACTION = 16966;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 43e2477..05fd504 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking
@@ -106,6 +110,7 @@
 	public boolean wasAcr = false;
 
 	public boolean fakeInModule = false;
+	boolean inCase = false;
 	/**
 	 * The current context of the scanner w.r.t restricted keywords
 	 *
@@ -1158,7 +1163,12 @@
 	}
 	this.nextToken = unambiguousToken;
 }
-
+private void updateCase(int token) {
+	if (token == TokenNamecase) 
+		this.inCase = true;
+	if (token == TokenNameCOLON || token == TokenNameARROW) 
+		this.inCase = false;
+}
 public int getNextToken() throws InvalidInputException {
 	
 	int token;
@@ -1179,13 +1189,14 @@
 	if (this.activeParser == null) { // anybody interested in the grammatical structure of the program should have registered.
 		return token;
 	}
-	if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT) {
+	if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT || token == TokenNameARROW) {
 		token = disambiguatedToken(token);
 	} else if (token == TokenNameELLIPSIS) {
 		this.consumingEllipsisAnnotations = false;
 	}
 	this.lookBack[0] = this.lookBack[1];
 	this.lookBack[1] = token;
+	updateCase(token);
 	return token;
 }
 protected int getNextToken0() throws InvalidInputException {
@@ -4824,7 +4835,11 @@
 }
 int disambiguatedToken(int token) {
 	final VanguardParser parser = getVanguardParser();
-	if (token == TokenNameLPAREN  && maybeAtLambdaOrCast()) {
+	if (token == TokenNameARROW  && this.inCase) {
+		this.nextToken = TokenNameARROW;
+		this.inCase = false;
+		return TokenNameBeginCaseExpr;
+	} else	if (token == TokenNameLPAREN  && maybeAtLambdaOrCast()) {
 		if (parser.parse(Goal.LambdaParameterListGoal) == VanguardParser.SUCCESS) {
 			this.nextToken = TokenNameLPAREN;
 			return TokenNameBeginLambda;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
index c9bf5ce..d20a4d2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java
@@ -47,6 +47,7 @@
 	private static long[][][] Tables8;
 	private static long[][][] Tables9;
 	private static long[][][] Tables11;
+	private static long[][][] Tables12;
 
 	public final static int MAX_OBVIOUS = 128;
 	public final static int[] OBVIOUS_IDENT_CHAR_NATURES = new int[MAX_OBVIOUS];
@@ -151,6 +152,9 @@
 static void initializeTableJava11() {
 	Tables11 = initializeTables("unicode10"); //$NON-NLS-1$
 }
+static void initializeTableJava12() {
+	Tables12 = initializeTables("unicode11"); //$NON-NLS-1$
+}
 static long[][][] initializeTables(String unicode_path) {
 	long[][][] tempTable = new long[2][][];
 	tempTable[START_INDEX] = new long[3][];
@@ -290,12 +294,18 @@
 			initializeTable19();
 		}
 		return isJavaIdentifierPart0(codePoint, Tables9);
-	} else {
+	} else if (complianceLevel <= ClassFileConstants.JDK11) {
 		// java 11 supports Unicode 10
 		if (Tables11 == null) {
 			initializeTableJava11();
 		}
 		return isJavaIdentifierPart0(codePoint, Tables11);
+	} else {
+		// java 12 supports Unicode 11
+		if (Tables12 == null) {
+			initializeTableJava12();
+		}
+		return isJavaIdentifierPart0(codePoint, Tables12);
 	}
 }
 public static boolean isJavaIdentifierPart(long complianceLevel, char high, char low) {
@@ -351,12 +361,19 @@
 			initializeTable19();
 		}
 		return isJavaIdentifierStart0(codePoint, Tables9);
-	} else {
+	} else if (complianceLevel <= ClassFileConstants.JDK11) {
 		// java 11 supports Unicode 10
 		if (Tables11 == null) {
 			initializeTableJava11();
 		}
 		return isJavaIdentifierStart0(codePoint, Tables11);
+	} else {
+		
+		// java 12 supports Unicode 11
+		if (Tables12 == null) {
+			initializeTableJava12();
+		}
+		return isJavaIdentifierStart0(codePoint, Tables12);
 	}
 }
 private static int toCodePoint(char high, char low) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
index e7f6bb9..12c16db 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,9 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -39,75 +42,75 @@
 							TokenNameCOMMENT_JAVADOC = 1003;
 
 	int TokenNameIdentifier = 22,
-							TokenNameabstract = 51,
-							TokenNameassert = 73,
-							TokenNameboolean = 97,
-							TokenNamebreak = 74,
-							TokenNamebyte = 98,
-							TokenNamecase = 99,
-							TokenNamecatch = 100,
-							TokenNamechar = 101,
-							TokenNameclass = 66,
-							TokenNamecontinue = 75,
-							TokenNameconst = 126,
-							TokenNamedefault = 71,
-							TokenNamedo = 76,
-							TokenNamedouble = 102,
-							TokenNameelse = 111,
-							TokenNameenum = 69,
-							TokenNameextends = 85,
-							TokenNamefalse = 39,
-							TokenNamefinal = 52,
-							TokenNamefinally = 109,
-							TokenNamefloat = 103,
-							TokenNamefor = 77,
-							TokenNamegoto = 127,
-							TokenNameif = 78,
-							TokenNameimplements = 122,
-							TokenNameimport = 104,
+							TokenNameabstract = 52,
+							TokenNameassert = 76,
+							TokenNameboolean = 99,
+							TokenNamebreak = 77,
+							TokenNamebyte = 100,
+							TokenNamecase = 101,
+							TokenNamecatch = 102,
+							TokenNamechar = 103,
+							TokenNameclass = 67,
+							TokenNamecontinue = 78,
+							TokenNameconst = 127,
+							TokenNamedefault = 73,
+							TokenNamedo = 79,
+							TokenNamedouble = 104,
+							TokenNameelse = 112,
+							TokenNameenum = 71,
+							TokenNameextends = 86,
+							TokenNamefalse = 38,
+							TokenNamefinal = 53,
+							TokenNamefinally = 111,
+							TokenNamefloat = 105,
+							TokenNamefor = 80,
+							TokenNamegoto = 128,
+							TokenNameif = 81,
+							TokenNameimplements = 123,
+							TokenNameimport = 106,
 							TokenNameinstanceof = 17,
-							TokenNameint = 105,
-							TokenNameinterface = 68,
-							TokenNamelong = 106,
-							TokenNamenative = 53,
+							TokenNameint = 107,
+							TokenNameinterface = 70,
+							TokenNamelong = 108,
+							TokenNamenative = 54,
 							TokenNamenew = 36,
-							TokenNamenull = 40,
-							TokenNamepackage = 84,
-							TokenNameprivate = 54,
-							TokenNameprotected = 55,
-							TokenNamepublic = 56,
-							TokenNamereturn = 79,
-							TokenNameshort = 107,
-							TokenNamestatic = 38,
-							TokenNamestrictfp = 57,
+							TokenNamenull = 39,
+							TokenNamepackage = 85,
+							TokenNameprivate = 55,
+							TokenNameprotected = 56,
+							TokenNamepublic = 57,
+							TokenNamereturn = 82,
+							TokenNameshort = 109,
+							TokenNamestatic = 48,
+							TokenNamestrictfp = 58,
 							TokenNamesuper = 34,
-							TokenNameswitch = 80,
+							TokenNameswitch = 51,
 							TokenNamesynchronized = 50,
 							TokenNamethis = 35,
-							TokenNamethrow = 81,
-							TokenNamethrows = 119,
-							TokenNametransient = 58,
-							TokenNametrue = 41,
-							TokenNametry = 82,
-							TokenNamevoid = 108,
-							TokenNamevolatile = 59,
-							TokenNamewhile = 72,
-							TokenNamemodule = 112,
-							TokenNameopen = 113,
-							TokenNamerequires = 114,
-							TokenNametransitive = 120,
-							TokenNameexports = 115,
-							TokenNameopens = 116,
-							TokenNameto = 123,
-							TokenNameuses = 117,
-							TokenNameprovides = 118,
-							TokenNamewith = 124,
-							TokenNameIntegerLiteral = 42,
-							TokenNameLongLiteral = 43,
-							TokenNameFloatingPointLiteral = 44,
-							TokenNameDoubleLiteral = 45,
-							TokenNameCharacterLiteral = 46,
-							TokenNameStringLiteral = 47,
+							TokenNamethrow = 74,
+							TokenNamethrows = 120,
+							TokenNametransient = 59,
+							TokenNametrue = 40,
+							TokenNametry = 83,
+							TokenNamevoid = 110,
+							TokenNamevolatile = 60,
+							TokenNamewhile = 75,
+							TokenNamemodule = 113,
+							TokenNameopen = 114,
+							TokenNamerequires = 115,
+							TokenNametransitive = 121,
+							TokenNameexports = 116,
+							TokenNameopens = 117,
+							TokenNameto = 124,
+							TokenNameuses = 118,
+							TokenNameprovides = 119,
+							TokenNamewith = 125,
+							TokenNameIntegerLiteral = 41,
+							TokenNameLongLiteral = 42,
+							TokenNameFloatingPointLiteral = 43,
+							TokenNameDoubleLiteral = 44,
+							TokenNameCharacterLiteral = 45,
+							TokenNameStringLiteral = 46,
 							TokenNamePLUS_PLUS = 2,
 							TokenNameMINUS_MINUS = 3,
 							TokenNameEQUAL_EQUAL = 19,
@@ -117,53 +120,54 @@
 							TokenNameLEFT_SHIFT = 18,
 							TokenNameRIGHT_SHIFT = 14,
 							TokenNameUNSIGNED_RIGHT_SHIFT = 16,
-							TokenNamePLUS_EQUAL = 86,
-							TokenNameMINUS_EQUAL = 87,
-							TokenNameMULTIPLY_EQUAL = 88,
-							TokenNameDIVIDE_EQUAL = 89,
-							TokenNameAND_EQUAL = 90,
-							TokenNameOR_EQUAL = 91,
-							TokenNameXOR_EQUAL = 92,
-							TokenNameREMAINDER_EQUAL = 93,
-							TokenNameLEFT_SHIFT_EQUAL = 94,
-							TokenNameRIGHT_SHIFT_EQUAL = 95,
-							TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 96,
+							TokenNamePLUS_EQUAL = 87,
+							TokenNameMINUS_EQUAL = 88,
+							TokenNameMULTIPLY_EQUAL = 89,
+							TokenNameDIVIDE_EQUAL = 90,
+							TokenNameAND_EQUAL = 91,
+							TokenNameOR_EQUAL = 92,
+							TokenNameXOR_EQUAL = 93,
+							TokenNameREMAINDER_EQUAL = 94,
+							TokenNameLEFT_SHIFT_EQUAL = 95,
+							TokenNameRIGHT_SHIFT_EQUAL = 96,
+							TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 97,
 							TokenNameOR_OR = 31,
 							TokenNameAND_AND = 30,
 							TokenNamePLUS = 4,
 							TokenNameMINUS = 5,
-							TokenNameNOT = 62,
+							TokenNameNOT = 63,
 							TokenNameREMAINDER = 9,
-							TokenNameXOR = 23,
+							TokenNameXOR = 24,
 							TokenNameAND = 21,
 							TokenNameMULTIPLY = 8,
-							TokenNameOR = 27,
-							TokenNameTWIDDLE = 63,
+							TokenNameOR = 28,
+							TokenNameTWIDDLE = 64,
 							TokenNameDIVIDE = 10,
 							TokenNameGREATER = 15,
 							TokenNameLESS = 11,
-							TokenNameLPAREN = 24,
+							TokenNameLPAREN = 23,
 							TokenNameRPAREN = 25,
-							TokenNameLBRACE = 48,
+							TokenNameLBRACE = 49,
 							TokenNameRBRACE = 33,
 							TokenNameLBRACKET = 6,
-							TokenNameRBRACKET = 64,
+							TokenNameRBRACKET = 66,
 							TokenNameSEMICOLON = 26,
 							TokenNameQUESTION = 29,
-							TokenNameCOLON = 61,
+							TokenNameCOLON = 62,
 							TokenNameCOMMA = 32,
 							TokenNameDOT = 1,
-							TokenNameEQUAL = 70,
+							TokenNameEQUAL = 72,
 							TokenNameAT = 37,
-							TokenNameELLIPSIS = 121,
-							TokenNameARROW = 110,
+							TokenNameELLIPSIS = 122,
+							TokenNameARROW = 98,
 							TokenNameCOLON_COLON = 7,
-							TokenNameBeginLambda = 49,
+							TokenNameBeginLambda = 47,
 							TokenNameBeginIntersectionCast = 65,
-							TokenNameBeginTypeArguments = 83,
-							TokenNameElidedSemicolonAndRightBrace = 67,
-							TokenNameAT308 = 28,
-							TokenNameAT308DOTDOTDOT = 125,
-							TokenNameEOF = 60,
-							TokenNameERROR = 128;
+							TokenNameBeginTypeArguments = 84,
+							TokenNameElidedSemicolonAndRightBrace = 68,
+							TokenNameAT308 = 27,
+							TokenNameAT308DOTDOTDOT = 126,
+							TokenNameBeginCaseExpr = 69,
+							TokenNameEOF = 61,
+							TokenNameERROR = 129;
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
index 274fa50..2bd646e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
index 4865baa..a49d711 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
index 37144d4..ef79d1d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
index 867a099..e9fa8cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
index 2c1fbd3..4af7a4f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
index 07b4bf6..24432a1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
index 56d678f..b84e8bb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
index 9e8f596..c5f0e8a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
index 353090b..3cf316c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
index 266bf1b..f25fe9a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
index df3f4df..68c3b12 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
index 3a3cedb..7ae8abe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
index 8bdb123..87ff0c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
index 3031ff9..05ba22c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc
index 518ee2a..ad9e312 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
index c8dd03c..76da0d6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc
index ec7d7e6..5b4675f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
index 9500898..add4528 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
index a1145dc..aa09c17 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
index f56c662..b4b627b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
index 28c6b22..ed603bb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
index 30e76fa..379d8cd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
index e594f6b..4e9607b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
index 4b69399..9670813 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props
index 5268fd6..64eb6d9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props
@@ -84,6 +84,7 @@
 ConditionalOrExpression_NotName=Expression
 ConstantDeclaration=ConstantDeclaration
 ConstantExpression=ConstantExpression
+ConstantExpressions=ConstantExpressions
 ConstructorDeclaration=ConstructorDeclaration
 ConstructorHeader=ConstructorDeclaration
 ConstructorHeaderName=ConstructorHeaderName
@@ -296,10 +297,18 @@
 SwitchBlock=SwitchBlock
 SwitchBlockStatement=SwitchBlockStatement
 SwitchBlockStatements=SwitchBlockStatements
+SwitchExpression=SwitchExpression
 SwitchLabel=SwitchLabel
+SwitchLabelCaseLhs=SwitchLabelCaseLhs
+SwitchLabelExpr=SwitchLabelDefaultExpr
+SwitchLabeledBlock=SwitchLabeledBlock
+SwitchLabeledExpression=SwitchLabeledExpression
+SwitchLabeledRule=SwitchLabeledRule
+SwitchLabeledThrowStatement=SwitchLabeledThrowStatement
 SwitchLabels=SwitchLabels
 SwitchStatement=SwitchStatement
 SynchronizedStatement=SynchronizedStatement
+ThrowExpression=ThrowExpression
 ThrowStatement=ThrowStatement
 TrailingSemiColon=;
 TryBlock=Block
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc
new file mode 100644
index 0000000..f434660
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc
new file mode 100644
index 0000000..abb590b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc
new file mode 100644
index 0000000..c8241e8
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc
new file mode 100644
index 0000000..ab6b33e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc
new file mode 100644
index 0000000..1cd7862
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc
new file mode 100644
index 0000000..2ca6b51
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc
new file mode 100644
index 0000000..ab6b33e
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 1a47e1d..d9361bf 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -7,7 +7,11 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
- * 
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Benjamin Muskalla - Contribution for bug 239066
@@ -154,6 +158,7 @@
 import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
 import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
 import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.SwitchExpression;
 import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
 import org.eclipse.jdt.internal.compiler.ast.ThisReference;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -662,6 +667,8 @@
 			return CompilerOptions.APILeak;
 		case IProblem.UnstableAutoModuleName:
 			return CompilerOptions.UnstableAutoModuleName;
+		case IProblem.PreviewFeatureUsed:
+			return CompilerOptions.PreviewFeatureUsed;
 }
 	return 0;
 }
@@ -806,6 +813,8 @@
 				return CategorizedProblem.CAT_MEMBER;
 			if ((problemID & IProblem.ModuleRelated) != 0)
 				return CategorizedProblem.CAT_MODULE;
+			if ((problemID & IProblem.Compliance) != 0)
+				return CategorizedProblem.CAT_COMPLIANCE;
 	}
 	return CategorizedProblem.CAT_INTERNAL;
 }
@@ -6060,7 +6069,8 @@
 			|| expr instanceof ThisReference) {
 		// fall through to bottom
 	} else if (expr instanceof Literal
-				|| expr instanceof ConditionalExpression) {
+				|| expr instanceof ConditionalExpression
+				|| expr instanceof SwitchExpression) {
 		if (expr instanceof NullLiteral) {
 			needImplementation(location); // reported as nonnull??
 			return false;
@@ -6479,13 +6489,28 @@
 		type.sourceStart,
 		type.sourceEnd);
 }
+
 public void missingEnumConstantCase(SwitchStatement switchStatement, FieldBinding enumConstant) {
+	missingEnumConstantCase(switchStatement.defaultCase, enumConstant, switchStatement.expression);
+}
+public void missingEnumConstantCase(SwitchExpression switchExpression, FieldBinding enumConstant) {
+	missingSwitchExpressionEnumConstantCase(switchExpression.defaultCase, enumConstant, switchExpression.expression);
+}
+private void missingSwitchExpressionEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) {
 	this.handle(
-		switchStatement.defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault,
-		new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) },
-		new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) },
-		switchStatement.expression.sourceStart,
-		switchStatement.expression.sourceEnd);
+			IProblem.SwitchExpressionMissingEnumConstantCase,
+			new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) },
+			new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) },
+			expression.sourceStart,
+			expression.sourceEnd);
+}
+private void missingEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) {
+	this.handle(
+			defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault,
+			new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) },
+			new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) },
+			expression.sourceStart,
+			expression.sourceEnd);
 }
 public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSwitch, TypeBinding expressionType) {
 	if (isEnumSwitch) {
@@ -6497,7 +6522,8 @@
 				switchStatement.expression.sourceEnd);
 	} else {
 		this.handle(
-				IProblem.MissingDefaultCase,
+				switchStatement instanceof SwitchExpression ?
+						IProblem.SwitchExpressionMissingDefaultCase : IProblem.MissingDefaultCase,
 				NoArgument,
 				NoArgument,
 				switchStatement.expression.sourceStart,
@@ -9249,6 +9275,32 @@
 		token.sourceStart,
 		token.sourceEnd);
 }
+public void previewFeatureNotEnabled(int sourceStart, int sourceEnd, String featureName) {
+	String[] args = new String[] {featureName};
+	this.handle(
+			IProblem.PreviewFeatureDisabled,
+			args,
+			args,
+			sourceStart,
+			sourceEnd);
+}
+public void previewFeatureUsed(int sourceStart, int sourceEnd) {
+	this.handle(
+			IProblem.PreviewFeatureUsed,
+			NoArgument,
+			NoArgument,
+			sourceStart,
+			sourceEnd);
+}
+public void previewFeatureNotSupported(int sourceStart, int sourceEnd, String featureName, String sourceLevel) {
+	String[] args = new String[] {featureName, sourceLevel};
+	this.handle(
+			IProblem.PreviewFeatureNotSupported,
+			args,
+			args,
+			sourceStart,
+			sourceEnd);
+}
 public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) {
 	this.handle(
 		IProblem.UseAssertAsAnIdentifier,
@@ -10989,4 +11041,69 @@
 			moduleReference.sourceStart,
 			moduleReference.sourceEnd);
 }
+public void switchExpressionIncompatibleResultExpressions(SwitchExpression expression) {
+	TypeBinding type = expression.resultExpressions.get(0).resolvedType;
+	this.handle(
+		IProblem.SwitchExpressionsIncompatibleResultExpressionTypes,
+		new String[] {new String(type.readableName())},
+		new String[] {new String(type.shortReadableName())},
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void switchExpressionEmptySwitchBlock(SwitchExpression expression) {
+	this.handle(
+		IProblem.SwitchExpressionsEmptySwitchBlock,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void switchExpressionNoResultExpressions(SwitchExpression expression) {
+	this.handle(
+		IProblem.SwitchExpressionsNoResultExpression,
+		NoArgument,
+		NoArgument,
+		expression.sourceStart,
+		expression.sourceEnd);
+}
+public void switchExpressionSwitchLabeledBlockCompletesNormally(Block block) {
+	this.handle(
+		IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally,
+		NoArgument,
+		NoArgument,
+		block.sourceStart,
+		block.sourceEnd);
+}
+public void switchExpressionLastStatementCompletesNormally(Statement stmt) {
+	this.handle(
+		IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally,
+		NoArgument,
+		NoArgument,
+		stmt.sourceStart,
+		stmt.sourceEnd);
+}
+public void switchExpressionTrailingSwitchLabels(Statement stmt) {
+	this.handle(
+		IProblem.SwitchExpressionTrailingSwitchLabels,
+		NoArgument,
+		NoArgument,
+		stmt.sourceStart,
+		stmt.sourceEnd);
+}
+public void switchExpressionMixedCase(ASTNode statement) {
+	this.handle(
+		IProblem.switchMixedCase,
+		NoArgument,
+		NoArgument,
+		statement.sourceStart,
+		statement.sourceEnd);
+}
+public void switchExpressionBreakMissingValue(ASTNode statement) {
+	this.handle(
+		IProblem.SwitchExpressionBreakMissingValue,
+		NoArgument,
+		NoArgument,
+		statement.sourceStart,
+		statement.sourceEnd);
+}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index b4a85c9..37dff5d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2018 IBM Corporation and others.
+# Copyright (c) 2000, 2019 IBM Corporation and others.
 #
 # This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License 2.0
@@ -7,7 +7,10 @@
 # https://www.eclipse.org/legal/epl-2.0/
 #
 # SPDX-License-Identifier: EPL-2.0
-# 
+#
+# This is an implementation of an early-draft specification developed under the Java
+# Community Process (JCP) and is made available for testing and evaluation purposes
+# only. The code is not compatible with any specification of the JCP.
 #
 # Contributors:
 #     IBM Corporation - initial API and implementation
@@ -879,6 +882,9 @@
 1100 = Problem detected during type inference: {0}
 #1101 is already used up but deprecated
 1102 = At least one of the problems in category ''{0}'' is not analysed due to a compiler option being ignored
+1103 = {0} is a preview feature and disabled by default. Use --enable-preview to enable
+1104 = You are using a preview language feature that may or may not be supported in a future release
+1105 = The preview feature {0} is only available with source level {1} and above
 
 # more programming problems:
 1200 = Unlikely argument type {0} for {1} on a {2}
@@ -967,6 +973,20 @@
 1511 = 'var' is not allowed here
 1512 = 'var' cannot be mixed with non-var parameters
 
+# Switch-Expressions
+1600 = Incompatible switch results expressions {0}
+1601 = A switch expression should have a non-empty switch block
+1602 = A switch expression should have at least one result expression
+1603 = A switch labeled block in a switch expression should not complete normally
+1604 = The last statement of a switch block in a switch expression should not complete normally
+1605 = Trailing switch labels are not allowed in a switch expression.
+1606 = Mixing of different kinds of case statements '->' and  ':' is not allowed within a switch
+1607 = A switch expression should have a default case
+1608 = Switch expressions are allowed only at source level 12 or above
+1609 = Switch Case Labels with '->' are allowed only at source level 12 or above
+1610 = Break of a switch expression should have a value
+1611 = A Switch expression should cover all possible values
+
 ### ELABORATIONS
 ## Access restrictions
 78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'')
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
index 51bfc33..5d9b78b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -75,7 +79,7 @@
 		 * how the JRT needs to be processed, for e.g., clients can skip a particular module
 		 * by returning FileVisitResult.SKIP_SUBTREE
 		 */
-		public FileVisitResult visitModule(T mod) throws IOException;
+		public FileVisitResult visitModule(T path, String name) throws IOException;
 	}
 
 	static abstract class AbstractFileVisitor<T> implements FileVisitor<T> {
@@ -180,6 +184,16 @@
 	public static boolean hasCompilationUnit(File jrt, String qualifiedPackageName, String moduleName) {
 		return getJrtSystem(jrt).hasClassFile(qualifiedPackageName, moduleName);
 	}
+	/*
+	 * Returns only the file name after removing trailing '/' if any for folders
+	 */
+	public static String sanitizedFileName(Path path) {
+		String p = path.getFileName().toString();
+		if (p.length() > 1 && p.charAt(p.length() - 1) == '/') {
+			return p.substring(0, p.length() - 1);
+		}
+		return p;
+	}
 	/**
 	 * Tries to read all bytes of the file denoted by path,
 	 * returns null if the file could not be found or if the read was interrupted.
@@ -253,10 +267,7 @@
 			List<String> sub = new ArrayList<>();
 			try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) {
 				for (final java.nio.file.Path subdir: stream) {
-					String r = subdir.getFileName().toString();
-					if (r.endsWith("/")) { //$NON-NLS-1$
-						r = r.substring(0, r.length() - 1);
-					}
+					String r = JRTUtil.sanitizedFileName(subdir);
 					if (r.contains(this.releaseInHex)) {
 						sub.add(r);
 					} else {
@@ -292,7 +303,7 @@
 								return FileVisitResult.SKIP_SUBTREE;
 							}
 							return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? FileVisitResult.CONTINUE
-									: visitor.visitModule(dir);
+									: visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod));
 						}
 						if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) {
 							// client is not interested in packages
@@ -466,7 +477,7 @@
 	byte[] getClassfileContent(String fileName, String module) throws IOException, ClassFormatException {
 		byte[] content = null;
 		if (module != null) {
-			content = getClassfileBytes(fileName, new String(module.toCharArray()));
+			content = getClassfileBytes(fileName, module);
 		} else {
 			String[] modules = getModules(fileName);
 			for (String mod : modules) {
@@ -543,7 +554,7 @@
 						return FileVisitResult.SKIP_SUBTREE;
 					}
 					return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? 
-							FileVisitResult.CONTINUE : visitor.visitModule(mod);
+							FileVisitResult.CONTINUE : visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod));
 				}
 				if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) {
 					// We are dealing with a module or not client is not interested in packages
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
index ce3f494..6004f80 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -270,6 +274,28 @@
 	 * @since 3.14 
 	 */
 	/*package*/ static final int JLS11_INTERNAL = JLS11;
+	
+	/**
+	 * Constant for indicating the AST API that handles JLS12.
+	 * <p>
+	 * This API is capable of handling all constructs in the
+	 * Java language as described in the Java Language
+	 * Specification, Java SE 12 Edition (JLS12).
+	 * JLS12 is a superset of all earlier versions of the
+	 * Java language, and the JLS12 API can be used to manipulate
+	 * programs written in all versions of the Java language
+	 * up to and including Java SE 12 (aka JDK 12).
+	 * </p>
+	 *
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final int JLS12 = 12;
+	/**
+	 * Internal synonym for {@link #JLS11}. Use to alleviate
+	 * deprecation warnings once JLS11 is deprecated
+	 * @since 3.16 
+	 */
+	static final int JLS12_INTERNAL = JLS12;
 
 	/*
 	 * Must not collide with a value for ICompilationUnit constants
@@ -850,7 +876,21 @@
 						null/*taskTag*/,
 						null/*taskPriorities*/,
 						true/*taskCaseSensitive*/);
-				break;	
+				break;
+			case JLS12_INTERNAL :
+				this.apiLevel = level;
+				// initialize a scanner
+				compliance = ClassFileConstants.getComplianceLevelForJavaVersion(ClassFileConstants.MAJOR_VERSION_12);
+				this.scanner = new Scanner(
+						true /*comment*/,
+						true /*whitespace*/,
+						false /*nls*/,
+						compliance /*sourceLevel*/,
+						compliance /*complianceLevel*/,
+						null/*taskTag*/,
+						null/*taskPriorities*/,
+						true/*taskCaseSensitive*/);
+				break;
 			default:
 				throw new IllegalArgumentException("Unsupported JLS level"); //$NON-NLS-1$
 		}
@@ -2539,6 +2579,19 @@
 	}
 
 	/**
+	 * Creates and returns a new unparented switch expression node
+	 * owned by this AST. By default, the expression is unspecified, but legal, 
+	 * and there are no statements or switch cases.
+	 *
+	 * @return a new unparented labeled switch expression node
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public SwitchExpression newSwitchExpression() {
+		SwitchExpression result = new SwitchExpression(this);
+		return result;
+	}
+	
+	/**
 	 * Creates a new unparented switch case statement node owned by
 	 * this AST. By default, the expression is unspecified, but legal.
 	 *
@@ -2548,7 +2601,6 @@
 		return new SwitchCase(this);
 	}
 
-
 	/**
 	 * Creates a new unparented switch statement node owned by this AST.
 	 * By default, the expression is unspecified, but legal, and there are
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 87340a1..6d0a464 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
@@ -360,7 +364,15 @@
 			spanningNode.setFlags(spanningNode.getFlags() | ASTNode.MALFORMED);
 		}
 	}
-
+	/**
+	 * Internal access method to SwitchCase#setExpression() for avoiding deprecated warnings
+	 * @param switchCase
+	 * @param exp
+	 * @deprecated
+	 */
+	private static void internalSetExpression(SwitchCase switchCase, Expression exp) {
+		switchCase.setExpression(exp);
+	}
 	/** 
 	 * Internal access method to SingleVariableDeclaration#setExtraDimensions() for avoiding deprecated warnings
 	 *
@@ -1285,20 +1297,42 @@
 			retrieveIdentifierAndSetPositions(statement.sourceStart, statement.sourceEnd, name);
 			breakStatement.setLabel(name);
 		}
+		else if (statement.expression != null && this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			final Expression expression= convert(statement.expression);
+			breakStatement.setExpression(expression);
+		}
 		return breakStatement;
 	}
 
 
 	public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement statement) {
 		SwitchCase switchCase = new SwitchCase(this.ast);
-		org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
-		if (constantExpression == null) {
-			switchCase.setExpression(null);
+		if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			org.eclipse.jdt.internal.compiler.ast.Expression[] expressions = statement.constantExpressions;
+			if (expressions == null || expressions.length == 0) {
+				switchCase.expressions().clear();
+			} else {
+				for (org.eclipse.jdt.internal.compiler.ast.Expression expression : expressions) {
+					switchCase.expressions().add(convert(expression));
+				}
+			}
 		} else {
-			switchCase.setExpression(convert(constantExpression));
+			org.eclipse.jdt.internal.compiler.ast.Expression constantExpression = statement.constantExpression;
+			if (constantExpression == null) {
+				internalSetExpression(switchCase, null);
+			} else {
+				internalSetExpression(switchCase, convert(constantExpression));
+			}
+		}
+		if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			switchCase.setSwitchLabeledRule(statement.isExpr);
 		}
 		switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
-		retrieveColonPosition(switchCase);
+		if (statement.isExpr) {
+			retrieveArrowPosition(switchCase);
+		} else {
+			retrieveColonPosition(switchCase);
+		}
 		return switchCase;
 	}
 
@@ -1842,6 +1876,9 @@
 		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) {
 			return convert((org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) expression);
 		}
+		if (expression instanceof org.eclipse.jdt.internal.compiler.ast.SwitchExpression) {
+			return convert((org.eclipse.jdt.internal.compiler.ast.SwitchExpression) expression);
+		}
 		return null;
 	}
 
@@ -2686,6 +2723,7 @@
 		return result;
 	}
 
+	
 	public ReturnStatement convert(org.eclipse.jdt.internal.compiler.ast.ReturnStatement statement) {
 		final ReturnStatement returnStatement = new ReturnStatement(this.ast);
 		returnStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
@@ -2827,6 +2865,33 @@
 		return literal;
 	}
 
+	public Expression convert(org.eclipse.jdt.internal.compiler.ast.SwitchExpression expression) {
+		if (this.ast.apiLevel < AST.JLS12_INTERNAL) {
+			return createFakeNullLiteral(expression);		
+		}
+		SwitchExpression switchExpression = new SwitchExpression(this.ast);
+		if (this.resolveBindings) {
+			recordNodes(switchExpression, expression);
+		}
+		switchExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
+		switchExpression.setExpression(convert(expression.expression));
+		org.eclipse.jdt.internal.compiler.ast.Statement[] statements = expression.statements;
+		if (statements != null) {
+			int statementsLength = statements.length;
+			for (int i = 0; i < statementsLength; i++) {
+				if (statements[i] instanceof org.eclipse.jdt.internal.compiler.ast.LocalDeclaration) {
+					checkAndAddMultipleLocalDeclaration(statements, i, switchExpression.statements());
+				} else {
+					final Statement currentStatement = convert(statements[i]);
+					if (currentStatement != null) {
+						switchExpression.statements().add(currentStatement);
+					}
+				}
+			}
+		}
+		return switchExpression;
+	}
+	
 	public SwitchStatement convert(org.eclipse.jdt.internal.compiler.ast.SwitchStatement statement) {
 		SwitchStatement switchStatement = new SwitchStatement(this.ast);
 		switchStatement.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1);
@@ -4226,7 +4291,7 @@
 	 * Warning: Callers of this method must ensure that the fake literal node is not recorded in
 	 * {@link #recordNodes(ASTNode, org.eclipse.jdt.internal.compiler.ast.ASTNode)}, see bug 403444!
 	 */
-	protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.FunctionalExpression expression) {
+	protected Expression createFakeNullLiteral(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
 		if (this.referenceContext != null) {
 			this.referenceContext.setFlags(this.referenceContext.getFlags() | ASTNode.MALFORMED);
 		}
@@ -4795,6 +4860,17 @@
 	 * This method fixes the length of the corresponding node.
 	 */
 	protected void retrieveColonPosition(ASTNode node) {
+		setNodeSourceEndPosition(node, TerminalTokens.TokenNameCOLON);
+	}
+	/**
+	 * This method is used to set the right end position for switch labeled rules ie with '->'
+	 * The actual AST nodes don't include the trailing semicolon.
+	 * This method fixes the length of the corresponding node.
+	 */
+	private void retrieveArrowPosition(ASTNode node) {
+		setNodeSourceEndPosition(node, TerminalTokens.TokenNameARROW);
+	}
+	private void setNodeSourceEndPosition(ASTNode node, int expectedToken) {
 		int start = node.getStartPosition();
 		int length = node.getLength();
 		int end = start + length;
@@ -4802,8 +4878,7 @@
 		try {
 			int token;
 			while ((token = this.scanner.getNextToken()) != TerminalTokens.TokenNameEOF) {
-				switch(token) {
-					case TerminalTokens.TokenNameCOLON:
+				if (token == expectedToken) {
 						node.setSourceRange(start, this.scanner.currentPosition - start);
 						return;
 				}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
index ff2d234..1e0259e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -484,7 +488,9 @@
 			return false;
 		}
 		BreakStatement o = (BreakStatement) other;
-		return safeSubtreeMatch(node.getLabel(), o.getLabel());
+		return ( node.getAST().apiLevel >= AST.JLS12_INTERNAL && node.getExpression() != null
+				? safeSubtreeMatch(node.getExpression(), o.getExpression())
+						: safeSubtreeMatch(node.getLabel(), o.getLabel()));
 	}
 
 	/**
@@ -2267,7 +2273,43 @@
 			return false;
 		}
 		SwitchCase o = (SwitchCase) other;
-		return safeSubtreeMatch(node.getExpression(), o.getExpression());
+		return ( node.getAST().apiLevel >= AST.JLS12_INTERNAL
+				? safeSubtreeListMatch(node.expressions(), o.expressions())
+						: compareDeprecatedSwitchExpression(node, o));
+	}
+	
+	/**
+	 * Return whether the deprecated comment strings of the given java doc are equals.
+	 * <p>
+	 * Note the only purpose of this method is to hide deprecated warnings.
+	 * @deprecated mark deprecated to hide deprecated usage
+	 */
+	private boolean compareDeprecatedSwitchExpression(SwitchCase first, SwitchCase second) {
+		return safeSubtreeMatch(first.getExpression(), second.getExpression());
+	}
+
+	/**
+	 * Returns whether the given node and the other object match.
+	 * <p>
+	 * The default implementation provided by this class tests whether the
+	 * other object is a node of the same type with structurally isomorphic
+	 * child subtrees. Subclasses may override this method as needed.
+	 * </p>
+	 * 
+	 * @param node the node
+	 * @param other the other object, or <code>null</code>
+	 * @return <code>true</code> if the subtree matches, or
+	 *   <code>false</code> if they do not match or the other object has a
+	 *   different node type or is <code>null</code>
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public boolean match(SwitchExpression node, Object other) {
+		if (!(other instanceof SwitchExpression)) {
+			return false;
+		}
+		SwitchExpression o = (SwitchExpression) other;
+		return	safeSubtreeMatch(node.getExpression(), o.getExpression())
+				&& safeSubtreeListMatch(node.statements(), o.statements());
 	}
 
 	/**
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
index ac6d710..11135b6 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -954,6 +958,14 @@
 	 * @since 3.14
 	 */
 	public static final int MODULE_MODIFIER = 99;
+	
+	/**
+	 * Node type constant indicating a node of type
+	 * <code>SwitchExpression</code>.
+	 * @see SwitchExpression
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final int SWITCH_EXPRESSION = 100;
 
 	/**
 	 * Returns the node class for the corresponding node type.
@@ -1129,6 +1141,8 @@
 				return SwitchCase.class;
 			case SWITCH_STATEMENT :
 				return SwitchStatement.class;
+			case SWITCH_EXPRESSION :
+				return SwitchExpression.class;
 			case SYNCHRONIZED_STATEMENT :
 				return SynchronizedStatement.class;
 			case TAG_ELEMENT :
@@ -2071,6 +2085,22 @@
 			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS11 and above"); //$NON-NLS-1$
 		}
 	}
+	
+	/**
+     * Checks that this AST operation is not used when
+     * building JLS2, JLS3, JLS4, JLS8, JLS9,JLS10 or JLS11 level ASTs.
+     * <p>
+     * Use this method to prevent access to new properties that have been added in JLS12
+     * </p>
+     *
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.16 
+	 */
+	final void unsupportedBelow12() {
+		if (this.ast.apiLevel < AST.JLS12_INTERNAL) {
+			throw new UnsupportedOperationException("Operation only supported in ASTs with level JLS12 and above"); //$NON-NLS-1$
+		}
+	}
 	/**
      * Checks that this AST operation is only used when
      * building JLS2 level ASTs.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
index c202eb2..af3682f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2018 IBM Corporation and others.
+ * Copyright (c) 2004, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -234,6 +238,7 @@
 			case AST.JLS9_INTERNAL:
 			case AST.JLS10_INTERNAL:
 			case AST.JLS11_INTERNAL:
+			case AST.JLS12_INTERNAL:
 				break;
 			default:
 				throw new IllegalArgumentException();
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
index b31c3a7..b88b354 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -1521,7 +1525,24 @@
 	public boolean visit(SwitchCase node) {
 		return true;
 	}
-
+	
+	/**
+	 * Visits the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing and return true.
+	 * Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
+	 * @return <code>true</code> if the children of this node should be
+	 * visited, and <code>false</code> if the children of this node should
+	 * be skipped
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public boolean visit(SwitchExpression node) {
+		return true;
+	}
+	
 	/**
 	 * Visits the given type-specific AST node.
 	 * <p>
@@ -2355,7 +2376,7 @@
 	public void endVisit(LambdaExpression node) {
 		// default implementation: do nothing
 	}
-
+	
 	/**
 	 * End of visit the given type-specific AST node.
 	 * <p>
@@ -2830,6 +2851,19 @@
 	 * </p>
 	 *
 	 * @param node the node to visit
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public void endVisit(SwitchExpression node) {
+		// default implementation: do nothing
+	}
+
+	/**
+	 * End of visit the given type-specific AST node.
+	 * <p>
+	 * The default implementation does nothing. Subclasses may reimplement.
+	 * </p>
+	 *
+	 * @param node the node to visit
 	 */
 	public void endVisit(SwitchStatement node) {
 		// default implementation: do nothing
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
index 4cebdc6..2441ce0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BreakStatement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -23,6 +27,9 @@
  * <pre>
  * BreakStatement:
  *    <b>break</b> [ Identifier ] <b>;</b>
+ *    
+ *    Break statement allows expression as part of Java 12 preview feature (JEP 325)
+ *		<b>break</b> <b>{ Identifier | Expression }</b>
  * </pre>
  *
  * @since 2.0
@@ -37,6 +44,13 @@
 	 */
 	public static final ChildPropertyDescriptor LABEL_PROPERTY =
 		new ChildPropertyDescriptor(BreakStatement.class, "label", SimpleName.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
+	
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}). (added in JEP 325).
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+			new ChildPropertyDescriptor(BreakStatement.class, "expression", Expression.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$);
 
 	/**
 	 * A list of property descriptors (element type:
@@ -44,12 +58,25 @@
 	 * or null if uninitialized.
 	 */
 	private static final List PROPERTY_DESCRIPTORS;
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_12;
 
 	static {
 		List properyList = new ArrayList(2);
 		createPropertyList(BreakStatement.class, properyList);
 		addProperty(LABEL_PROPERTY, properyList);
 		PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
+		
+		List properyList_12 = new ArrayList(2);
+		createPropertyList(BreakStatement.class, properyList_12);
+		addProperty(LABEL_PROPERTY, properyList_12);
+		addProperty(EXPRESSION_PROPERTY, properyList_12);
+		PROPERTY_DESCRIPTORS_12 = reapPropertyList(properyList_12);
 	}
 
 	/**
@@ -64,6 +91,9 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel >= AST.JLS12_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_12;
+		}
 		return PROPERTY_DESCRIPTORS;
 	}
 
@@ -71,6 +101,11 @@
 	 * The label, or <code>null</code> if none; none by default.
 	 */
 	private SimpleName optionalLabel = null;
+	
+	/**
+	 * The expression; <code>null</code> for none
+	 */
+	private Expression optionalExpression = null;
 
 	/**
 	 * Creates a new unparented break statement node owned by the given
@@ -99,6 +134,14 @@
 				setLabel((SimpleName) child);
 				return null;
 			}
+		} 
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
 		}
 		// allow default implementation to flag the error
 		return super.internalGetSetChildProperty(property, get, child);
@@ -115,6 +158,9 @@
 		result.setSourceRange(getStartPosition(), getLength());
 		result.copyLeadingComment(this);
 		result.setLabel((SimpleName) ASTNode.copySubtree(target, getLabel()));
+		if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			result.setExpression((Expression) ASTNode.copySubtree(target, getLabel()));
+		}
 		return result;
 	}
 
@@ -128,6 +174,9 @@
 	void accept0(ASTVisitor visitor) {
 		boolean visitChildren = visitor.visit(this);
 		if (visitChildren) {
+			if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+				acceptChild(visitor, getExpression());
+			} 
 			acceptChild(visitor, getLabel());
 		}
 		visitor.endVisit(this);
@@ -160,17 +209,53 @@
 		this.optionalLabel = label;
 		postReplaceChild(oldChild, label, LABEL_PROPERTY);
 	}
+	
+	/**
+	 * Returns the expression of this break statement, or <code>null</code> if
+	 * there is none.
+	 *
+	 * @return the expression, or <code>null</code> if there is none
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public Expression getExpression() {
+		// optionalExpression can be null
+		unsupportedBelow12();
+		return this.optionalExpression;
+	}
+
+	/**
+	 * Sets or clears the expression of this break statement.
+	 *
+	 * @param expression the expression, or <code>null</code> if
+	 *    there is none
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * </ul>
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public void setExpression(Expression expression) {
+		unsupportedBelow12();
+		ASTNode oldChild = this.optionalExpression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.optionalExpression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
 
 	@Override
 	int memSize() {
-		return super.memSize() + 1 * 4;
+		return super.memSize() + 2 * 4;
 	}
 
 	@Override
 	int treeSize() {
 		return
 			memSize()
-			+ (this.optionalLabel == null ? 0 : getLabel().treeSize());
+			+ (this.optionalLabel == null ? 0 : getLabel().treeSize())
+			+ (this.optionalExpression == null ? 0 : getExpression().treeSize());
 	}
 }
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
index e50e553..f926654 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultASTVisitor.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,9 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -334,6 +337,10 @@
 		endVisitNode(node);
 	}
 	@Override
+	public void endVisit(SwitchExpression node) {
+		endVisitNode(node);
+	}
+	@Override
 	public void endVisit(SwitchCase node) {
 		endVisitNode(node);
 	}
@@ -731,6 +738,11 @@
 	public boolean visit(SwitchCase node) {
 		return visitNode(node);
 	}
+	
+	@Override
+	public boolean visit(SwitchExpression node) {
+		return visitNode(node);
+	}
 
 	@Override
 	public boolean visit(SwitchStatement node) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index 341e16e..851500e 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -742,6 +746,7 @@
 				case ASTNode.METHOD_INVOCATION :
 				case ASTNode.SUPER_METHOD_INVOCATION :
 				case ASTNode.CONDITIONAL_EXPRESSION :
+				case ASTNode.SWITCH_EXPRESSION :
 				case ASTNode.MARKER_ANNOTATION :
 				case ASTNode.NORMAL_ANNOTATION :
 				case ASTNode.SINGLE_MEMBER_ANNOTATION :
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
index 13d9688..de760b9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/Expression.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -48,6 +52,7 @@
  *    {@link SuperFieldAccess},
  *    {@link SuperMethodInvocation},
  *    {@link SuperMethodReference},
+ *    {@link SwitchExpression},
  *    {@link ThisExpression},
  *    {@link TypeLiteral},
  *    {@link TypeMethodReference},
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
index c805cea..6e430a1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchCase.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -23,8 +27,12 @@
  * <p>
  * <pre>
  * SwitchCase:
- *		<b>case</b> Expression  <b>:</b>
- *		<b>default</b> <b>:</b>
+ * 		<b>case</b> Expression  <b>:</b>
+ * 		<b>default</b> <b>:</b>
+ * 
+ * Switch case allows multiple expressions and '->' as part of Java 12 preview feature (JEP 325)
+ *		<b>case</b> [ Expression { <b>,</b> Expression } ]  <b>{ : | ->}</b>
+ *		<b>default</b> <b>{ : | ->}</b>
  * </pre>
  * </p>
  *
@@ -37,22 +45,43 @@
 	/**
 	 * The "expression" structural property of this node type (child type: {@link Expression}).
 	 * @since 3.0
+	 * @deprecated In the JLS 12 15.28.1 API, this property is replaced by {@link #EXPRESSIONS2_PROPERTY }.
 	 */
 	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
 		new ChildPropertyDescriptor(SwitchCase.class, "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
 
 	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}). (added in JEP 325).
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final ChildListPropertyDescriptor EXPRESSIONS2_PROPERTY  =
+			new ChildListPropertyDescriptor(SwitchCase.class, "expression", Expression.class, CYCLE_RISK); //$NON-NLS-1$);
+	
+	
+	/**
 	 * A list of property descriptors (element type:
 	 * {@link StructuralPropertyDescriptor}),
 	 * or null if uninitialized.
 	 */
 	private static final List PROPERTY_DESCRIPTORS;
+	
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_12;
 
 	static {
 		List propertyList = new ArrayList(2);
 		createPropertyList(SwitchCase.class, propertyList);
 		addProperty(EXPRESSION_PROPERTY, propertyList);
 		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+		
+		propertyList = new ArrayList(2);
+		createPropertyList(SwitchCase.class, propertyList);
+		addProperty(EXPRESSIONS2_PROPERTY , propertyList);
+		PROPERTY_DESCRIPTORS_12 = reapPropertyList(propertyList);
 	}
 
 	/**
@@ -66,6 +95,9 @@
 	 * @since 3.0
 	 */
 	public static List propertyDescriptors(int apiLevel) {
+		if (apiLevel >= AST.JLS12_INTERNAL) {
+			return PROPERTY_DESCRIPTORS_12;
+		}
 		return PROPERTY_DESCRIPTORS;
 	}
 
@@ -75,6 +107,17 @@
 	 * @see #expressionInitialized
 	 */
 	private Expression optionalExpression = null;
+	
+	/**
+	 * <code>true</code> indicates "->" and <code>false</code> indicates ":".
+	 */
+	private boolean switchLabeledRule = false;
+
+	
+	/**
+	 * The expression; <code>empty</code> for none; 
+	 */
+	private ASTNode.NodeList expressions = null;
 
 	/**
 	 * Indicates whether <code>optionalExpression</code> has been initialized.
@@ -89,6 +132,9 @@
 	 */
 	SwitchCase(AST ast) {
 		super(ast);
+		if (ast.apiLevel >= AST.JLS12_INTERNAL) {
+			this.expressions = new ASTNode.NodeList(EXPRESSIONS2_PROPERTY );
+		}
 	}
 
 	@Override
@@ -111,17 +157,32 @@
 	}
 
 	@Override
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == EXPRESSIONS2_PROPERTY ) {
+			return expressions();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+	
+	@Override
 	final int getNodeType0() {
 		return SWITCH_CASE;
 	}
 
+	@SuppressWarnings("unchecked")
 	@Override
 	ASTNode clone0(AST target) {
 		SwitchCase result = new SwitchCase(target);
 		result.setSourceRange(getStartPosition(), getLength());
 		result.copyLeadingComment(this);
-		result.setExpression(
-			(Expression) ASTNode.copySubtree(target, getExpression()));
+		if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			result.expressions().addAll(
+				ASTNode.copySubtrees(target, expressions()));
+		} else {
+			result.setExpression(
+					(Expression) ASTNode.copySubtree(target, getExpression()));
+		}
 		return result;
 	}
 
@@ -135,7 +196,11 @@
 	void accept0(ASTVisitor visitor) {
 		boolean visitChildren = visitor.visit(this);
 		if (visitChildren) {
-			acceptChild(visitor, getExpression());
+			if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+				acceptChildren(visitor, this.expressions);
+			} else {
+				acceptChild(visitor, getExpression());
+			}
 		}
 		visitor.endVisit(this);
 	}
@@ -145,6 +210,7 @@
 	 * <code>null</code> if there is none (the "default:" case).
 	 *
 	 * @return the expression node, or <code>null</code> if there is none
+	 * @deprecated use getExpressions() (see JLS 12)
 	 */
 	public Expression getExpression() {
 		if (!this.expressionInitialized) {
@@ -160,6 +226,21 @@
 		}
 		return this.optionalExpression;
 	}
+	
+	/**
+	 * Returns the list of expressions of this switch case, or
+	 * <code>empty</code> if there is none (the "default:" case).
+	 *
+	 * @return the expression node, or <code>expression</code> if there is none
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public List expressions() {
+		if (this.expressions == null) {
+			unsupportedBelow12();
+		}
+		return this.expressions;
+	}
 
 	/**
 	 * Sets the expression of this switch case, or clears it (turns it into
@@ -173,6 +254,7 @@
 	 * <li>the node already has a parent</li>
 	 * <li>a cycle in would be created</li>
 	 * </ul>
+	 * @deprecated see JLS 12
 	 */
 	public void setExpression(Expression expression) {
 		ASTNode oldChild = this.optionalExpression;
@@ -181,18 +263,47 @@
 		this.expressionInitialized = true;
 		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
 	}
+	
+	/**
+	 * Sets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>.
+	 * <code>true</code> indicates "->" and <code>false</code> indicates ":".
+
+	 * @param switchLabeledRule <code>true</code> or </false>
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public void setSwitchLabeledRule(boolean switchLabeledRule) {
+		unsupportedBelow12();
+		this.switchLabeledRule = switchLabeledRule;
+	}
+	
+	/**
+	 * Gets the switchLabeledRule of this switch case as <code>true</code> or <code>false</code>.
+	 *<code>true</code> indicates "->" and <code>false</code> indicates ":".
+	 *
+	 * @return switchLabeledRule <code>true</code> or </false>
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public boolean isSwitchLabeledRule() {
+		unsupportedBelow12();
+		return this.switchLabeledRule;
+	}
 
 	/**
 	 * Returns whether this switch case represents the "default:" case.
 	 * <p>
 	 * This convenience method is equivalent to
-	 * <code>getExpression() == null</code>.
+	 * <code>getExpression() == null</code> or <code>getExpressions().isEmpty()</code>.
 	 * </p>
 	 *
 	 * @return <code>true</code> if this is the default switch case, and
 	 *    <code>false</code> if this is a non-default switch case
 	 */
 	public boolean isDefault()  {
+		if (this.ast.apiLevel >= AST.JLS12_INTERNAL) {
+			return expressions().isEmpty();
+		}
 		return getExpression() == null;
 	}
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java
new file mode 100644
index 0000000..2eea888
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/SwitchExpression.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.dom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Switch expression AST node type (added in JEP 325).
+ * <p>
+ * <pre>
+ * SwitchExpression:
+ *		<b>switch</b> <b>(</b> Expression <b>)</b>
+ * 			<b>{</b> { SwitchCase | Statement } <b>}</b>
+ * SwitchCase:
+ *		<b>case</b> [ Expression { <b>,</b> Expression } ]  <b>{ : | ->}</b>
+ *		<b>default</b> <b>{ : | ->}</b>
+ * </pre>
+ * <code>SwitchCase</code> nodes are treated as a kind of
+ * <code>Statement</code>.
+ * </p>
+ *
+ * @since 3.17 BETA_JAVA_12
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class SwitchExpression extends Expression {
+
+	/**
+	 * The "expression" structural property of this node type (child type: {@link Expression}).
+	 * @since 3.16
+	 */
+	public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
+		new ChildPropertyDescriptor(SwitchExpression.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * The "statements" structural property of this node type (element type: {@link Statement}).
+	 * @since 3.16
+	 */
+	public static final ChildListPropertyDescriptor STATEMENTS_PROPERTY =
+		new ChildListPropertyDescriptor(SwitchExpression.class, "statements", Statement.class, CYCLE_RISK); //$NON-NLS-1$
+
+	/**
+	 * A list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor}),
+	 * or null if uninitialized.
+	 */
+	private static final List PROPERTY_DESCRIPTORS_12_0;
+
+	static {
+		List propertyList = new ArrayList(3);
+		createPropertyList(SwitchExpression.class, propertyList);
+		addProperty(EXPRESSION_PROPERTY, propertyList);
+		addProperty(STATEMENTS_PROPERTY, propertyList);
+		PROPERTY_DESCRIPTORS_12_0 = reapPropertyList(propertyList);
+	}
+
+	/**
+	 * Returns a list of structural property descriptors for this node type.
+	 * Clients must not modify the result.
+	 *
+	 * @param apiLevel the API level; one of the
+	 * <code>AST.JLS*</code> constants
+	 * @return a list of property descriptors (element type:
+	 * {@link StructuralPropertyDescriptor})
+	 * @since 3.16
+	 */
+	public static List propertyDescriptors(int apiLevel) {
+		return PROPERTY_DESCRIPTORS_12_0;
+	}
+
+	/**
+	 * The expression; lazily initialized; defaults to a unspecified, but legal,
+	 * expression.
+	 */
+	private Expression expression = null;
+
+	/**
+	 * The statements and SwitchCase nodes
+	 * (element type: {@link Statement}).
+	 * Defaults to an empty list.
+	 */
+	private ASTNode.NodeList statements =
+		new ASTNode.NodeList(STATEMENTS_PROPERTY);
+
+	/**
+	 * Creates a new unparented switch statement node owned by the given
+	 * AST. By default, the swicth statement has an unspecified, but legal,
+	 * expression, and an empty list of switch groups.
+	 * <p>
+	 * N.B. This constructor is package-private.
+	 * </p>
+	 *
+	 * @param ast the AST that is to own this node
+	 * @exception UnsupportedOperationException if this operation is used below JLS12
+	 */
+	SwitchExpression(AST ast) {
+		super(ast);
+		unsupportedBelow12();
+	}
+
+	@Override
+	final List internalStructuralPropertiesForType(int apiLevel) {
+		return propertyDescriptors(apiLevel);
+	}
+
+	@Override
+	final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+		if (property == EXPRESSION_PROPERTY) {
+			if (get) {
+				return getExpression();
+			} else {
+				setExpression((Expression) child);
+				return null;
+			}
+		}
+		// allow default implementation to flag the error
+		return super.internalGetSetChildProperty(property, get, child);
+	}
+
+	@Override
+	final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+		if (property == STATEMENTS_PROPERTY) {
+			return statements();
+		}
+		// allow default implementation to flag the error
+		return super.internalGetChildListProperty(property);
+	}
+
+	@Override
+	final int getNodeType0() {
+		return SWITCH_EXPRESSION;
+	}
+
+	@Override
+	ASTNode clone0(AST target) {
+		SwitchExpression result = new SwitchExpression(target);
+		result.setSourceRange(getStartPosition(), getLength());
+		result.setExpression((Expression) getExpression().clone(target));
+		result.statements().addAll(ASTNode.copySubtrees(target, statements()));
+		return result;
+	}
+
+	@Override
+	final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+		// dispatch to correct overloaded match method
+		return matcher.match(this, other);
+	}
+
+	@Override
+	void accept0(ASTVisitor visitor) {
+		boolean visitChildren = visitor.visit(this);
+		if (visitChildren) {
+			// visit children in normal left to right reading order
+			acceptChild(visitor, getExpression());
+			acceptChildren(visitor, this.statements);
+		}
+		visitor.endVisit(this);
+	}
+
+	/**
+	 * Returns the expression of this switch statement.
+	 *
+	 * @return the expression node
+	 */
+	public Expression getExpression() {
+		if (this.expression == null) {
+			// lazy init must be thread-safe for readers
+			synchronized (this) {
+				if (this.expression == null) {
+					preLazyInit();
+					this.expression = new SimpleName(this.ast);
+					postLazyInit(this.expression, EXPRESSION_PROPERTY);
+				}
+			}
+		}
+		return this.expression;
+	}
+
+	/**
+	 * Sets the expression of this switch statement.
+	 *
+	 * @param expression the new expression node
+	 * @exception IllegalArgumentException if:
+	 * <ul>
+	 * <li>the node belongs to a different AST</li>
+	 * <li>the node already has a parent</li>
+	 * <li>a cycle in would be created</li>
+	 * </ul>
+	 */
+	public void setExpression(Expression expression) {
+		if (expression == null) {
+			throw new IllegalArgumentException();
+		}
+		ASTNode oldChild = this.expression;
+		preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+		this.expression = expression;
+		postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
+	}
+
+	/**
+	 * Returns the live ordered list of statements for this switch statement.
+	 * Within this list, <code>SwitchCase</code> nodes mark the start of
+	 * the switch groups.
+	 *
+	 * @return the live list of statement nodes
+	 *    (element type: {@link Statement})
+	 */
+	public List statements() {
+		return this.statements;
+	}
+
+	@Override
+	int memSize() {
+		return BASE_NODE_SIZE + 3 * 4;
+	}
+
+	@Override
+	int treeSize() {
+		return
+			memSize()
+			+ (this.expression == null ? 0 : getExpression().treeSize())
+			+ this.statements.listSize();
+	}
+}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
index 7f2c004..001fc1f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -7,6 +7,10 @@
  * https://www.eclipse.org/legal/epl-2.0/
  *
  * SPDX-License-Identifier: EPL-2.0
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
@@ -81,6 +85,14 @@
 	 * @since 3.14
 	 */
 	private static final int JLS9 = AST.JLS9;
+	
+	/**
+	 * Internal synonym for {@link AST#JLS12}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	private static final int JLS12 = AST.JLS12;
+	
 
 	/**
 	 * The string buffer into which the serialized representation of the AST is
@@ -1487,32 +1499,76 @@
 
 	@Override
 	public boolean visit(SwitchCase node) {
-		if (node.isDefault()) {
-			this.buffer.append("default :\n");//$NON-NLS-1$
-		} else {
-			this.buffer.append("case ");//$NON-NLS-1$
-			node.getExpression().accept(this);
-			this.buffer.append(":\n");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS12) {
+			if (node.isDefault()) {
+				this.buffer.append("default");//$NON-NLS-1$
+				this.buffer.append(node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				this.buffer.append("case ");//$NON-NLS-1$
+				for (Iterator it = node.expressions().iterator(); it.hasNext(); ) {
+					Expression t = (Expression) it.next();
+						t.accept(this);
+						this.buffer.append(it.hasNext() ? ", " : //$NON-NLS-1$
+							node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
+		}
+		else {
+			if (node.isDefault()) {
+				this.buffer.append("default :\n");//$NON-NLS-1$
+			} else {
+				this.buffer.append("case ");//$NON-NLS-1$
+				getSwitchExpression(node).accept(this);
+				this.buffer.append(":\n");//$NON-NLS-1$
+			}
 		}
 		this.indent++; //decremented in visit(SwitchStatement)
 		return false;
 	}
+	/**
+	 * @deprecated
+	 */
+	private Expression getSwitchExpression(SwitchCase node) {
+		return node.getExpression();
+	}
 
-	@Override
-	public boolean visit(SwitchStatement node) {
+	private void visitSwitchNode(ASTNode node) {
 		this.buffer.append("switch (");//$NON-NLS-1$
-		node.getExpression().accept(this);
+		if (node instanceof SwitchExpression) {
+			((SwitchExpression)node).getExpression().accept(this);
+		} else if (node instanceof SwitchStatement) {
+			((SwitchStatement)node).getExpression().accept(this);
+		}
 		this.buffer.append(") ");//$NON-NLS-1$
 		this.buffer.append("{\n");//$NON-NLS-1$
 		this.indent++;
-		for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
-			Statement s = (Statement) it.next();
-			s.accept(this);
-			this.indent--; // incremented in visit(SwitchCase)
+		if (node instanceof SwitchExpression) {
+			for (Iterator it = ((SwitchExpression)node).statements().iterator(); it.hasNext(); ) {
+				Statement s = (Statement) it.next();
+				s.accept(this);
+				this.indent--; // incremented in visit(SwitchCase)
+			}
+		} else if (node instanceof SwitchStatement) {
+			for (Iterator it = ((SwitchStatement)node).statements().iterator(); it.hasNext(); ) {
+				Statement s = (Statement) it.next();
+				s.accept(this);
+				this.indent--; // incremented in visit(SwitchCase)
+			}
 		}
 		this.indent--;
 		printIndent();
 		this.buffer.append("}\n");//$NON-NLS-1$
+			
+	}
+	@Override
+	public boolean visit(SwitchExpression node) {
+		visitSwitchNode(node);
+		return false;
+	}
+	
+	@Override
+	public boolean visit(SwitchStatement node) {
+		visitSwitchNode(node);
 		return false;
 	}
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index ace31ed..ead61a2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -117,6 +117,9 @@
 
 	/** @deprecated using deprecated code */
 	private static final ChildListPropertyDescriptor INTERNAL_TRY_STATEMENT_RESOURCES_PROPERTY = TryStatement.RESOURCES_PROPERTY;
+	
+	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_SWITCH_EXPRESSION_PROPERTY = SwitchCase.EXPRESSION_PROPERTY;
 
 	/** @deprecated using deprecated code */
 	private static final int JLS2_INTERNAL = AST.JLS2;
@@ -132,6 +135,8 @@
 
 	/** @deprecated using deprecated code */
 	private static final int JLS9_INTERNAL = AST.JLS9;
+	
+	private static final int JLS12_INTERNAL = AST.JLS12;
 
 
 	TextEdit currentEdit;
@@ -1036,6 +1041,60 @@
 		}
 		return pos;
 	}
+	
+	private int rewriteExpressionOptionalQualifier(SwitchCase parent, StructuralPropertyDescriptor property, int startPos) {
+		RewriteEvent event= getEvent(parent, property);
+		if (event != null) {
+			switch (event.getChangeKind()) {
+				case RewriteEvent.INSERTED: {
+					ASTNode node= (ASTNode) event.getNewValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					doTextInsert(startPos, node, getIndent(startPos), true, editGroup);
+					doTextInsert(startPos, ".", editGroup); //$NON-NLS-1$
+					return startPos;
+				}
+				case RewriteEvent.REMOVED: {
+					try {
+						ASTNode node= (ASTNode) event.getOriginalValue();
+						TextEditGroup editGroup= getEditGroup(event);
+						int dotEnd= getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, node.getStartPosition() + node.getLength());
+						doTextRemoveAndVisit(startPos, dotEnd - startPos, node, editGroup);
+						return dotEnd;
+					} catch (CoreException e) {
+						handleException(e);
+					}
+					break;
+				}
+				case RewriteEvent.REPLACED: {
+					ASTNode node= (ASTNode) event.getOriginalValue();
+					TextEditGroup editGroup= getEditGroup(event);
+					SourceRange range= getExtendedRange(node);
+					int offset= range.getStartPosition();
+					int length= range.getLength();
+
+					doTextRemoveAndVisit(offset, length, node, editGroup);
+					doTextInsert(offset, (ASTNode) event.getNewValue(), getIndent(startPos), true, editGroup);
+					try {
+						return getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, offset + length);
+					} catch (CoreException e) {
+						handleException(e);
+					}
+					break;
+				}
+			}
+		}
+		Object node= getOriginalValue(parent, property);
+		if (node == null) {
+			return startPos;
+		}
+		int pos= doVisit((ASTNode) node);
+		try {
+			return getScanner().getTokenEndOffset(TerminalTokens.TokenNameCOLON, pos);
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return pos;
+	}
 
 	class ParagraphListRewriter extends ListRewriter {
 
@@ -1543,7 +1602,48 @@
 		}
 	}
 
+	private int rewriteExpression2(ASTNode node, ChildListPropertyDescriptor property, int pos) {
+		RewriteEvent event= getEvent(node, property);
+		if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
+			return doVisit(node, property, pos);
+		}
+		RewriteEvent[] children= event.getChildren();
+		boolean isAllInsert= isAllOfKind(children, RewriteEvent.INSERTED);
+		boolean isAllRemove= isAllOfKind(children, RewriteEvent.REMOVED);
+		String keyword= Util.EMPTY_STRING;
+		if (((SwitchCase)node).isSwitchLabeledRule()) {
+			keyword = "->"; //$NON-NLS-1$
+		} else {
+			keyword = ":"; //$NON-NLS-1$
+		}
 
+		Prefix formatterPrefix = this.formatter.CASE_SEPARATION;
+
+		int endPos= new ModifierRewriter(formatterPrefix).rewriteList(node, property, pos, keyword, " "); //$NON-NLS-1$ 
+
+		try {
+			int nextPos= getScanner().getNextStartOffset(endPos, false);
+			RewriteEvent lastChild = children[children.length - 1];
+			boolean lastUnchanged= lastChild.getChangeKind() != RewriteEvent.UNCHANGED;
+
+			if (isAllRemove) {
+				doTextRemove(endPos, nextPos - endPos, getEditGroup(lastChild));
+				return nextPos;
+			} else if (isAllInsert || (nextPos == endPos && lastUnchanged)){
+				String separator;
+				if (lastChild.getNewValue() instanceof Annotation) {
+					separator= formatterPrefix.getPrefix(getIndent(pos));
+				} else {
+					separator= String.valueOf(' '); //$NON-NLS-1$
+				}
+				doTextInsert(endPos, separator, getEditGroup(lastChild));
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+		return endPos;
+	}
+	
 	private int rewriteModifiers2(ASTNode node, ChildListPropertyDescriptor property, int pos) {
 		RewriteEvent event= getEvent(node, property);
 		if (event == null || event.getChangeKind() == RewriteEvent.UNCHANGED) {
@@ -3413,7 +3513,19 @@
 		}
 
 		// dont allow switching from case to default or back. New statements should be created.
-		rewriteRequiredNode(node, SwitchCase.EXPRESSION_PROPERTY);
+		if (node.getAST().apiLevel() >= JLS12_INTERNAL) {
+		//	rewriteExpression2(node, SwitchCase.EXPRESSIONS2_PROPERTY, node.getStartPosition()); 
+			String keyword = Util.EMPTY_STRING;
+			if (node.isSwitchLabeledRule()) {
+				keyword = "->"; //$NON-NLS-1$
+			} else {
+				keyword = ":"; //$NON-NLS-1$
+			}
+			rewriteNodeList(node, SwitchCase.EXPRESSIONS2_PROPERTY, node.getStartPosition(), keyword, ", "); //$NON-NLS-1$
+		} else {
+			rewriteExpressionOptionalQualifier(node, SwitchCase.EXPRESSION_PROPERTY, node.getStartPosition());
+		}		
+		
 		return false;
 	}
 
@@ -3512,6 +3624,37 @@
 	}
 
 	@Override
+	public boolean visit(SwitchExpression node) {
+		if (!hasChildrenChanges(node)) {
+			return doVisitUnchangedChildren(node);
+		}
+
+		int pos= rewriteRequiredNode(node, SwitchExpression.EXPRESSION_PROPERTY);
+
+		ChildListPropertyDescriptor property= SwitchExpression.STATEMENTS_PROPERTY;
+		if (getChangeKind(node, property) != RewriteEvent.UNCHANGED) {
+			try {
+				pos= getScanner().getTokenEndOffset(TerminalTokens.TokenNameLBRACE, pos);
+				int insertIndent= getIndent(node.getStartPosition());
+				if (DefaultCodeFormatterConstants.TRUE.equals(this.options.get(DefaultCodeFormatterConstants.FORMATTER_INDENT_SWITCHSTATEMENTS_COMPARE_TO_SWITCH))) {
+					insertIndent++;
+				}
+				
+				ParagraphListRewriter listRewriter= new SwitchListRewriter(insertIndent);
+				StringBuffer leadString= new StringBuffer();
+				leadString.append(getLineDelimiter());
+				leadString.append(createIndentString(insertIndent));
+				listRewriter.rewriteList(node, property, pos, leadString.toString());
+			} catch (CoreException e) {
+				handleException(e);
+			}
+		} else {
+			voidVisit(node, SwitchExpression.STATEMENTS_PROPERTY);
+		}
+		return false;
+	}
+	
+	@Override
 	public boolean visit(SwitchStatement node) {
 		if (!hasChildrenChanges(node)) {
 			return doVisitUnchangedChildren(node);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index ee92237..8a380d2 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -8,11 +8,16 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
 package org.eclipse.jdt.internal.core.dom.rewrite;
 
+import java.util.Iterator;
 import java.util.List;
 
 import org.eclipse.jdt.core.dom.*;
@@ -76,6 +81,9 @@
 	private static final ChildListPropertyDescriptor INTERNAL_TRY_STATEMENT_RESOURCES_PROPERTY = TryStatement.RESOURCES_PROPERTY;
 
 	/** @deprecated using deprecated code */
+	private static final ChildPropertyDescriptor INTERNAL_SWITCH_EXPRESSION_PROPERTY = SwitchCase.EXPRESSION_PROPERTY;
+
+	/** @deprecated using deprecated code */
 	private static final int JLS2_INTERNAL = AST.JLS2;
 
 	/** @deprecated using deprecated code */
@@ -89,6 +97,13 @@
 
 	/** @deprecated using deprecated code */
 	private static final int JLS9_INTERNAL = AST.JLS9;
+	
+	/**
+	 * Internal synonym for {@link AST#JLS12}. Use to alleviate
+	 * deprecation warnings.
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	private static final int JLS12 = AST.JLS12;
 
 
 	public static String asString(ASTNode node, RewriteEventStore store) {
@@ -959,25 +974,61 @@
 
 	@Override
 	public boolean visit(SwitchCase node) {
-		ASTNode expression= getChildNode(node, SwitchCase.EXPRESSION_PROPERTY);
-		if (expression == null) {
-			this.result.append("default"); //$NON-NLS-1$
+		if (node.getAST().apiLevel() >= JLS12) {
+			if (node.isDefault()) {
+				this.result.append("default");//$NON-NLS-1$
+				this.result.append(node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
+			} else {
+				this.result.append("case ");//$NON-NLS-1$
+				for (Iterator it = node.expressions().iterator(); it.hasNext(); ) {
+					Expression t = (Expression) it.next();
+						t.accept(this);
+						this.result.append(it.hasNext() ? ", " : //$NON-NLS-1$
+							node.isSwitchLabeledRule() ? "->" : ":");//$NON-NLS-1$ //$NON-NLS-2$
+				}
+			}
 		} else {
-			this.result.append("case "); //$NON-NLS-1$
-			expression.accept(this);
+			ASTNode expression= getChildNode(node, SwitchCase.EXPRESSION_PROPERTY);
+			if (expression == null) {
+				this.result.append("default"); //$NON-NLS-1$
+			} else {
+				this.result.append("case "); //$NON-NLS-1$
+				expression.accept(this);
+			}
+			this.result.append(':');
 		}
-		this.result.append(':');
 		return false;
 	}
 
 	@Override
-	public boolean visit(SwitchStatement node) {
+	public boolean visit(SwitchExpression node) {
+		visitSwitchNode(node);
+		return false;
+	}
+	
+	private void visitSwitchNode(ASTNode node) {
 		this.result.append("switch ("); //$NON-NLS-1$
-		getChildNode(node, SwitchStatement.EXPRESSION_PROPERTY).accept(this);
+		if (node instanceof SwitchExpression) {
+			getChildNode(node, SwitchExpression.EXPRESSION_PROPERTY).accept(this);
+		}
+		else if (node instanceof SwitchStatement) {
+			getChildNode(node, SwitchStatement.EXPRESSION_PROPERTY).accept(this);
+		}
 		this.result.append(')');
 		this.result.append('{');
-		visitList(node, SwitchStatement.STATEMENTS_PROPERTY, null);
+		if (node instanceof SwitchExpression) {
+			visitList(node, SwitchExpression.STATEMENTS_PROPERTY, null);
+		}
+		else if (node instanceof SwitchStatement) {
+			visitList(node, SwitchStatement.STATEMENTS_PROPERTY, null);
+		}
+		
 		this.result.append('}');
+	}
+	
+	@Override
+	public boolean visit(SwitchStatement node) {
+		visitSwitchNode(node);
 		return false;
 	}
 
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
index ad53806..6e936b1 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFormatter.java
@@ -1,10 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
+ * 
+ * 
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
  *
  * SPDX-License-Identifier: EPL-2.0
  *
@@ -574,6 +579,8 @@
 	public final BlockContext IF_BLOCK_NO_ELSE= new BlockFormattingPrefix("if (true)", 8); //$NON-NLS-1$
 	public final BlockContext ELSE_AFTER_STATEMENT= new BlockFormattingPrefix("if (true) foo();else ", 15); //$NON-NLS-1$
 	public final BlockContext ELSE_AFTER_BLOCK= new BlockFormattingPrefix("if (true) {}else ", 11); //$NON-NLS-1$
+	
+	public final Prefix CASE_SEPARATION= new FormattingPrefix("case A, B", "A" , CodeFormatter.K_EXPRESSION); //$NON-NLS-1$ //$NON-NLS-2$
 
 	public final BlockContext FOR_BLOCK= new BlockFormattingPrefix("for (;;) ", 7); //$NON-NLS-1$
 	public final BlockContext WHILE_BLOCK= new BlockFormattingPrefix("while (true)", 11); //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 922b1b5..e2f4edd 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -1,3 +1,4 @@
+

 /*******************************************************************************
  * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index f194800..ba40de8 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -386,11 +386,22 @@
 			handleToken(node, TokenNameCOLON, this.options.insert_space_before_colon_in_default, false);
 		} else {
 			handleToken(node, TokenNamecase, false, true);
-			handleToken(node.getExpression(), TokenNameCOLON, this.options.insert_space_before_colon_in_case, false);
+			handleToken(getSwitchExpression(node), TokenNameCOLON, this.options.insert_space_before_colon_in_case, false);
 		}
 		return true;
 	}
 
+	/**
+	 * 
+	 * @param node
+	 * @return expression
+	 * @deprecated
+	 */
+	private Expression getSwitchExpression(SwitchCase node) {
+		return node.getExpression();
+	}
+	 
+
 	@Override
 	public boolean visit(DoStatement node) {
 		handleTokenBefore(node.getExpression(), TokenNameLPAREN,
diff --git a/org.eclipse.jdt.core/grammar/java.g b/org.eclipse.jdt.core/grammar/java.g
index 41761de..bed20ac 100644
--- a/org.eclipse.jdt.core/grammar/java.g
+++ b/org.eclipse.jdt.core/grammar/java.g
@@ -113,6 +113,7 @@
 	ElidedSemicolonAndRightBrace
 	AT308
 	AT308DOTDOTDOT
+	BeginCaseExpr
 
 --    BodyMarker
 
@@ -1267,6 +1268,7 @@
 /.$putCase consumeSwitchBlockStatements() ; $break ./
 /:$readableName SwitchBlockStatements:/
 
+SwitchBlockStatement -> SwitchLabeledRule
 SwitchBlockStatement ::= SwitchLabels BlockStatements
 /.$putCase consumeSwitchBlockStatement() ; $break ./
 /:$readableName SwitchBlockStatement:/
@@ -1276,13 +1278,54 @@
 /.$putCase consumeSwitchLabels() ; $break ./
 /:$readableName SwitchLabels:/
 
-SwitchLabel ::= 'case' ConstantExpression ':'
+SwitchLabel ::= SwitchLabelCaseLhs ':'
 /. $putCase consumeCaseLabel(); $break ./
 
 SwitchLabel ::= 'default' ':'
 /. $putCase consumeDefaultLabel(); $break ./
 /:$readableName SwitchLabel:/
 
+-- BEGIN SwitchExpression (JEP 325) --
+
+UnaryExpressionNotPlusMinus -> SwitchExpression
+UnaryExpressionNotPlusMinus_NotName -> SwitchExpression
+
+SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchBlock
+/.$putCase consumeSwitchExpression() ; $break ./
+/:$readableName SwitchExpression:/
+
+SwitchLabeledRule ::= SwitchLabeledExpression
+SwitchLabeledRule ::= SwitchLabeledBlock
+SwitchLabeledRule ::= SwitchLabeledThrowStatement
+/. $putCase consumeSwitchLabeledRule(); $break ./
+/:$readableName SwitchLabeledRule:/
+
+SwitchLabeledExpression ::= SwitchLabelExpr Expression ';'
+/. $putCase consumeSwitchLabeledExpression(); $break ./
+/:$readableName SwitchLabeledExpression:/
+
+SwitchLabeledBlock ::= SwitchLabelExpr Block
+/. $putCase consumeSwitchLabeledBlock(); $break ./
+/:$readableName SwitchLabeledBlock:/
+
+SwitchLabeledThrowStatement ::= SwitchLabelExpr ThrowExpression ';'
+/. $putCase consumeSwitchLabeledThrowStatement(); $break ./
+/:$readableName SwitchLabeledThrowStatement:/
+
+SwitchLabelExpr ::= 'default'  '->'
+/. $putCase consumeDefaultLabelExpr(); $break ./
+/:$readableName SwitchLabelDefaultExpr:/
+
+SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->'
+/. $putCase consumeCaseLabelExpr(); $break ./
+/:$readableName SwitchLabelExpr:/
+
+SwitchLabelCaseLhs ::= 'case' ConstantExpressions
+/. $putCase consumeSwitchLabelCaseLhs(); $break ./
+/:$readableName SwitchLabelCaseLhs:/
+
+-- END SwitchExpression (JEP 325) --
+
 WhileStatement ::= 'while' '(' Expression ')' Statement
 /.$putCase consumeStatementWhile() ; $break ./
 /:$readableName WhileStatement:/
@@ -1330,7 +1373,7 @@
 BreakStatement ::= 'break' ';'
 /.$putCase consumeStatementBreak() ; $break ./
 
-BreakStatement ::= 'break' Identifier ';'
+BreakStatement ::= 'break' Expression ';'
 /.$putCase consumeStatementBreakWithLabel() ; $break ./
 /:$readableName BreakStatement:/
 
@@ -1349,6 +1392,10 @@
 /.$putCase consumeStatementThrow(); $break ./
 /:$readableName ThrowStatement:/
 
+ThrowExpression ::= 'throw' Expression
+/.$putCase consumeThrowExpression() ; $break ./
+/:$readableName ThrowExpression:/
+
 SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block
 /.$putCase consumeStatementSynchronized(); $break ./
 /:$readableName SynchronizedStatement:/
@@ -1990,6 +2037,11 @@
 Expressionopt -> Expression
 /:$readableName Expression:/
 
+ConstantExpressions -> Expression
+ConstantExpressions ::= ConstantExpressions ',' Expression
+/.$putCase consumeConstantExpressions(); $break ./
+/:$readableName ConstantExpressions:/
+
 ConstantExpression -> Expression
 /:$readableName ConstantExpression:/
 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
index d27dacb..33e9b72 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -2571,6 +2575,31 @@
 	public static final String CORE_MAIN_ONLY_PROJECT_HAS_TEST_ONLY_DEPENDENCY = PLUGIN_ID + ".classpath.mainOnlyProjectHasTestOnlyDependency";  //$NON-NLS-1$
 
 	/**
+	 * Compiler option ID: Enabling support for preview language features.
+	 * <p>When enabled, the compiler will activate the preview language features of this Java version.</p>
+	 *
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "enabled", "disabled" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"disabled"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final String COMPILER_PB_ENABLE_PREVIEW_FEATURES = PLUGIN_ID + ".compiler.problem.enablePreviewFeatures"; //$NON-NLS-1$
+	/**
+	 * Compiler option ID: Reporting Preview features.
+	 * <p>When enabled, the compiler will issue a warning when a preview feature is used.</p>
+	 * <dl>
+	 * <dt>Option id:</dt><dd><code>"org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures"</code></dd>
+	 * <dt>Possible values:</dt><dd><code>{ "warning", "info", "ignore" }</code></dd>
+	 * <dt>Default:</dt><dd><code>"warning"</code></dd>
+	 * </dl>
+	 * @category CompilerOptionID
+	 * @since 3.17 BETA_JAVA_12
+	 */
+	public static final String COMPILER_PB_REPORT_PREVIEW_FEATURES = PLUGIN_ID + ".compiler.problem.reportPreviewFeatures"; //$NON-NLS-1$
+	/**
 	 * Core option ID: Set the timeout value for retrieving the method's parameter names from javadoc.
 	 * <p>Timeout in milliseconds to retrieve the method's parameter names from javadoc.</p>
 	 * <p>If the value is <code>0</code>, the parameter names are not fetched and the raw names are returned.</p>
@@ -3028,12 +3057,18 @@
 	public static final String VERSION_11 = "11"; //$NON-NLS-1$
 	/**
 	 * Configurable option value: {@value}.
+	 * @since 3.17 BETA_JAVA_12
+	 * @category OptionValue
+	 */
+	public static final String VERSION_12 = "12"; //$NON-NLS-1$
+	/**
+	 * Configurable option value: {@value}.
 	 * @since 3.4
 	 * @category OptionValue
 	 */
 	public static final String VERSION_CLDC_1_1 = "cldc1.1"; //$NON-NLS-1$
 	private static List<String> allVersions = Arrays.asList(VERSION_CLDC_1_1, VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4, VERSION_1_5,
-			VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11);
+			VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12);
 
 	/**
 	 * Returns all {@link JavaCore}{@code #VERSION_*} levels in the order of their 
@@ -5986,6 +6021,8 @@
 	 * <li>{@link #COMPILER_PB_ASSERT_IDENTIFIER}</li>
 	 * <li>{@link #COMPILER_PB_ENUM_IDENTIFIER}</li>
 	 * <li>{@link #COMPILER_CODEGEN_INLINE_JSR_BYTECODE} for compliance levels 1.5 and greater</li>
+	 * <li>{@link #COMPILER_PB_ENABLE_PREVIEW_FEATURES} for compliance levels 11 and greater</li>
+	 * <li>{@link #COMPILER_PB_REPORT_PREVIEW_FEATURES} for compliance levels 11 and greater</li>
 	 * </ul>
 	 *
 	 * <p>If the given compliance is unknown, the given map is unmodified.</p>
@@ -6072,6 +6109,8 @@
 					options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
 					options.put(JavaCore.COMPILER_CODEGEN_INLINE_JSR_BYTECODE, JavaCore.ENABLED);
 					options.put(JavaCore.COMPILER_RELEASE, JavaCore.ENABLED);
+					options.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.DISABLED);
+					options.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.WARNING);
 				}
 				break;
 		}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index cdfd6f2..8de8ebe 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -6,6 +6,10 @@
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -432,7 +436,7 @@
 
 	public static class CompilationParticipants {
 
-		private final static int MAX_SOURCE_LEVEL = 11 ; // 1.1 to 1.8 and 9, 10
+		static final int MAX_SOURCE_LEVEL = JavaCore.getAllVersions().size() - 1; // All except VERSION_CLDC_1_1
 
 		/*
 		 * The registered compilation participants (a table from int (source level) to Object[])
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
index 45cd6ed..fdb13ad 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -935,11 +935,7 @@
 				}
 
 				@Override
-				public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException {
-					String name = mod.toString();
-					if (name.endsWith("/")) { //$NON-NLS-1$
-						name = name.substring(0, name.length() - 1);
-					}
+				public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException {
 					JrtPackageFragmentRoot root = new JrtPackageFragmentRoot(imagePath, name, JavaProject.this);
 					roots.add(root);
 					if (rootToResolvedEntries != null) 
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
index 93c1781..dba3e1a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JrtPackageFragmentRoot.java
@@ -78,11 +78,7 @@
 				}
 
 				@Override
-				public FileVisitResult visitModule(Path mod) throws IOException {
-					String name = mod.toString();
-					if (name.endsWith("/")) { //$NON-NLS-1$
-						name = name.substring(0, name.length() - 1);
-					}
+				public FileVisitResult visitModule(Path path, String name) throws IOException {
 					if (!JrtPackageFragmentRoot.this.moduleName.equals(name)) {
 						return FileVisitResult.SKIP_SUBTREE;
 					}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
index 64cf749..4c99d4a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java
@@ -530,7 +530,7 @@
 		}
 
 		@Override
-		public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException {
+		public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException {
 			return FileVisitResult.CONTINUE;
 		}
 	}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
index 7f7a9f4..a3aaa8f 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrt.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -97,8 +101,7 @@
 			}
 
 			@Override
-			public FileVisitResult visitModule(Path mod) throws IOException {
-				String name = mod.toString();
+			public FileVisitResult visitModule(Path path, String name) throws IOException {
 				try {
 					jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, name));
 				} catch (ClassFormatException e) {
@@ -143,9 +146,9 @@
 				}
 
 				@Override
-				public FileVisitResult visitModule(Path mod) throws IOException {
+				public FileVisitResult visitModule(Path path, String name) throws IOException {
 					try {
-						jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, mod.toString()));
+						jrt.acceptModule(JRTUtil.getClassfileContent(imageFile, IModule.MODULE_INFO_CLASS, name));
 					} catch (ClassFormatException e) {
 						e.printStackTrace();
 					}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java
index 6207656..95f3523 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJrtWithReleaseOption.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -92,11 +96,8 @@
 	private boolean isJRE12Plus(Path path) {
 		try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(path)) {
 			for (final java.nio.file.Path subdir : stream) {
-				if (Files.exists(subdir.resolve("system-modules"))) { //$NON-NLS-1$
-					String rel = subdir.getFileName().toString();
-					if (rel.endsWith("/")) { //$NON-NLS-1$
-						rel = rel.substring(0, rel.length() - 1);
-					}
+				String rel = JRTUtil.sanitizedFileName(subdir);
+				if (Files.exists(this.fs.getPath(rel, "system-modules"))) { //$NON-NLS-1$
 					int parseInt = Integer.parseInt(rel, 16);
 					return (parseInt > 11);
 				}
@@ -157,10 +158,7 @@
 			List<String> sub = new ArrayList<>();
 			try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) {
 				for (final java.nio.file.Path subdir : stream) {
-					String rel = subdir.getFileName().toString();
-					if (rel.endsWith("/")) { //$NON-NLS-1$
-						rel = rel.substring(0, rel.length() - 1);
-					}
+					String rel = JRTUtil.sanitizedFileName(subdir);
 					if (rel.contains(this.releaseInHex)) {
 						sub.add(rel);
 					} else {
@@ -207,8 +205,7 @@
 						}
 
 						@Override
-						public FileVisitResult visitModule(Path mod) throws IOException {
-							String name = mod.getName(1).toString();
+						public FileVisitResult visitModule(Path path, String name) throws IOException {
 							this.packageSet = new SimpleSet(41);
 							this.packageSet.add(""); //$NON-NLS-1$
 							if (name.endsWith("/")) { //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
index 1366b58..12371d0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -305,7 +305,7 @@
 							&& JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true)))
 								? null
 								: entry.getAccessRuleSet();
-					String release = JavaCore.DISABLED.equals(javaProject.getOption(JavaCore.COMPILER_RELEASE, true)) ? null : compliance;
+					String release = JavaCore.ENABLED.equals(javaProject.getOption(JavaCore.COMPILER_RELEASE, false)) ? compliance : null;
 					ClasspathLocation bLocation = null;
 					String libPath = path.toOSString();
 					if (Util.isJrt(libPath)) {
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
index a57cc10..db4ecde 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java
@@ -8,6 +8,10 @@
  *
  * SPDX-License-Identifier: EPL-2.0
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Stephan Herrmann - Contribution for
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
index df04833..baa8c67 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/indexing/AddJrtToIndex.java
@@ -98,7 +98,7 @@
 		@Override
 		public FileVisitResult visitFile(java.nio.file.Path path, java.nio.file.Path mod, BasicFileAttributes attrs)
 				throws IOException {
-			String name = path.getFileName().toString();
+			String name = JRTUtil.sanitizedFileName(path);
 			if (Util.isClassFileName(name) && 
 					isValidPackageNameForClassOrisModule(name)) {
 				this.indexedFileNames.put(name, FILE_INDEX_STATE.EXISTS);
@@ -106,7 +106,7 @@
 			return FileVisitResult.CONTINUE;
 		}
 		@Override
-		public FileVisitResult visitModule(java.nio.file.Path mod) throws IOException {
+		public FileVisitResult visitModule(java.nio.file.Path path, String name) throws IOException {
 			return FileVisitResult.CONTINUE;
 		}
 	}
@@ -132,7 +132,7 @@
 		@Override
 		public FileVisitResult visitFile(java.nio.file.Path path, java.nio.file.Path mod, BasicFileAttributes attrs)
 				throws IOException {
-			String name = path.getFileName().toString();
+			String name = JRTUtil.sanitizedFileName(path);
 			if (Util.isClassFileName(name) && 
 					isValidPackageNameForClassOrisModule(name)) {
 				try {
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
index 3d21fab..265e1cc 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/TypeReferenceLocator.java
@@ -1,11 +1,15 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
  * https://www.eclipse.org/legal/epl-2.0/
  *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
  * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
@@ -652,6 +656,9 @@
 			binding = ((ProblemReferenceBinding) binding).closestMatch();
 		if (binding instanceof ReferenceBinding)
 			return resolveLevelForType((ReferenceBinding) binding);
+		if (((SingleNameReference) nameRef).isLabel)
+			return IMPOSSIBLE_MATCH;
+		
 		return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH;
 	}