Update jdt.core to I20181121-1800

Change-Id: I1fd2f91f49053c04a793d2c49437d9b2e647eada
diff --git a/org.eclipse.jdt.core.tests.compiler/.classpath b/org.eclipse.jdt.core.tests.compiler/.classpath
index 01836c4..3e5654f 100644
--- a/org.eclipse.jdt.core.tests.compiler/.classpath
+++ b/org.eclipse.jdt.core.tests.compiler/.classpath
@@ -1,7 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<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 kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
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 313c8cc..a62c336 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, 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
@@ -71,7 +71,6 @@
 	public static Test buildComparableTestSuite(Class evaluationTestClass) {
 		Test suite = buildMinimalComplianceTestSuite(evaluationTestClass, F_1_5);
 		TESTS_COUNTERS.put(evaluationTestClass.getName(), Integer.valueOf(suite.countTestCases()));
-		 isJRE11Plus = isJRELevel(F_11);
 		return suite;
 	}
 
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
index f5828ae..9a7deef 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/Deprecated9Test.java
@@ -864,18 +864,52 @@
 				"	requires jdk.xml.bind;\n" +
 				"}\n"
 			};
-			runner.expectedCompilerLog =
-				"----------\n" + 
-				"1. WARNING in module-info.java (at line 2)\n" + 
-				"	requires jdk.xml.bind;\n" + 
-				"	         ^^^^^^^^^^^^\n" + 
-				"The module jdk.xml.bind has been deprecated since version 9 and marked for removal\n" + 
-				"----------\n";
-			runner.runWarningTest();
+			if (isJRE11Plus) {
+				runner.expectedCompilerLog =
+					"----------\n" + 
+					"1. ERROR in module-info.java (at line 2)\n" + 
+					"	requires jdk.xml.bind;\n" + 
+					"	         ^^^^^^^^^^^^\n" + 
+					"jdk.xml.bind cannot be resolved to a module\n" + 
+					"----------\n";
+				runner.runNegativeTest();
+			} else {
+				runner.expectedCompilerLog =
+					"----------\n" + 
+					"1. WARNING in module-info.java (at line 2)\n" + 
+					"	requires jdk.xml.bind;\n" + 
+					"	         ^^^^^^^^^^^^\n" + 
+					"The module jdk.xml.bind has been deprecated since version 9 and marked for removal\n" + 
+					"----------\n";
+				runner.runWarningTest();
+			}
 		} finally {
 			this.javaClassLib = save;
 		}
 	}
+	public void testBug533063_2() throws Exception {
+		runConformTest(new String[] {
+			"dont.use/module-info.java",
+			"@Deprecated(forRemoval=true,since=\"9\") module dont.use {}\n"
+		});
+		this.moduleMap.clear(); // don't use the source module beyond this point
+		Runner runner = new Runner();
+		runner.shouldFlushOutputDirectory = false;
+		runner.testFiles = new String[] {
+			"my.mod/module-info.java",
+			"module my.mod {\n" +
+			"	requires dont.use;\n" +
+			"}\n"
+		};
+		runner.expectedCompilerLog =
+			"----------\n" + 
+			"1. WARNING in my.mod\\module-info.java (at line 2)\n" + 
+			"	requires dont.use;\n" + 
+			"	         ^^^^^^^^\n" + 
+			"The module dont.use has been deprecated since version 9 and marked for removal\n" + 
+			"----------\n";
+		runner.runWarningTest();
+	}
 	public void testBug534304() throws Exception {
 		runNegativeTest(
 			new String[] {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
index da0ddf9..d23366f 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/LambdaExpressionsTest.java
@@ -1027,11 +1027,9 @@
 }
 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=406641, [1.8][compiler][codegen] Code generation for intersection cast.
 public void test039() {
-// FIXME: was differentiating error messages ever implemented?
-//	String errMsg = (this.complianceLevel >= ClassFileConstants.JDK9) ?
-//			"X (in module: Unnamed Module) cannot be cast to I (in module: Unnamed Module)" :
-//				"X cannot be cast to I";
-	String errMsg = "X cannot be cast to I";
+	String errMsg = isJRE11Plus
+		? "class X cannot be cast to class I (X and I are in unnamed module of loader"
+		: "X cannot be cast to I";
 	this.runConformTest(
 			new String[] {
 					"X.java",
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
index d45a695..35554d8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java
@@ -14434,6 +14434,9 @@
 			"----------\n");
 }
 public void testBug536978_comment5() {
+	String errMsg = isJRE11Plus 
+			? "class Result1 cannot be cast to class OtherResult (Result1 and OtherResult are in unnamed module of loader"
+			: "Result1 cannot be cast to OtherResult";
 	runConformTest(
 		new String[] {
 			"SimpleDemo.java",
@@ -14475,6 +14478,6 @@
 			"	}\n" + 
 			"}\n"
 		},
-		"Result1 cannot be cast to OtherResult");
+		errMsg);
 }
 }
diff --git a/org.eclipse.jdt.core.tests.model/.classpath b/org.eclipse.jdt.core.tests.model/.classpath
index 0035118..7c258d5 100644
--- a/org.eclipse.jdt.core.tests.model/.classpath
+++ b/org.eclipse.jdt.core.tests.model/.classpath
@@ -1,6 +1,10 @@
 <classpath>
-	<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 kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
index 4590978..6523f0e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterBugsTests.java
@@ -5723,7 +5723,7 @@
  */
 public void testBug298844a() {
 	setFormatLineCommentOnFirstColumn();
-	this.formatterPrefs.insert_new_line_in_empty_method_body = false;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 	String source = 
 		"public class X01 {\n" + 
 		"public X01() {\n" + 
@@ -5739,7 +5739,7 @@
 	);
 }
 public void testBug298844b() {
-	this.formatterPrefs.insert_new_line_in_empty_method_body = false;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 	String source = 
 		"public class X02 {\n" + 
 		"public void foo() {\n" + 
@@ -11767,7 +11767,7 @@
  * https://bugs.eclipse.org/475793 - [formatter] Incorrect whitespace after lambda block
  */
 public void testBug475793() {
-	this.formatterPrefs.insert_new_line_in_empty_block = false;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 	String source =
 		"public class C {\r\n" + 
 		"	public void f() {\r\n" + 
@@ -11786,7 +11786,7 @@
  * https://bugs.eclipse.org/475746 - [formatter] insert-space rules sometimes ignored with anonymous subclass or when Annotations present
  */
 public void testBug475746() {
-	this.formatterPrefs.insert_new_line_in_empty_block = false;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 	this.formatterPrefs.insert_space_after_opening_paren_in_method_invocation = true;
 	this.formatterPrefs.insert_space_before_closing_paren_in_method_invocation = true;
 	this.formatterPrefs.insert_space_after_opening_paren_in_method_declaration = true;
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
index bd7bb18..f027f9b 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/formatter/FormatterRegressionTests.java
@@ -645,7 +645,7 @@
 	public void test041() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = false;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test041", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -653,7 +653,7 @@
 	public void test042() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
-		preferences.insert_new_line_in_empty_type_declaration = false;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		preferences.insert_space_before_opening_brace_in_block = true;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test042", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
@@ -662,7 +662,7 @@
 	public void test043() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = false;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test043", "A.java");//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -1940,10 +1940,10 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test173", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -1954,10 +1954,10 @@
 	public void test174() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test174", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -1969,10 +1969,9 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = true;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test175", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -1983,10 +1982,9 @@
 	public void test176() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = true;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test176", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -1997,10 +1995,9 @@
 	public void test177() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test177", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -2011,10 +2008,9 @@
 	public void test178() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test178", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -2025,10 +2021,9 @@
 	public void test179() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = true;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test179", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -2039,10 +2034,9 @@
 	public void test180() {
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test180", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4293,10 +4287,9 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test319", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4305,10 +4298,9 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test320", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4317,10 +4309,9 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test321", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4329,10 +4320,9 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = true;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test322", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4341,10 +4331,10 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getEclipse21Settings());
 		preferences.number_of_empty_lines_to_preserve = 0;
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_anonymous_type_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = false;
-		preferences.insert_new_line_in_empty_method_body = false;
-		preferences.insert_new_line_in_empty_block = false;
+		preferences.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test323", "A.java", CodeFormatter.K_CLASS_BODY_DECLARATIONS);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4614,7 +4604,7 @@
 		preferences.tab_char = DefaultCodeFormatterOptions.SPACE;
 		preferences.blank_lines_before_method = 1;
 		preferences.blank_lines_before_first_class_body_declaration = 1;
-		preferences.insert_new_line_in_empty_method_body = false;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test347", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -4631,7 +4621,7 @@
 		preferences.tab_char = DefaultCodeFormatterOptions.SPACE;
 		preferences.blank_lines_before_method = 1;
 		preferences.blank_lines_before_first_class_body_declaration = 1;
-		preferences.insert_new_line_in_empty_method_body = false;
+		preferences.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		DefaultCodeFormatter codeFormatter = new DefaultCodeFormatter(preferences);
 		runTest(codeFormatter, "test348", "A.java", CodeFormatter.K_COMPILATION_UNIT);//$NON-NLS-1$ //$NON-NLS-2$
 	}
@@ -7273,9 +7263,9 @@
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_enum_constant = false;
-		preferences.insert_new_line_in_empty_enum_declaration = false;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
         preferences.tab_size = 4;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
@@ -7303,9 +7293,9 @@
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_enum_constant = false;
-		preferences.insert_new_line_in_empty_enum_declaration = true;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
         preferences.tab_size = 4;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
@@ -7333,9 +7323,9 @@
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_enum_constant = true;
-		preferences.insert_new_line_in_empty_enum_declaration = false;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
         preferences.tab_size = 4;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
@@ -7363,9 +7353,9 @@
 		Map options = DefaultCodeFormatterConstants.getJavaConventionsSettings();
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.tab_char = DefaultCodeFormatterOptions.TAB;
-		preferences.insert_new_line_in_empty_type_declaration = true;
-		preferences.insert_new_line_in_empty_enum_constant = true;
-		preferences.insert_new_line_in_empty_enum_declaration = true;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
         preferences.tab_size = 4;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
@@ -8970,8 +8960,8 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.indent_body_declarations_compare_to_annotation_declaration_header = false;
 		preferences.indent_body_declarations_compare_to_type_header = true;
-		preferences.insert_new_line_in_empty_annotation_declaration = false;
-		preferences.insert_new_line_in_empty_type_declaration = true;
+		preferences.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
 			Hashtable newJavaCoreOptions = JavaCore.getOptions();
@@ -8996,8 +8986,8 @@
 		DefaultCodeFormatterOptions preferences = new DefaultCodeFormatterOptions(options);
 		preferences.indent_body_declarations_compare_to_annotation_declaration_header = true;
 		preferences.indent_body_declarations_compare_to_type_header = false;
-		preferences.insert_new_line_in_empty_annotation_declaration = true;
-		preferences.insert_new_line_in_empty_type_declaration = false;
+		preferences.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		preferences.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
 		Hashtable javaCoreOptions = JavaCore.getOptions();
 		try {
 			Hashtable newJavaCoreOptions = JavaCore.getOptions();
@@ -14372,4 +14362,199 @@
 	String input = getCompilationUnit("Formatter", "", "test131292", "in.java").getSource();
 	formatSource(input, getCompilationUnit("Formatter", "", "test131292", "F_out.java").getSource());
 }
+
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973a() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "A_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973b() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = true;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "B_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973c() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = true;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "C_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973d() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "D_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973e() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = true;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = true;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "E_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973f() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "F_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973g() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "G_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973h() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_PRESERVE;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	this.formatterPrefs.align_type_members_on_columns = true;
+	this.formatterPrefs.align_variable_declarations_on_columns = true;
+	this.formatterPrefs.align_assignment_statements_on_columns = true;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "H_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973i() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.page_width = 50;
+	this.formatterPrefs.use_tabs_only_for_leading_indentations = true;
+	this.formatterPrefs.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY;
+	this.formatterPrefs.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	this.formatterPrefs.keep_simple_getter_setter_on_one_line = false;
+	this.formatterPrefs.keep_guardian_clause_on_one_line = false;
+	String input = getCompilationUnit("Formatter", "", "test205973", "in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "I_out.java").getSource());
+}
+/**
+ * https://bugs.eclipse.org/205973 - [formatter] Allow to keep simple methods on one line (for exemple simple getter or setter)
+ */
+public void testBug205973j() throws JavaModelException {
+	setComplianceLevel(CompilerOptions.VERSION_1_8);
+	this.formatterPrefs.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+	String input = getCompilationUnit("Formatter", "", "test205973", "J_in.java").getSource();
+	formatSource(input, getCompilationUnit("Formatter", "", "test205973", "J_out.java").getSource());
+}
 }
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 a0b495c..7aee8c4 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
@@ -3491,6 +3491,16 @@
 				IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
 				null);
 		} catch (CoreException e) {
+			logError("exception occurred while waiting on indexing", e);
+		}
+	}
+
+	private static void logError(String errorMessage, CoreException e) {
+		Plugin plugin = JavaCore.getPlugin();
+		if (plugin != null) {
+			ILog log = plugin.getLog();
+			Status status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, errorMessage, e);
+			log.log(status);
 		}
 	}
 }
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 1be91df..a7d9e60 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
@@ -25,6 +25,7 @@
 import org.eclipse.core.filesystem.URIUtil;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.resources.IResource;
@@ -37,6 +38,7 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaProject;
@@ -1902,12 +1904,18 @@
 		return;
 	}
 	try {
-		createJava9Project("Test", new String[]{"src"});
+		IJavaProject prj = createJava9Project("Test", new String[]{"src"});
 		String moduleSrc =
 			"module test {\n" +
 			"	requires oracle.net;\n" +
 			"}\n";
 		createFile("/Test/src/module-info.java", moduleSrc);
+		prj.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+		IMarker[] markers = prj.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+		if (markers.length == 1 && markers[0].toString().contains("oracle.net cannot be resolved to a module")) {
+			System.out.println("Skipping "+getClass().getName()+".testModule2() because module oracle.net is unavailable");
+			return; // oracle.net is missing from openjdk builds
+		}
 		ICompilationUnit unit = getCompilationUnit("/Test/src/module-info.java");
 		int start = moduleSrc.indexOf("oracle.net");
 		int length = "oracle.net".length();
@@ -1926,4 +1934,55 @@
 		deleteProject("Test");
 	}
 }
+public void testModule2b() throws CoreException, IOException {
+	if (!isJRE9) {
+		System.err.println(this.getClass().getName()+'.'+getName()+" needs a Java 9 JRE - skipped");
+		return;
+	}
+	try {
+		// create project with incomplete source attachment:
+		String javaHome = System.getProperty("java.home") + File.separator;
+		Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar");
+		createSourceZip(
+				new String[] {
+					"java.base/module-info.java",
+					"module java.base {}\n",
+					"java.se.ee/module-info.java",
+					"module java.se.ee {}\n"
+				},
+				getWorkspacePath()+"/Test/src.zip");
+		Path sourceAttachment = new Path("/Test/src.zip");
+		IClasspathEntry jrtEntry;
+		jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, null, false);
+		IJavaProject project = this.createJavaProject("Test", new String[] {"src"}, new String[0],
+				new String[0], "bin", "9");
+		IClasspathEntry[] old = project.getRawClasspath();
+		IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
+		System.arraycopy(old, 0, newPath, 0, old.length);
+		newPath[old.length] = jrtEntry;
+		project.setRawClasspath(newPath, null);
+		//
+		String moduleSrc =
+			"module test {\n" +
+			"	requires java.desktop;\n" +
+			"}\n";
+		createFile("/Test/src/module-info.java", moduleSrc);
+		ICompilationUnit unit = getCompilationUnit("/Test/src/module-info.java");
+		int start = moduleSrc.indexOf("java.desktop");
+		int length = "java.desktop".length();
+		IJavaElement[] elements = unit.codeSelect(start, length);
+		assertEquals("expected #elements", 1, elements.length);
+
+		IModuleDescription javaDesktop = (IModuleDescription) elements[0];
+		IModularClassFile cf = (IModularClassFile) javaDesktop.getClassFile();
+		assertSourceEquals(
+			"Unexpected source for class file java.desktop/module-info.class",
+			null,
+			cf.getSource());
+		ISourceRange javadocRange = javaDesktop.getJavadocRange();
+		assertEquals("javadoc from source", null, javadocRange);
+	} finally {
+		deleteProject("Test");
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java
new file mode 100644
index 0000000..010f0de
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Bug376673Test.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IJavaProject;
+
+import junit.framework.Test;
+
+public class Bug376673Test extends ModifyingResourceTests {
+
+	public Bug376673Test(String name) {
+		super(name);
+		this.endChar = "";
+	}
+
+	public static Test suite() {
+		return buildModelTestSuite(Bug376673Test.class);
+	}
+
+	/**
+     * An extra test for bug 413114 in the context of bug 376673.
+     * We want to know whether we can compile with when using a class from a jar as created in
+     * {@link org.eclipse.jdt.core.tests.model.JavaSearchBugsTests2#testBug376673e()}.
+	 */
+	public void testBug376673() throws Exception {
+		try {
+			if ("macosx".equals(System.getProperty("osgi.os"))) {
+				return;
+			}
+			IJavaProject p = createJavaProject("P", new String[] { "src" }, new String[] { "/P/lib376673.jar", "JCL17_LIB" }, "bin", "1.7");
+
+			org.eclipse.jdt.core.tests.util.Util.createJar(
+					new String[] { "p\uD842\uDF9F/i\uD842\uDF9F/Test.java",
+							"package p\uD842\uDF9F.i\uD842\uDF9F;\n" + "public class Test{}\n" },
+					p.getProject().getLocation().append("lib376673.jar").toOSString(), "1.7");
+
+			createFolder("/P/src/pkg");
+			String[] classFileContent = new String[] {
+					"package pkg;",
+					"class UseJarClass {",
+					"	public p\uD842\uDF9F.i\uD842\uDF9F.Test test;",
+					"}",
+			};
+			IFile file = createFile("/P/src/pkg/UseJarClass.java", String.join(System.lineSeparator(), classFileContent), "UTF-8");
+			file.setCharset("UTF-8", null);
+			refresh(p);
+			waitForAutoBuild();
+			waitUntilIndexesReady();
+			IMarker[] markers = p.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+			List<String> errors = new ArrayList<>();
+			StringBuilder markersToString = new StringBuilder();
+			for (IMarker marker : markers) {
+				
+				Integer severity = (Integer) marker.getAttribute(IMarker.SEVERITY);
+				String message = (String) marker.getAttribute(IMarker.MESSAGE);
+				if (severity.intValue() == IMarker.SEVERITY_ERROR) {
+					errors.add(message);
+				}
+				
+				markersToString.append("Marker with severity: ");
+				markersToString.append(severity);
+				markersToString.append(", and message: ");
+				markersToString.append(message);
+				markersToString.append(", at location: ");
+				markersToString.append(marker.getAttribute(IMarker.LOCATION));
+				markersToString.append(", at line: ");
+				markersToString.append(marker.getAttribute(IMarker.LINE_NUMBER));
+			}
+			assertEquals("expected no markers on test project, all markers are:" + System.lineSeparator() + markersToString,
+					Collections.emptyList(), errors);
+		} finally {
+			deleteProject("P");
+		}
+	}
+}
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 8240228..e5d2894 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
@@ -120,6 +120,10 @@
 	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);
+	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/JavaSearchBugsTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
index d08d5a1..a4fe9ca 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests2.java
Binary files differ
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 0e8f645..3c7e20f 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
@@ -41,6 +41,7 @@
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.IProblemRequestor;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.WorkingCopyOwner;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.CompilationUnit;
@@ -94,6 +95,16 @@
 		deleteProject("P1");
 	}
 	
+	IClasspathAttribute[] moduleAttribute() {
+		return new IClasspathAttribute[] { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") };
+	}
+	void addModularProjectEntry(IJavaProject project, IJavaProject depProject) throws JavaModelException {
+		addClasspathEntry(project, JavaCore.newProjectEntry(depProject.getPath(), null, false, moduleAttribute(), false));
+	}
+	void addModularLibraryEntry(IJavaProject project, String libraryPath) throws JavaModelException {
+		addLibraryEntry(project, new Path(libraryPath), null, null, null, null, moduleAttribute(), false);	
+	}
+
 	// Test that the java.base found as a module package fragment root in the project 
 	public void test001() throws CoreException {
 		if (!isJRE9) return;
@@ -1837,8 +1848,8 @@
 			deleteProject("com.greetings");
 		}
 	}
-	// Changes to implicit dependencies should be reflected
-	public void test_ModuleSourcePath_implicitdeps2() throws CoreException {
+	// Changes to implicit dependencies should be reflected // FIXME: container JavaCore.MODULE_PATH_CONTAINER_ID is unreliable
+	public void _test_ModuleSourcePath_implicitdeps2() throws CoreException {
 		if (!isJRE9) return;
 		try {
 			String[] sources = new String[] {
@@ -6279,21 +6290,28 @@
 		if (!isJRE9) return;
 		ClasspathJrt.resetCaches();
 		try {
-			IJavaProject javaProject = createJava9Project("mod1", new String[] {"src"});
+			// jdk.rmic is not be visible to code in an unnamed module, but using requires we can see the module.
+			// only, there's nothing exported from it (which is why JEP 261 hides it from unnamed), so we --add-reads:
+			IClasspathAttribute[] attrs = new IClasspathAttribute[] {
+				JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
+			};
+			IJavaProject javaProject = createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);
 
 			String srcMod =
-				"@SuppressWarnings(\"removal\")\n" + // javax.xml.ws.annotation is deprecated for removal
 				"module mod1 {\n" + 
 				"	exports com.mod1.pack1;\n" + 
-				"	requires java.xml.ws.annotation;\n" + 
+				"	requires jdk.rmic;\n" + 
 				"}";
 			createFile("/mod1/src/module-info.java", 
 				srcMod);
 			createFolder("/mod1/src/com/mod1/pack1");
 			String srcX =
 				"package com.mod1.pack1;\n" +
-				"@javax.annotation.Generated(\"com.acme.generator.CodeGen\")\n" +
+				"import sun.rmi.rmic.Main;\n" +
 				"public class Dummy {\n" +
+				"	String test() {\n" +
+				"		return Main.getString(\"in\");\n" +
+				"	}\n" +
 				"}";
 			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX);
 
@@ -6318,6 +6336,92 @@
 		}
 	}
 
+	public void testBug526054b() throws Exception {
+		if (!isJRE9) return;
+		ClasspathJrt.resetCaches();
+		try {
+			// one project can see jdk.rmic/sun.rmi.rmic
+			IClasspathAttribute[] attrs = new IClasspathAttribute[] {
+				JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, "jdk.rmic/sun.rmi.rmic=mod1")
+			};
+			createJava9ProjectWithJREAttributes("mod1", new String[] {"src"}, attrs);
+
+			String srcMod1 =
+				"module mod1 {\n" + 
+				"	exports com.mod1.pack1;\n" + 
+				"	requires jdk.rmic;\n" + 
+				"}";
+			createFile("/mod1/src/module-info.java", 
+				srcMod1);
+			createFolder("/mod1/src/com/mod1/pack1");
+			String srcX1 =
+				"package com.mod1.pack1;\n" +
+				"import sun.rmi.rmic.Constants;\n" + // this should never be complained against due to above add-exports.
+				"public class Dummy implements Constants {\n" +
+				"}";
+			createFile("/mod1/src/com/mod1/pack1/Dummy.java", srcX1);
+			
+			// second project cannot see jdk.rmic/sun.rmi.rmic:
+			createJava9Project("mod2", new String[] {"src"});
+
+			String srcMod2 =
+				"module mod2 {\n" + 
+				"	exports com.mod2.pack1;\n" + 
+				"	requires jdk.rmic;\n" + 
+				"}";
+			createFile("/mod2/src/module-info.java", 
+				srcMod2);
+			createFolder("/mod2/src/com/mod2/pack1");
+			String srcX2 =
+				"package com.mod2.pack1;\n" +
+				"import sun.rmi.rmic.Main;\n" +
+				"public class Dummy {\n" +
+				"	String test() {\n" +
+				"		return Main.getString(\"in\");\n" +
+				"	}\n" +
+				"}";
+			createFile("/mod2/src/com/mod2/pack1/Dummy.java", srcX2);
+
+			// check first:
+			this.problemRequestor.initialize(srcX1.toCharArray());
+			getWorkingCopy("/mod1/src/com/mod1/pack1/Dummy.java", srcX1, true);
+			assertProblems("Dummy in mod1 should have no problems",
+					"----------\n" + 
+					"----------\n",
+					this.problemRequestor);
+
+			// check second:
+			this.problemRequestor.initialize(srcX2.toCharArray());
+			getWorkingCopy("/mod2/src/com/mod2/pack1/Dummy.java", srcX2, true);
+			assertProblems("Dummy in mod2 should have problems",
+					"----------\n" + 
+					"1. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 2)\n" + 
+					"	import sun.rmi.rmic.Main;\n" + 
+					"	       ^^^^^^^^^^^^^^^^^\n" + 
+					"The type sun.rmi.rmic.Main is not accessible\n" + 
+					"----------\n" + 
+					"2. ERROR in /mod2/src/com/mod2/pack1/Dummy.java (at line 5)\n" + 
+					"	return Main.getString(\"in\");\n" + 
+					"	       ^^^^\n" + 
+					"Main cannot be resolved\n" + 
+					"----------\n",
+					this.problemRequestor);
+
+			// check both in a combined build
+			getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null);
+			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			IMarker[] markers = getWorkspace().getRoot().findMarkers(null, true, IResource.DEPTH_INFINITE);
+			sortMarkers(markers);
+			assertMarkers("Unexpected markers",
+					"The type sun.rmi.rmic.Main is not accessible\n" + 
+					"Main cannot be resolved",
+					markers);
+		} finally {
+			deleteProject("mod1");
+			deleteProject("mod2");
+		}
+	}
+
 	public void testBug525918() throws CoreException {
 		if (!isJRE9) return;
 		try {
@@ -7018,6 +7122,194 @@
 			JavaCore.setOptions(options);
 		}
 	}
+	// missing linked jar must not cause NPE
+	public void testBug540904() throws CoreException, IOException {
+		if (!isJRE9) return;
+		try {
+			String[] src = new String[] { 
+					"src/test/Test.java",
+					"package test;\n" +
+					"public class Test {\n" +
+					"}"
+			};
+			IJavaProject p2 = setupModuleProject("Bug540904", src, new IClasspathEntry[] {  });
+			IFile file = getFile("/Bug540904/link.jar");
+			file.createLink(new Path("MISSING/missing.jar"), IResource.ALLOW_MISSING_LOCAL, null);
+			addLibraryEntry(p2, file.getFullPath(), false);
+			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			IMarker[] markers = p2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+			assertMarkers("Unexpected markers", "", markers);
+		} finally {
+			this.deleteProject("Bug540904");
+		}
+	}
+	public void testBug540788() throws Exception {
+		if (!isJRE9) return;
+		try {
+			// project common:
+			IJavaProject common = createJava9Project("Bug540788.common", new String[] { "src/main/java" });
+			createSourceFiles(common,
+					new String[] {
+						"src/main/java/module-info.java",
+						"module org.sheepy.common {\n" + 
+						"	requires transitive org.eclipse.emf.common;\n" + 
+						"	requires transitive org.eclipse.emf.ecore;\n" + 
+						"}\n"
+					});
+			IFolder libs = createFolder("/Bug540788.common/libs");
+			String emfCommonPath = libs.getLocation()+"/org.eclipse.emf.common.jar";
+			Util.createJar(
+					new String[] {
+							"src/org/eclipse/emf/common/Foo.java",
+							"package org.eclipse.emf.common;\n" +
+							"public interface Foo {\n" +
+							"}",
+					},
+					null,
+					new HashMap<>(),
+					null,
+					emfCommonPath);
+			addModularLibraryEntry(common, emfCommonPath);
+			String ecorePath = libs.getLocation()+"/org.eclipse.emf.ecore.jar";
+			Util.createJar(
+					new String[] {
+						"src/org/eclipse/emf/ecore/EObject.java",
+						"package org.eclipse.emf.ecore;\n" +
+						"public interface EObject {\n" +
+						"}",
+					},
+					null,
+					new HashMap<>(),
+					null,
+					ecorePath);
+			addModularLibraryEntry(common, ecorePath);
+			// project vulkan:
+			IJavaProject vulkan = createJava9Project("Bug540788.vulkan", new String[] { "src/main/java" });
+			createSourceFiles(vulkan,
+					new String[] {
+						"src/main/java/module-info.java",
+						"module org.sheepy.vulkan {\n" + 
+						"	requires transitive org.sheepy.common;\n" + 
+						"	exports org.sheepy.vulkan.model.resource;\n" + 
+						"}\n",
+						"src/main/java/org/sheepy/vulkan/model/resource/Resource.java",
+						"package org.sheepy.vulkan.model.resource;\n" + 
+						"import org.eclipse.emf.ecore.EObject;\n" + 
+						"public interface Resource extends EObject {\n" + 
+						"}\n",
+						"src/main/java/org/sheepy/vulkan/model/resource/VulkanBuffer.java",
+						"package org.sheepy.vulkan.model.resource;\n" + 
+						"public interface VulkanBuffer extends Resource {\n" + 
+						"}\n",
+					});
+			addModularProjectEntry(vulkan, common);
+			addModularLibraryEntry(vulkan, emfCommonPath);
+			addModularLibraryEntry(vulkan, ecorePath);
+			// project vulkan.demo
+			IJavaProject vulkan_demo = createJava9Project("Bug540788.vulkan.demo", new String[] { "src/main/java" });
+			createSourceFiles(vulkan_demo,
+					new String[] {
+						"src/main/java/module-info.java",
+						"module org.sheepy.vulkan.demo {\n" + 
+						"	exports org.sheepy.vulkan.demo.model;\n" + 
+						"	requires org.sheepy.vulkan;\n" + 
+						"}\n",
+						"src/main/java/org/sheepy/vulkan/demo/model/UniformBuffer.java",
+						"package org.sheepy.vulkan.demo.model;\n" + 
+						"import org.sheepy.vulkan.model.resource.VulkanBuffer;\n" + 
+						"public interface UniformBuffer extends VulkanBuffer {\n" + 
+						"}\n",
+					});
+			addModularProjectEntry(vulkan_demo, vulkan);
+			addModularProjectEntry(vulkan_demo, common);
+			addModularLibraryEntry(vulkan_demo, emfCommonPath);
+			addModularLibraryEntry(vulkan_demo, ecorePath);
+			
+			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			IMarker[] markers = vulkan_demo.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+			assertMarkers("Unexpected markers", "", markers);
+		} finally {
+			deleteProject("Bug540788.common");
+			deleteProject("Bug540788.vulkan");
+			deleteProject("Bug540788.vulkan.demo");
+		}
+	}
+	public void testBug541015() throws Exception {
+		try {
+			IJavaProject m1 = createJava9Project("m1", new String[] { "src" });
+			createSourceFiles(m1,
+					new String[] {
+						"src/module-info.java",
+						"module m1 { exports org.p1; }\n",
+						"src/org/p1/T1.java",
+						"package org.p1;\n" +
+						"public class T1 {}\n"
+					});
+			IJavaProject m2 = createJava9Project("m2", new String[] { "src" });
+			createSourceFiles(m2,
+					new String[] {
+						"src/module-info.java",
+						"module m2 { exports org.p1; }\n",
+						"src/org/p1/T1.java",
+						"package org.p1;\n" +
+						"public class T1 {}\n"
+					});
+			IJavaProject m3 = createJava9Project("m3", new String[] { "src" });
+			createSourceFiles(m3,
+					new String[] {
+						"src/module-info.java",
+						"module m3 { exports org.p1; }\n",
+						"src/org/p1/T1.java",
+						"package org.p1;\n" +
+						"public class T1 {}\n"
+					});
+			IJavaProject unnamed = createJava9Project("unnamed", new String[] { "src" });
+			String testSource = "package test;\n" +
+			"import org.p1.T1;\n" +
+			"public class Test {\n" +
+			"	T1 t1;\n" +
+			"}\n";
+			createSourceFiles(unnamed,
+					new String[] {
+						"src/test/Test.java",
+						testSource
+					});
+			addModularProjectEntry(unnamed, m1);
+			addModularProjectEntry(unnamed, m2);
+			addModularProjectEntry(unnamed, m3);
+			
+			getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null);
+			IMarker[] markers = unnamed.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+			sortMarkers(markers);
+			assertMarkers("Unexpected markers",
+					"The import org.p1.T1 cannot be resolved\n" + 
+					"T1 cannot be resolved to a type",
+					markers);
+			
+			char[] sourceChars = testSource.toCharArray();
+			this.problemRequestor.initialize(sourceChars);
+			getCompilationUnit("/unnamed/src/test/Test.java").getWorkingCopy(this.wcOwner, null);
+			assertProblems(
+					"Unexpected problems",
+					"----------\n" + 
+					"1. ERROR in /unnamed/src/test/Test.java (at line 2)\n" + 
+					"	import org.p1.T1;\n" + 
+					"	       ^^^^^^^^^\n" + 
+					"The import org.p1.T1 cannot be resolved\n" + 
+					"----------\n" + 
+					"2. ERROR in /unnamed/src/test/Test.java (at line 4)\n" + 
+					"	T1 t1;\n" + 
+					"	^^\n" + 
+					"T1 cannot be resolved to a type\n" + 
+					"----------\n",
+					this.problemRequestor);
+		} finally {
+			deleteProject("m1");
+			deleteProject("m2");
+			deleteProject("m3");
+			deleteProject("unnamed");
+		}
+	}
 	protected void assertNoErrors() throws CoreException {
 		for (IProject p : getWorkspace().getRoot().getProjects()) {
 			int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
index 4560776..55168e7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
@@ -5939,5 +5939,59 @@
 			deleteProject(project18);
 	}
 }
+public void testBug534865() throws CoreException, IOException {
+	IJavaProject project18 = null;
+	try {
+		project18 = createJavaProject("Reconciler18", new String[] {"src"}, new String[] {"JCL18_LIB"}, "bin");
+		setUpProjectCompliance(project18, "1.8");
+		project18.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED);
+		createFolder("/Reconciler18/src/org/eclipse/jdt/annotation");
+		createFile(
+			"/Reconciler18/src/org/eclipse/jdt/annotation/Nullable.java",
+			"package org.eclipse.jdt.annotation;\n" +
+					"import static java.lang.annotation.ElementType.TYPE_USE;\n" + 
+					"\n" + 
+					"import java.lang.annotation.Documented;\n" + 
+					"import java.lang.annotation.Retention;\n" + 
+					"import java.lang.annotation.RetentionPolicy;\n" + 
+					"import java.lang.annotation.Target;\n" +
+					"@Documented\n" + 
+					"@Retention(RetentionPolicy.CLASS)\n" + 
+					"@Target({ TYPE_USE })\n" + 
+					"public @interface Nullable {\n" + 
+					"	// marker annotation with no members\n" + 
+					"}\n"
+		);
+		String source = 
+				"package org.eclipse.jdt.annotation;\n" +
+				"import static java.lang.annotation.ElementType.TYPE_USE;\n" + 
+				"\n" + 
+				"import java.lang.annotation.Documented;\n" + 
+				"import java.lang.annotation.Retention;\n" + 
+				"import java.lang.annotation.RetentionPolicy;\n" + 
+				"import java.lang.annotation.Target;\n" +
+				"@Documented\n" + 
+				"@Retention(RetentionPolicy.CLASS)\n" + 
+				"@Target({ TYPE_USE })\n" + 
+				"public @interface NonNull {\n" + 
+				"	// marker annotation with no members\n" + 
+				"}\n";
 
+		createFile(
+			"/Reconciler18/src/org/eclipse/jdt/annotation/NonNull.java",
+			source
+		);
+		this.workingCopies = new ICompilationUnit[1];
+		this.problemRequestor.initialize(source.toCharArray());
+		this.workingCopies[0] = getCompilationUnit("/Reconciler18/src/org/eclipse/jdt/annotation/NonNull.java").getWorkingCopy(this.wcOwner, null);
+		assertProblems(
+			"Unexpected problems",
+			"----------\n" + 
+			"----------\n"
+		);
+	} finally {
+		if (project18 != null)
+			deleteProject(project18);
+	}
+}
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
index 92d8969..919c45e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests9.java
@@ -16,8 +16,15 @@
 
 
 import java.io.IOException;
+import java.util.Hashtable;
 
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IProblemRequestor;
@@ -393,4 +400,54 @@
 		deleteProject("P1");
 	}
 }
+public void testBug540541() throws CoreException, IOException {
+	if (!isJRE9) return;
+	IJavaProject project1 = null;
+	IJavaProject project2 = null;
+	Hashtable<String, String> options = JavaCore.getOptions();
+	try {
+		project1 = createJava9Project("java.base", "9");
+		createFile("/java.base/src/module-info.java",
+					"module java.base {\n" +
+					"	exports java.lang;\n" +
+					"}");
+		createFolder("/java.base/src/java/lang");
+		createFile("/java.base/src/java/lang/Object.java",
+					"package java.lang;\n" +
+					"public class Object {\n" +
+					"}\n");
+		
+		project1.setRawClasspath(new IClasspathEntry[] {JavaCore.newSourceEntry(new Path("/java.base/src"))}, null);
+		project1.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null);
+		IMarker[] markers = project1.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+		assertMarkers("Unexpected markers on java.base", "", markers);
+		
+		project2 = createJava9Project("client", "9");
+		IClasspathAttribute[] attributes = new IClasspathAttribute[] { JavaCore.newClasspathAttribute("module", "true") };
+		IClasspathEntry projectEntry = JavaCore.newProjectEntry(project1.getPath(), null, false, attributes, false);
+		project2.setRawClasspath(new IClasspathEntry[] {projectEntry, JavaCore.newSourceEntry(new Path("/client/src"))}, null);
+		createFolder("/client/src/p");
+		createFile("/client/src/p/X.java",
+					"package p;\n" +
+					"public class X {\n" +
+					"}\n");
+		this.workingCopy = getCompilationUnit("client/src/p/X.java").getWorkingCopy(this.wcOwner, null);
+		this.problemRequestor.initialize(this.workingCopy.getSource().toCharArray());
+		this.workingCopy.reconcile(AST_INTERNAL_JLS11, true, this.wcOwner, null);
+		assertProblems("Expecting no problems",
+						"----------\n" + 
+						"----------\n",
+						this.problemRequestor);
+		
+		markers = project2.getProject().findMarkers(null, true, IResource.DEPTH_INFINITE);
+		assertMarkers("Unexpected markers on client", "", markers);
+	} finally {
+		if (project1 != null)
+			deleteProject(project1);
+		if (project2 != null)
+			deleteProject(project2);
+		JavaCore.setOptions(options);
+	}
+}
+
 }
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
index 9e76945..b5ff9eb 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests9.java
@@ -268,13 +268,11 @@
 			int length = selection.length();
 			
 			waitUntilIndexesReady();
-			// once indexes are ready, there's no second try and since
-			// SelectionOnQualifiedTypeReference ("test.ITest") cannot be resolved, 
-			// we don't recognize the selection:
+			// even after indexes are built we meanwhile (after bug 540541) find the selected type
 			IJavaElement[] elements = this.wc.codeSelect(start, length);
 			assertElementsEqual(
 				"Unexpected elements",
-				"",
+				"ITest [in ITest.java [in test [in src [in Resolve]]]]",
 				elements
 			);
 		} finally {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
index 3695005..1333386 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RunJavaSearchTests.java
@@ -71,6 +71,7 @@
 		allClasses.add(JavaSearchScopeTests.class);
 		allClasses.add(MatchingRegionsTest.class);
 		allClasses.add(JavaIndexTests.class);
+		allClasses.add(Bug376673Test.class);
 
 		// Reset forgotten subsets of tests
 		TestCase.TESTS_PREFIX = null;
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java
new file mode 100644
index 0000000..89aa366
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/A_out.java
@@ -0,0 +1,160 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {}
+		int a = 10;
+		while (a-- > 0) {
+			System.out.println(a);
+		}
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (a == 0) {
+			return null;
+		}
+		if (false) {}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {};
+	Runnable tinyLambda = () -> {
+		doSomething();
+	};
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {
+	}
+
+	void foo() {
+		if (true) {
+		} else {
+		}
+		synchronized (this) {
+		}
+		try {
+		} finally {
+		}
+
+		labeled: {
+		}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() {
+		return something;
+	}
+
+	public void setSomehing(int something) {
+		this.something = something;
+	}
+
+	public void doNoting() {
+	}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() {
+			return a;
+		}
+	};
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+	A;
+}
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {
+	};
+}
+
+public enum EnumConstants {
+	EMPTY {
+	},
+	TINY {
+		int getVal() {
+			return 2;
+		}
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() {
+			return 3;
+		}
+	};
+	int getVal() {
+		return 1;
+	}
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java
new file mode 100644
index 0000000..4c112b8
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/B_out.java
@@ -0,0 +1,145 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (a == 0) {
+			return null;
+		}
+		if (false) {
+		}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {};
+	Runnable tinyLambda = () -> { doSomething(); };
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {
+	}
+
+	void foo() {
+		if (true) {
+		} else {
+		}
+		synchronized (this) {
+		}
+		try {
+		} finally {
+		}
+
+		labeled: {
+		}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() { return something; }
+
+	public void setSomehing(int something) { this.something = something; }
+
+	public void doNoting() {
+	}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {
+	};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() { return a; }
+	};
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum {
+	A;
+}
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {
+	};
+}
+
+public enum EnumConstants {
+	EMPTY {},
+	TINY {
+		int getVal() { return 2; }
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() { return 3; }
+	};
+	int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java
new file mode 100644
index 0000000..ec05534
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/C_out.java
@@ -0,0 +1,143 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {
+		}
+		int a = 10;
+		while (a-- > 0) {
+			System.out.println(a);
+		}
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) { throw new IllegalArgumentException(); }
+		if (a == 0) { return null; }
+		if (false) {
+		}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {
+	};
+	Runnable emptyLambda2 = () -> {
+	};
+	Runnable tinyLambda = () -> {
+		doSomething();
+	};
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {}
+
+	void foo() {
+		if (true) {} else {}
+		synchronized (this) {}
+		try {} finally {}
+
+		labeled: {}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() {
+		return something;
+	}
+
+	public void setSomehing(int something) {
+		this.something = something;
+	}
+
+	public void doNoting() {}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {};
+	TinyClass tinyAnonymous = new TinyClass() { String b; };
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() {
+			return a;
+		}
+	};
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+	EMPTY {
+	},
+	TINY {
+		int getVal() {
+			return 2;
+		}
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() {
+			return 3;
+		}
+	};
+	int getVal() {
+		return 1;
+	}
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java
new file mode 100644
index 0000000..a1e2cca
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/D_out.java
@@ -0,0 +1,148 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {
+		}
+		int a = 10;
+		while (a-- > 0) {
+			System.out.println(a);
+		}
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (a == 0) {
+			return null;
+		}
+		if (false) {
+		}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {};
+	Runnable tinyLambda = () -> { doSomething(); };
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {}
+
+	void foo() {
+		if (true) {} else {}
+		synchronized (this) {}
+		try {} finally {}
+
+		labeled: {}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() {
+		return something;
+	}
+
+	public void setSomehing(int something) {
+		this.something = something;
+	}
+
+	public void doNoting() {
+	}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {};
+	TinyClass tinyAnonymous = new TinyClass() { String b; };
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() {
+			return a;
+		}
+	};
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+	A;
+}
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {
+	};
+}
+
+public enum EnumConstants {
+	EMPTY {},
+	TINY {
+		int getVal() {
+			return 2;
+		}
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() {
+			return 3;
+		}
+	};
+	int getVal() {
+		return 1;
+	}
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java
new file mode 100644
index 0000000..60cf56f
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/E_out.java
@@ -0,0 +1,127 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do { a += 2; System.out.println(a); } while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) { throw new IllegalArgumentException(); }
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {
+	};
+	Runnable emptyLambda2 = () -> {
+	};
+	Runnable tinyLambda = () -> {
+		doSomething();
+	};
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {
+	}
+
+	void foo() {
+		if (true) {
+		} else {
+		}
+		synchronized (this) {
+		}
+		try {
+		} finally {
+		}
+
+		labeled: {
+		}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() { return something; }
+
+	public void setSomehing(int something) { this.something = something; }
+
+	public void doNoting() {}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {
+	};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() { return a; }
+	};
+}
+
+public enum EmptyEnum {
+}
+
+public enum TinyEnum {
+	A;
+}
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+	EMPTY {},
+	TINY { int getVal() { return 2; } },
+	SMALL { int val = 3; int getVal() { return 3; } };
+	int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java
new file mode 100644
index 0000000..012f0e3
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/F_out.java
@@ -0,0 +1,142 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) { throw new IllegalArgumentException(); }
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) { System.out.println("fizz"); }
+		if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {
+	};
+	Runnable emptyLambda2 = () -> {
+	};
+	Runnable tinyLambda = () -> {
+		doSomething();
+	};
+	Runnable smallLambda = () -> {
+		doFirstThing();
+		doSecondThing();
+	};
+}
+
+class Example {
+	static {
+	}
+
+	void foo() {
+		if (true) {
+		} else {
+		}
+		synchronized (this) {
+		}
+		try {
+		} finally {
+		}
+
+		labeled: {
+		}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() {
+		return something;
+	}
+
+	public void setSomehing(int something) {
+		this.something = something;
+	}
+
+	public void doNoting() {
+	}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() {
+			return a;
+		}
+	};
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {
+	};
+}
+
+public enum EnumConstants {
+	EMPTY {},
+	TINY {
+		int getVal() {
+			return 2;
+		}
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() {
+			return 3;
+		}
+	};
+	int getVal() {
+		return 1;
+	}
+}
+
+public @interface EmptyInterface {
+}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java
new file mode 100644
index 0000000..fc1e78c
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/G_out.java
@@ -0,0 +1,121 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {
+		}
+		int a = 10;
+		while (a-- > 0) {
+			System.out.println(a);
+		}
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) { throw new IllegalArgumentException(); }
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) { System.out.println("fizz"); }
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {};
+	Runnable tinyLambda = () -> { doSomething(); };
+	Runnable smallLambda = () -> { doFirstThing(); doSecondThing(); };
+}
+
+class Example {
+	static {}
+
+	void foo() {
+		if (true) {} else {}
+		synchronized (this) {}
+		try {} finally {}
+
+		labeled: {}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() { return something; }
+
+	public void setSomehing(int something) { this.something = something; }
+
+	public void doNoting() {}
+
+	public void doOneThing() { System.out.println(); }
+
+	public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+public class EmptyClass {
+}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass {
+	int a;
+	String b;
+}
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {
+	};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() { return a; }
+	};
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+	EMPTY {
+	},
+	TINY {
+		int getVal() { return 2; }
+	},
+	SMALL {
+		int val = 3;
+
+		int getVal() { return 3; }
+	};
+	int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java
new file mode 100644
index 0000000..9eba7cd
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/H_out.java
@@ -0,0 +1,109 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {
+		}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable	emptyLambda		= () -> {};
+	Runnable	emptyLambda2	= () -> {
+								};
+	Runnable	tinyLambda		= () -> { doSomething(); };
+	Runnable	smallLambda		= () -> { doFirstThing(); doSecondThing(); };
+}
+
+class Example {
+	static {
+	}
+
+	void foo() {
+		if (true) {
+		} else {
+		}
+		synchronized (this) {
+		}
+		try {
+		} finally {
+		}
+
+		labeled: {
+		}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() { return something; }
+
+	public void setSomehing(int something) { this.something = something; }
+
+	public void doNoting() {}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+public class EmptyClass {}
+
+public class TinyClass {
+	int a;
+}
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+	EmptyClass	emptyAnonymous	= new EmptyClass() {
+								};
+	TinyClass	tinyAnonymous	= new TinyClass() { String b; };
+	Object		o				= new SmallClass() { int a; int getA() { return a; } };
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum {
+	A;
+}
+
+public enum SmallEnum { VALUE(0); SmallEnum(int val) {}; }
+
+public enum EnumConstants {
+	EMPTY {
+	},
+	TINY { int getVal() { return 2; } },
+	SMALL { int val = 3; int getVal() { return 3; } };
+	int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface {
+	void run();
+}
+
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java
new file mode 100644
index 0000000..82d5839
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/I_out.java
@@ -0,0 +1,125 @@
+class Example {
+	public void example() {
+		for (int i = 0; i < 10; i++) {}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do {
+			a += 2;
+			System.out.println(a);
+		} while (a < 50);
+	}
+}
+
+class Example {
+	public String example(int a) {
+		if (a < 0) {
+			throw new IllegalArgumentException();
+		}
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) {
+			System.out.println("fizz");
+		}
+		if (a % 5 == 0) {
+			System.out.println("buzz");
+			return "";
+		}
+		return Integer.toString(a);
+	}
+}
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {};
+	Runnable tinyLambda = () -> {
+	    doSomething();
+	};
+	Runnable smallLambda = () -> {
+	    doFirstThing();
+	    doSecondThing();
+	};
+}
+
+class Example {
+	static {}
+
+	void foo() {
+		if (true) {} else {}
+		synchronized (this) {}
+		try {} finally {}
+
+		labeled: {}
+	}
+}
+
+public class Example {
+	private int something;
+
+	public int getSomething() {
+		return something;
+	}
+
+	public void setSomehing(int something) {
+		this.something = something;
+	}
+
+	public void doNoting() {}
+
+	public void doOneThing() {
+		System.out.println();
+	}
+
+	public void doMoreThings() {
+		something = 4;
+		doOneThing();
+		doOneThing();
+	}
+}
+
+public class EmptyClass {}
+
+public class TinyClass { int a; }
+
+public class SmallClass { int a; String b; }
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {};
+	TinyClass tinyAnonymous = new TinyClass() {
+		String b;
+	};
+	Object o = new SmallClass() {
+		int a;
+
+		int getA() { return a; }
+	};
+}
+
+public enum EmptyEnum {}
+
+public enum TinyEnum { A; }
+
+public enum SmallEnum {
+	VALUE(0);
+	SmallEnum(int val) {};
+}
+
+public enum EnumConstants {
+	EMPTY {},
+	TINY { int getVal() { return 2; } },
+	SMALL {
+		int val = 3;
+
+		int getVal() { return 3; }
+	};
+	int getVal() { return 1; }
+}
+
+public @interface EmptyInterface {}
+
+public @interface TinyInterface { void run(); }
+
+public @interface SmallInteface {
+	int toA();
+
+	String toB();
+}
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java
new file mode 100644
index 0000000..41d96d0
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_in.java
@@ -0,0 +1,30 @@
+class Example {
+	
+	void method1() {
+		int a;
+	}
+	
+	void method2() {
+		
+		int a;
+		
+		
+	}
+	
+	void method3() {
+		int a; //
+	}
+	
+	void method4() {
+		int a; /* */
+	}
+	
+	void method5() {
+		/* */ int a;
+	}
+	
+	void method6() { int a; /* */ } /* */
+	
+	void method7() { /* */ int a; } /* */
+	
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java
new file mode 100644
index 0000000..2a7ae61
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/J_out.java
@@ -0,0 +1,27 @@
+class Example {
+
+	void method1() { int a; }
+
+	void method2() {
+
+		int a;
+
+	}
+
+	void method3() {
+		int a; //
+	}
+
+	void method4() {
+		int a; /* */
+	}
+
+	void method5() {
+		/* */ int a;
+	}
+
+	void method6() { int a; /* */ } /* */
+
+	void method7() { /* */ int a; } /* */
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java
new file mode 100644
index 0000000..bde96a4
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test205973/in.java
@@ -0,0 +1,93 @@
+class Example{
+	public void example() {
+		for (int i = 0; i < 10; i++) {
+		}
+		int a = 10;
+		while (a-- > 0) { System.out.println(a); }
+		do { a += 2;
+		System.out.println(a); } while(a < 50);
+	}
+}
+
+
+class Example {
+	public String example(int a) {
+		if (a < 0) { 
+			throw new IllegalArgumentException(); }
+		if (a == 0) { return null; }
+		if (false) {}
+		if (a % 3 == 0) {
+			System.out.println("fizz"); }
+		if (a % 5 == 0) { System.out.println("buzz"); return ""; }
+		return Integer.toString(a);
+	}
+}
+
+
+class Example {
+	Runnable emptyLambda = () -> {};
+	Runnable emptyLambda2 = () -> {
+	};
+	Runnable tinyLambda = () -> { doSomething(); };
+	Runnable smallLambda = () -> { doFirstThing(); doSecondThing(); };
+}
+
+
+class Example {
+	static {
+	}
+	
+	void foo() {
+		if (true) {} else {}
+		synchronized(this) {}
+		try {} finally {}
+		
+		labeled:{}
+	}
+}
+
+
+public class Example {
+	private int something;
+	public int getSomething() { return something; }
+	public void setSomehing(int something) { this.something = something; }
+	public void doNoting() {}
+	public void doOneThing() { System.out.println();
+	}
+	public void doMoreThings() { something = 4; doOneThing(); doOneThing(); }
+}
+
+
+public class EmptyClass{}
+public class TinyClass{ 
+	int a; }
+public class SmallClass{ int a; String b; }
+
+
+public class AnonymousClasses {
+	EmptyClass emptyAnonymous = new EmptyClass() {
+	};
+	TinyClass tinyAnonymous = new TinyClass() { String b; };
+	Object o = new SmallClass() { int a; int getA() { return a; } };
+}
+
+
+public enum EmptyEnum {}
+public enum TinyEnum{ A;
+}
+public enum SmallEnum{ VALUE(0); SmallEnum(int val) {}; }
+
+
+public enum EnumConstants {
+	EMPTY {
+	},
+	TINY { int getVal() { return 2; }},
+	SMALL { int val = 3; int getVal() { return 3; }};
+	int getVal() { return 1; }
+}
+
+
+public @interface EmptyInterface {}
+public @interface TinyInterface { 
+	void run(); }
+public @interface SmallInteface { int toA(); String toB(); }
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
index 7b6cead..19532de 100644
--- a/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
+++ b/org.eclipse.jdt.core.tests.model/workspace/Formatter/test496/A_out.java
@@ -1,7 +1,8 @@
 public class A {
 
     void doX() {
-        if (1 > 0) { return; //
+        if (1 > 0) {
+            return; //
         }
         return;
     }
diff --git a/org.eclipse.jdt.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
index 8450e8a..f3331f2 100644
--- a/org.eclipse.jdt.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core/META-INF/MANIFEST.MF
@@ -14,9 +14,9 @@
  org.eclipse.jdt.core.formatter,
  org.eclipse.jdt.core.index,
  org.eclipse.jdt.core.jdom,
+ org.eclipse.jdt.core.provisional;x-friends:="org.eclipse.jdt.debug.ui,org.eclipse.jdt.launching,org.eclipse.jdt.ui",
  org.eclipse.jdt.core.search,
  org.eclipse.jdt.core.util,
- org.eclipse.jdt.core.provisional;x-friends:="org.eclipse.jdt.debug.ui,org.eclipse.jdt.launching",
  org.eclipse.jdt.internal.codeassist;x-internal:=true,
  org.eclipse.jdt.internal.codeassist.complete;x-internal:=true,
  org.eclipse.jdt.internal.codeassist.impl;x-internal:=true,
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 d1030b9..4993c0b 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
@@ -30,6 +30,7 @@
  *     Jesper S Moller   - Contributions for
  *								bug 407297 - [1.8][compiler] Control generation of parameter names by option
  *    Mat Booth - Contribution for bug 405176 
+ *    Frits Jalvingh - fix for bug 533830.
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.batch;
 
@@ -105,6 +106,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.parser.Parser;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblem;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
@@ -828,6 +830,9 @@
 
 		private void logProblem(CategorizedProblem problem, int localErrorCount,
 			int globalErrorCount, char[] unitSource) {
+			if(problem instanceof DefaultProblem) {
+				((DefaultProblem) problem).reportError();
+			}
 			if ((this.tagBits & Logger.EMACS) != 0) {
 				String severity = problem.isError() ? "output.emacs.error" : //$NON-NLS-1$
 									problem.isInfo() ? "output.emacs.info" //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 8bc9f2a..7d500e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -14,7 +14,8 @@
  *     Technical University Berlin - extended API and implementation
  *     Stephan Herrmann  - Contribution for bug 295551
  *     Jesper S Moller   - Contributions for
- *							  Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335             
+ *							  Bug 405066 - [1.8][compiler][codegen] Implement code generation infrastructure for JSR335
+ *     Frits Jalvingh    - contributions for bug 533830.             
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
@@ -294,11 +295,6 @@
 	int problemCount = this.compilationResult.problemCount;
 	CategorizedProblem[] problems = this.compilationResult.problems;
 	if (this.suppressWarningsCount == 0) {
-		 for (int iProblem = 0, length = problemCount; iProblem < length; iProblem++) {
-			 if (problems[iProblem] instanceof DefaultProblem) {
-				 ((DefaultProblem)problems[iProblem]).reportError();
-			 }
-		 }
 		return;
 	}
 	int removed = 0;
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 37951c7..e86303e 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
@@ -175,10 +175,9 @@
 			case ClassFileConstants.MAJOR_VERSION_1_1:
 				return ((long)ClassFileConstants.MAJOR_VERSION_1_1 << 16) + ClassFileConstants.MINOR_VERSION_3;
 			default:
-				if (major <= MAJOR_LATEST_VERSION)
-					return ((long)major << 16) + ClassFileConstants.MINOR_VERSION_0;
+				major = Math.min(major, MAJOR_LATEST_VERSION);
+				return ((long)major << 16) + ClassFileConstants.MINOR_VERSION_0;
 		}
-		return 0;
 	}
 	/*
 	 * cldc1.1 is 45.3, but we modify it to be different from JDK1_1.
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
index e602d24..b7b81f4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java
@@ -16,6 +16,7 @@
 import java.util.function.Predicate;
 
 import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
 
 /**
  * A module aware name environment
@@ -107,6 +108,18 @@
 	/** Answer a type identified by the given names. moduleName may be one of the special names from ModuleBinding (ANY, ANY_NAMED, UNNAMED). */
 	NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName);
 	char[][] getModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName);
+	default char[][] getUniqueModulesDeclaringPackage(char[][] parentPackageName, char[] name, char[] moduleName) {
+		char[][] allNames = getModulesDeclaringPackage(parentPackageName, name, moduleName);
+		if (allNames != null && allNames.length > 1) {
+			SimpleSetOfCharArray set = new SimpleSetOfCharArray(allNames.length);
+			for (char[] oneName : allNames)
+				set.add(oneName);
+			allNames = new char[set.elementSize][];
+			set.asArray(allNames);
+		}
+		return allNames;
+	}
+
 	
 	/**
 	 * Answer whether the given package (within the given module) contains any compilation unit.
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 01834ac..073e3b2 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
@@ -1020,6 +1020,9 @@
 		return 0;
 	}
 	public static long versionToJdkLevel(String versionID) {
+		return versionToJdkLevel(versionID, true);
+	}
+	public static long versionToJdkLevel(String versionID, boolean supportUnreleased) {
 		String version = versionID;
 		// verification is optimized for all versions with same length and same "1." prefix
 		if (version != null && version.length() > 0) {
@@ -1055,10 +1058,13 @@
 							version = version.substring(0, index);
 					}
 					int major = Integer.parseInt(version) + ClassFileConstants.MAJOR_VERSION_0;
-					if (major <= ClassFileConstants.MAJOR_LATEST_VERSION) {
-						long jdkLevel = ((long) major << 16) + ClassFileConstants.MINOR_VERSION_0;
-						return jdkLevel;
+					if (major > ClassFileConstants.MAJOR_LATEST_VERSION) {
+						if (supportUnreleased)
+							major = ClassFileConstants.MAJOR_LATEST_VERSION;
+						else
+							return 0; // unknown
 					}
+					return ((long) major << 16) + ClassFileConstants.MINOR_VERSION_0;
 				} catch (NumberFormatException e) {
 					// do nothing and return 0 at the end
 				}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
index a12b2db..9dce583 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java
@@ -625,6 +625,8 @@
 public
 // SH}
 void faultInImports() {
+	if (this.tempImports != null)
+		return; // faultInImports already in progress
 	boolean unresolvedFound = false;
 	// should report unresolved only if we are not suppressing caching of failed resolutions
 	boolean reportUnresolved = !this.suppressImportErrors;
@@ -777,6 +779,7 @@
 	if (this.tempImports.length > this.importPtr)
 		System.arraycopy(this.tempImports, 0, this.tempImports = new ImportBinding[this.importPtr], 0, this.importPtr);
 	this.imports = this.tempImports;
+	this.tempImports = null;
 	int length = this.imports.length;
 	this.typeOrPackageCache = new HashtableOfObject(length);
 	for (int i = 0; i < length; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index d0f230d..63c5adb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -368,6 +368,8 @@
 	ReferenceBinding candidate = null;
 	for (NameEnvironmentAnswer answer : answers) {
 		if (answer == null) continue;
+		if (candidate != null && candidate.problemId() == ProblemReasons.Ambiguous)
+			return candidate; // saw enough
 //{ObjectTeams: if we were looking specifically for a source type, and if this is satisfied now, reset to normal:
 		if (!answer.isBinaryType() && Config.hasConfig())
 			Config.setSourceTypeRequired(false);
@@ -430,8 +432,6 @@
 			continue;
 		}
 		candidate = combine(candidate, answerPackage.getType0(name), clientModule);
-		if (candidate != null && candidate.problemId() == ProblemReasons.Ambiguous)
-			return candidate; // saw enough
 	}
 	return candidate;
 }
@@ -959,7 +959,7 @@
 	if (packageBinding == null || packageBinding == TheNotFoundPackage) {
 		if (this.useModuleSystem) {
 			if (this.module.isUnnamed()) {
-				char[][] declaringModules = ((IModuleAwareNameEnvironment) this.nameEnvironment).getModulesDeclaringPackage(null, constantPoolName[0], ModuleBinding.ANY);
+				char[][] declaringModules = ((IModuleAwareNameEnvironment) this.nameEnvironment).getUniqueModulesDeclaringPackage(null, constantPoolName[0], ModuleBinding.ANY);
 				if (declaringModules != null) {
 					for (char[] mod : declaringModules) {
 						ModuleBinding declaringModule = this.root.getModule(mod);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 7cf8b0e..ec3fdcd 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -18,9 +18,12 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
@@ -535,12 +538,13 @@
 		}
 
 		PackageBinding binding = null;
+		char[][] declaringModuleNames = null;
 		boolean packageMayBeIncomplete = !considerRequiredModules;
 		if (this.environment.useModuleSystem) {
 			IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
-			char[][] declaringModuleNames = moduleEnv.getModulesDeclaringPackage(parentName, name, nameForLookup());
+			declaringModuleNames = moduleEnv.getUniqueModulesDeclaringPackage(parentName, name, nameForLookup());
 			if (declaringModuleNames != null) {
-				if (!this.isUnnamed() && CharOperation.containsEqual(declaringModuleNames, this.moduleName)) {
+				if (CharOperation.containsEqual(declaringModuleNames, this.moduleName)) {
 					// declared here, not yet known, so create it now:
 					binding = new PackageBinding(subPkgCompoundName, parent, this.environment, this);
 				} else if (considerRequiredModules) {
@@ -571,8 +575,8 @@
 		}
 
 		// enrich with split-siblings from visible modules:
-		if (!isUnnamed() && considerRequiredModules) {
-			binding = combineWithPackagesFromRequired(binding, subPkgCompoundName);
+		if (considerRequiredModules) {
+			binding = combineWithPackagesFromOtherRelevantModules(binding, subPkgCompoundName, declaringModuleNames);
 		}
 		if (binding == null || !binding.isValidBinding()) {
 			if (parent != null && !packageMayBeIncomplete) // don't remember package that may still lack some siblings
@@ -596,6 +600,9 @@
 	 * </p>
 	 */
 	public PackageBinding getVisiblePackage(char[][] qualifiedPackageName) {
+		return getVisiblePackage(qualifiedPackageName, true);
+	}
+	PackageBinding getVisiblePackage(char[][] qualifiedPackageName, boolean considerRequiredModules) {
 		if (qualifiedPackageName == null || qualifiedPackageName.length == 0) {
 			return this.environment.defaultPackage;
 		}
@@ -606,7 +613,7 @@
 
 		// check each sub package
 		for (int i = 1; i < qualifiedPackageName.length; i++) {
-			PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i], true); 
+			PackageBinding binding = getVisiblePackage(parent, qualifiedPackageName[i], considerRequiredModules); 
 			if (binding == null || binding == LookupEnvironment.TheNotFoundPackage) {
 				return null;
 			}
@@ -653,19 +660,12 @@
 		if (packageBinding.isDeclaredIn(this)) {
 			char[] packageName = packageBinding.readableName();
 			if (checkForSplit && this.environment.useModuleSystem) {
+				char[][] declaringModuleNames = null;
 				if (isUnnamed()) {
 					IModuleAwareNameEnvironment moduleEnv = (IModuleAwareNameEnvironment) this.environment.nameEnvironment;
-					char[][] declaringModuleNames = moduleEnv.getModulesDeclaringPackage(null, packageName, ANY);
-					if (declaringModuleNames != null) {
-						for (int i = 0; i < declaringModuleNames.length; i++) {
-							ModuleBinding otherModule = this.environment.getModule(declaringModuleNames[i]);
-							if (otherModule != null && !otherModule.isPackageLookupActive)
-								packageBinding = SplitPackageBinding.combine(otherModule.getVisiblePackage(packageBinding.compoundName), packageBinding, this);
-						}
-					}
-				} else {
-					packageBinding = combineWithPackagesFromRequired(packageBinding, packageBinding.compoundName);
+					declaringModuleNames = moduleEnv.getUniqueModulesDeclaringPackage(null, packageName, ANY);
 				}
+				packageBinding = combineWithPackagesFromOtherRelevantModules(packageBinding, packageBinding.compoundName, declaringModuleNames);
 			}
 			this.declaredPackages.put(packageName, packageBinding);
 			if (packageBinding.parent == null) {
@@ -675,19 +675,40 @@
 		return packageBinding;
 	}
 	
-	private PackageBinding combineWithPackagesFromRequired(PackageBinding currentBinding, char[][] compoundName) {
+	private PackageBinding combineWithPackagesFromOtherRelevantModules(PackageBinding currentBinding, char[][] compoundName, char[][] declaringModuleNames) {
 		boolean save = this.isPackageLookupActive;
 		this.isPackageLookupActive = true;
 		try {
-			for (ModuleBinding moduleBinding : getAllRequiredModules())
-				if (!moduleBinding.isPackageLookupActive)
-					currentBinding = SplitPackageBinding.combine(moduleBinding.getVisiblePackage(compoundName), currentBinding, this);
+			char[] singleName = compoundName[compoundName.length-1];
+			PackageBinding parent = currentBinding != null ? currentBinding.parent : null;
+			for (ModuleBinding moduleBinding : otherRelevantModules(declaringModuleNames)) {
+				if (!moduleBinding.isPackageLookupActive) {
+					PackageBinding nextBinding = parent != null 
+							? moduleBinding.getVisiblePackage(parent, singleName, true)
+							: moduleBinding.getVisiblePackage(compoundName, true);
+					currentBinding = SplitPackageBinding.combine(nextBinding, currentBinding, this);
+				}
+			}
 			return currentBinding;
 		} finally {
 			this.isPackageLookupActive = save;
 		}
 	}
 
+	List<ModuleBinding> otherRelevantModules(char[][] declaringModuleNames) {
+		if (isUnnamed() && declaringModuleNames != null) {
+			// unnamed module reads all named modules,
+			// so all modules declaring the given package are relevant:
+			return Arrays.stream(declaringModuleNames)
+				.filter(modName -> modName != UNNAMED)
+				.map(modName -> this.environment.getModule(modName))
+				.filter(Objects::nonNull)
+				.collect(Collectors.toList());
+		} else {
+			return Arrays.asList(getAllRequiredModules());
+		}
+	}
+
 	/**
 	 * Check if the given package is accessible by this module. True when the package is declared in
 	 * this module or exported by some required module to this module.
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 7716e2a..e663811 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
@@ -917,6 +917,7 @@
 	 * @since 3.1
 	 * @deprecated Use {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_BLOCK_COMMENT} and {@link #FORMATTER_COMMENT_CLEAR_BLANK_LINES_IN_JAVADOC_COMMENT}
 	 */
+	@Deprecated
 	public final static String FORMATTER_COMMENT_CLEAR_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines"; //$NON-NLS-1$
 
 	/**
@@ -958,6 +959,7 @@
 	 * @deprecated Use multiple settings for each kind of comments. See {@link #FORMATTER_COMMENT_FORMAT_BLOCK_COMMENT},
 	 * {@link #FORMATTER_COMMENT_FORMAT_JAVADOC_COMMENT} and {@link #FORMATTER_COMMENT_FORMAT_LINE_COMMENT}.
 	 */
+	@Deprecated
 	public final static String FORMATTER_COMMENT_FORMAT = "org.eclipse.jdt.core.formatter.comment.format_comments"; //$NON-NLS-1$
 
 	/**
@@ -1670,6 +1672,7 @@
 	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE}
 	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PARAMETER}
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation";//$NON-NLS-1$
 
 	/**
@@ -1689,6 +1692,7 @@
 	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_PACKAGE}
 	 * {@link #FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_TYPE}
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_after_annotation_on_member";//$NON-NLS-1$
 
 	/**
@@ -1902,7 +1906,9 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.2
+	 * @deprecated Use {@link #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_annotation_declaration";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1914,7 +1920,9 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.0
+	 * @deprecated Use {@link #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_anonymous_type_declaration";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1926,7 +1934,12 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.0
+	 * @deprecated Use {@link #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE},
+	 *             {@link #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE},
+	 *             {@link #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE}, and
+	 *             {@link #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_block";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1938,7 +1951,9 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.1
+	 * @deprecated Use {@link #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_constant";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1950,7 +1965,9 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.1
+	 * @deprecated Use {@link #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_enum_declaration";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1962,7 +1979,9 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.0
+	 * @deprecated Use {@link #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_method_body";	//$NON-NLS-1$
 	/**
 	 * <pre>
@@ -1974,8 +1993,11 @@
 	 * @see JavaCore#INSERT
 	 * @see JavaCore#DO_NOT_INSERT
 	 * @since 3.0
+	 * @deprecated Use {@link #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE} instead.
 	 */
+	@Deprecated
 	public static final String FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_empty_type_declaration";	//$NON-NLS-1$
+
 	/**
 	 * <pre>
 	 * FORMATTER / Option to insert a space after and in wilcard
@@ -3939,13 +3961,15 @@
 	public static final String FORMATTER_KEEP_EMPTY_ARRAY_INITIALIZER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_empty_array_initializer_on_one_line"; //$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to keep guardian clause on one line
+	 * FORMATTER / Option to keep guardian clause on one line, in addition to the
+	 *             #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE option
 	 *     - option id:         "org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line"
 	 *     - possible values:   { TRUE, FALSE }
 	 *     - default:           FALSE
 	 * </pre>
 	 * @see #TRUE
 	 * @see #FALSE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
 	 * @since 3.0
 	 */
 	public static final String FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line";	//$NON-NLS-1$
@@ -4013,6 +4037,180 @@
 
 	/**
 	 * <pre>
+	 * FORMATTER / Option to control when a loop body block should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_loop_body_block_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when an if-then statement body block should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @see #FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE for a special case
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_if_then_body_block_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when a code block other than if-then and loop body should
+	 *             be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_code_block_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_code_block_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when a method body should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_method_body_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_method_body_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when a lambda body should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_lambda_body_block_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to always keep simple getters and setters on one line, in addition to the
+	 *             #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE option
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line"
+	 *     - possible values:   { TRUE, FALSE }
+	 *     - default:           FALSE
+	 * </pre>
+	 * @see #TRUE
+	 * @see #FALSE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_simple_getter_setter_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when a type declaration should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 * @since 3.0
+	 */
+	public static final String FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_type_declaration_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when an anonymous type declaration should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_anonymous_type_declaration_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when an enum constant declaration body should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_enum_constant_declaration_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when an enum declaration should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_enum_declaration_on_one_line"; //$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Option to control when an annotation declaration should be kept on one line
+	 *     - option id:         "org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line"
+	 *     - possible values:   { ONE_LINE_NEVER, ONE_LINE_IF_EMPTY, ONE_LINE_IF_SINGLE_ITEM,
+	 *                            ONE_LINE_ALWAYS, ONE_LINE_PRESERVE }
+	 *     - default:           ONE_LINE_NEVER
+	 * </pre>
+	 * @see #ONE_LINE_NEVER
+	 * @see #ONE_LINE_IF_EMPTY
+	 * @see #ONE_LINE_IF_SINGLE_ITEM
+	 * @see #ONE_LINE_ALWAYS
+	 * @see #ONE_LINE_PRESERVE
+	 * @since 3.16
+	 */
+	public static final String FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.keep_annotation_declaration_on_one_line"; //$NON-NLS-1$
+
+	/**
+	 * <pre>
 	 * FORMATTER / Option to specify the length of the page. Beyond this length, the formatter will try to split the code
 	 *     - option id:         "org.eclipse.jdt.core.formatter.lineSplit"
 	 *     - possible values:   "&lt;n&gt;", where n is zero or a positive integer
@@ -4439,6 +4637,92 @@
 
 	/**
 	 * <pre>
+	 * FORMATTER / Value to never keep braced code on one line.
+	 * </pre>
+	 * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String ONE_LINE_NEVER = "one_line_never";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to keep braced code on one line only if it's empty.
+	 * </pre>
+	 * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String ONE_LINE_IF_EMPTY = "one_line_if_empty";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to keep braced code on one line if it contains at most a single
+	 *             item.
+	 * </pre>
+	 * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String ONE_LINE_IF_SINGLE_ITEM = "one_line_if_single_item";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to always keep braced code on one line, as long as it doesn't
+	 *             exceed the line width limit.
+	 * </pre>
+	 * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String ONE_LINE_ALWAYS = "one_line_always";	//$NON-NLS-1$
+	/**
+	 * <pre>
+	 * FORMATTER / Value to keep braced code on one line as long as it doesn't exceed the
+	 *             line width limit and it was already in one line in the original source.
+	 * </pre>
+	 * @see #FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE
+	 * @see #FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE
+	 * @since 3.16
+	 */
+	public static final String ONE_LINE_PRESERVE = "one_line_preserve";	//$NON-NLS-1$
+
+	/**
+	 * <pre>
 	 * FORMATTER / Value to set an option to true.
 	 * </pre>
 	 * @since 3.0
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index 96080ea..3b6826d 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -433,6 +433,7 @@
 		LineBreaksPreparator breaksPreparator = new LineBreaksPreparator(this.tokenManager, this.workingOptions);
 		this.astRoot.accept(breaksPreparator);
 		breaksPreparator.finishUp();
+		this.astRoot.accept(new OneLineEnforcer(this.tokenManager, this.workingOptions));
 	}
 
 	private void prepareComments() {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index be69d11..8d0c166 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -21,11 +21,14 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.formatter;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.function.Consumer;
 
-import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.util.Util;
 
@@ -254,13 +257,19 @@
 	public boolean insert_new_line_before_else_in_if_statement;
 	public boolean insert_new_line_before_finally_in_try_statement;
 	public boolean insert_new_line_before_while_in_do_statement;
-	public boolean insert_new_line_in_empty_anonymous_type_declaration;
-	public boolean insert_new_line_in_empty_block;
-	public boolean insert_new_line_in_empty_annotation_declaration;
-	public boolean insert_new_line_in_empty_enum_constant;
-	public boolean insert_new_line_in_empty_enum_declaration;
-	public boolean insert_new_line_in_empty_method_body;
-	public boolean insert_new_line_in_empty_type_declaration;
+
+	public String keep_loop_body_block_on_one_line;
+	public String keep_if_then_body_block_on_one_line;
+	public String keep_code_block_on_one_line;
+	public String keep_lambda_body_block_on_one_line;
+	public String keep_method_body_on_one_line;
+	public String keep_type_declaration_on_one_line;
+	public String keep_anonymous_type_declaration_on_one_line;
+	public String keep_enum_declaration_on_one_line;
+	public String keep_enum_constant_declaration_on_one_line;
+	public String keep_annotation_declaration_on_one_line;
+	public boolean keep_simple_getter_setter_on_one_line;
+
 	public boolean insert_space_after_and_in_type_parameter;
 	public boolean insert_space_after_assignment_operator;
 	public boolean insert_space_after_at_in_annotation;
@@ -451,6 +460,13 @@
 	public int initial_indentation_level;
 	public String line_separator;
 
+	private final static List<String> KEEP_ON_ONE_LINE_VALUES = Arrays.asList(
+			DefaultCodeFormatterConstants.ONE_LINE_NEVER,
+			DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY,
+			DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM,
+			DefaultCodeFormatterConstants.ONE_LINE_ALWAYS,
+			DefaultCodeFormatterConstants.ONE_LINE_PRESERVE);
+
 	private DefaultCodeFormatterOptions() {
 		// cannot be instantiated
 	}
@@ -584,13 +600,17 @@
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, this.insert_new_line_before_else_in_if_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, this.insert_new_line_before_finally_in_try_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, this.insert_new_line_before_while_in_do_statement? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION, this.insert_new_line_in_empty_anonymous_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, this.insert_new_line_in_empty_block? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION, this.insert_new_line_in_empty_annotation_declaration ? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT, this.insert_new_line_in_empty_enum_constant? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION, this.insert_new_line_in_empty_enum_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, this.insert_new_line_in_empty_method_body? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
-		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, this.insert_new_line_in_empty_type_declaration? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE, this.keep_annotation_declaration_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE, this.keep_anonymous_type_declaration_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE, this.keep_if_then_body_block_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE, this.keep_lambda_body_block_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE, this.keep_loop_body_block_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE, this.keep_code_block_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE, this.keep_enum_constant_declaration_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE, this.keep_enum_declaration_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE, this.keep_method_body_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE, this.keep_type_declaration_on_one_line);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE, this.keep_simple_getter_setter_on_one_line? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL, this.insert_new_line_after_label? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_AND_IN_TYPE_PARAMETER, this.insert_space_after_and_in_type_parameter? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
 		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, this.insert_space_after_assignment_operator? JavaCore.INSERT : JavaCore.DO_NOT_INSERT);
@@ -1538,34 +1558,31 @@
 		if (insertNewLineBeforeWhileInDoStatementOption != null) {
 			this.insert_new_line_before_while_in_do_statement = JavaCore.INSERT.equals(insertNewLineBeforeWhileInDoStatementOption);
 		}
-		final Object insertNewLineInEmptyAnonymousTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION);
-		if (insertNewLineInEmptyAnonymousTypeDeclarationOption != null) {
-			this.insert_new_line_in_empty_anonymous_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnonymousTypeDeclarationOption);
-		}
-		final Object insertNewLineInEmptyBlockOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK);
-		if (insertNewLineInEmptyBlockOption != null) {
-			this.insert_new_line_in_empty_block = JavaCore.INSERT.equals(insertNewLineInEmptyBlockOption);
-		}
-		final Object insertNewLineInEmptyAnnotationDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION);
-		if (insertNewLineInEmptyAnnotationDeclarationOption != null) {
-			this.insert_new_line_in_empty_annotation_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyAnnotationDeclarationOption);
-		}
-		final Object insertNewLineInEmptyEnumConstantOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT);
-		if (insertNewLineInEmptyEnumConstantOption != null) {
-			this.insert_new_line_in_empty_enum_constant = JavaCore.INSERT.equals(insertNewLineInEmptyEnumConstantOption);
-		}
-		final Object insertNewLineInEmptyEnumDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION);
-		if (insertNewLineInEmptyEnumDeclarationOption != null) {
-			this.insert_new_line_in_empty_enum_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyEnumDeclarationOption);
-		}
-		final Object insertNewLineInEmptyMethodBodyOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY);
-		if (insertNewLineInEmptyMethodBodyOption != null) {
-			this.insert_new_line_in_empty_method_body = JavaCore.INSERT.equals(insertNewLineInEmptyMethodBodyOption);
-		}
-		final Object insertNewLineInEmptyTypeDeclarationOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION);
-		if (insertNewLineInEmptyTypeDeclarationOption != null) {
-			this.insert_new_line_in_empty_type_declaration = JavaCore.INSERT.equals(insertNewLineInEmptyTypeDeclarationOption);
-		}
+		
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_annotation_declaration_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_anonymous_type_declaration_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_if_then_body_block_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_loop_body_block_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_lambda_body_block_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE,
+				Arrays.asList(DefaultCodeFormatterConstants.ONE_LINE_NEVER, DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY),
+				v -> this.keep_code_block_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_enum_constant_declaration_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_enum_declaration_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_method_body_on_one_line = v);
+		setString(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE, KEEP_ON_ONE_LINE_VALUES,
+				v -> this.keep_type_declaration_on_one_line = v);
+		setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_KEEP_SIMPLE_GETTER_SETTER_ON_ONE_LINE, DefaultCodeFormatterConstants.TRUE,
+				v -> this.keep_simple_getter_setter_on_one_line = v);
+
 		final Object insertNewLineAfterLabelOption = settings.get(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_LABEL);
 		if (insertNewLineAfterLabelOption != null) {
 			this.insert_new_line_after_label = JavaCore.INSERT.equals(insertNewLineAfterLabelOption);
@@ -2397,6 +2414,21 @@
 		return defaultValue;
 	}
 
+	private void setString(Map<String, String> settings, String key, List<String> allowedValues, Consumer<String> setter) {
+		Object value = settings.get(key);
+		if (value != null) {
+			if (!allowedValues.contains(value))
+				throw new IllegalArgumentException("Unrecognized value for setting " + key + ": " + value); //$NON-NLS-1$ //$NON-NLS-2$
+			setter.accept((String) value);
+		}
+	}
+
+	private void setBoolean(Map<String, String> settings, String key, String trueValue, Consumer<Boolean> setter) {
+		Object value = settings.get(key);
+		if (value != null)
+			setter.accept(trueValue.equals(value));
+	}
+
 	/**
 	 * This method is used to handle deprecated preferences which might be replaced by
 	 * one or more preferences.
@@ -2493,6 +2525,51 @@
 				this.insert_new_line_after_annotation_on_local_variable = JavaCore.INSERT.equals(insertNewLineAfterAnnotationOnLocalVariableOption);
 			}
 		}
+
+		// insert new line between empty braces -> keep braced code on one line
+		HashMap<Boolean, String> insertToOneLine = new HashMap<>();
+		insertToOneLine.put(true, DefaultCodeFormatterConstants.ONE_LINE_NEVER);
+		insertToOneLine.put(false, DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY);
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANNOTATION_DECLARATION_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANNOTATION_DECLARATION, JavaCore.INSERT,
+					v -> this.keep_annotation_declaration_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ANONYMOUS_TYPE_DECLARATION_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ANONYMOUS_TYPE_DECLARATION, JavaCore.INSERT,
+					v -> this.keep_anonymous_type_declaration_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_IF_THEN_BODY_BLOCK_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+					v -> this.keep_if_then_body_block_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_LOOP_BODY_BLOCK_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+					v -> this.keep_loop_body_block_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_LAMBDA_BODY_BLOCK_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+					v -> this.keep_lambda_body_block_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_CODE_BLOCK_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_BLOCK, JavaCore.INSERT,
+					v -> this.keep_code_block_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_CONSTANT_DECLARATION_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_CONSTANT, JavaCore.INSERT,
+					v -> this.keep_enum_constant_declaration_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_ENUM_DECLARATION_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_ENUM_DECLARATION, JavaCore.INSERT,
+					v -> this.keep_enum_declaration_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_METHOD_BODY_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_METHOD_BODY, JavaCore.INSERT,
+					v -> this.keep_method_body_on_one_line = insertToOneLine.get(v));
+		}
+		if (settings.get(DefaultCodeFormatterConstants.FORMATTER_KEEP_TYPE_DECLARATION_ON_ONE_LINE) == null) {
+			setBoolean(settings, DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_EMPTY_TYPE_DECLARATION, JavaCore.INSERT,
+					v -> this.keep_type_declaration_on_one_line = insertToOneLine.get(v));
+		}
 	}
 
 	public void setDefaultSettings() {
@@ -2613,13 +2690,17 @@
 		this.insert_new_line_before_else_in_if_statement = false;
 		this.insert_new_line_before_finally_in_try_statement = false;
 		this.insert_new_line_before_while_in_do_statement = false;
-		this.insert_new_line_in_empty_anonymous_type_declaration = true;
-		this.insert_new_line_in_empty_block = true;
-		this.insert_new_line_in_empty_annotation_declaration = true;
-		this.insert_new_line_in_empty_enum_constant = true;
-		this.insert_new_line_in_empty_enum_declaration = true;
-		this.insert_new_line_in_empty_method_body = true;
-		this.insert_new_line_in_empty_type_declaration = true;
+		this.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_simple_getter_setter_on_one_line = false;
 		this.insert_space_after_and_in_type_parameter = true;
 		this.insert_space_after_assignment_operator = true;
 		this.insert_space_after_at_in_annotation = false;
@@ -2937,13 +3018,16 @@
 		this.insert_new_line_before_else_in_if_statement = false;
 		this.insert_new_line_before_finally_in_try_statement = false;
 		this.insert_new_line_before_while_in_do_statement = false;
-		this.insert_new_line_in_empty_anonymous_type_declaration = true;
-		this.insert_new_line_in_empty_block = true;
-		this.insert_new_line_in_empty_annotation_declaration = true;
-		this.insert_new_line_in_empty_enum_constant = true;
-		this.insert_new_line_in_empty_enum_declaration = true;
-		this.insert_new_line_in_empty_method_body = true;
-		this.insert_new_line_in_empty_type_declaration = true;
+		this.keep_annotation_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_anonymous_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_if_then_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_lambda_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_loop_body_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_code_block_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_enum_constant_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_enum_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_method_body_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
+		this.keep_type_declaration_on_one_line = DefaultCodeFormatterConstants.ONE_LINE_NEVER;
 		this.insert_space_after_and_in_type_parameter = true;
 		this.insert_space_after_assignment_operator = true;
 		this.insert_space_after_at_in_annotation = false;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
index bcfdee8..041680d 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/LineBreaksPreparator.java
@@ -167,8 +167,7 @@
 		breakLineBefore(node);
 
 		handleBracedCode(node, node.getName(), this.options.brace_position_for_type_declaration,
-				this.options.indent_body_declarations_compare_to_type_header,
-				this.options.insert_new_line_in_empty_type_declaration);
+				this.options.indent_body_declarations_compare_to_type_header);
 
 		this.declarationModifierVisited = false;
 		return true;
@@ -224,8 +223,7 @@
 	@Override
 	public boolean visit(EnumDeclaration node) {
 		handleBracedCode(node, node.getName(), this.options.brace_position_for_enum_declaration,
-				this.options.indent_body_declarations_compare_to_enum_declaration_header,
-				this.options.insert_new_line_in_empty_enum_declaration);
+				this.options.indent_body_declarations_compare_to_enum_declaration_header);
 		handleBodyDeclarations(node.bodyDeclarations());
 
 		List<EnumConstantDeclaration> enumConstants = node.enumConstants();
@@ -257,8 +255,7 @@
 	@Override
 	public boolean visit(AnnotationTypeDeclaration node) {
 		handleBracedCode(node, node.getName(), this.options.brace_position_for_annotation_type_declaration,
-				this.options.indent_body_declarations_compare_to_annotation_declaration_header,
-				this.options.insert_new_line_in_empty_annotation_declaration);
+				this.options.indent_body_declarations_compare_to_annotation_declaration_header);
 
 		handleBodyDeclarations(node.bodyDeclarations());
 		if (node.getModifiers() == 0)
@@ -272,12 +269,10 @@
 	public boolean visit(AnonymousClassDeclaration node) {
 		if (node.getParent() instanceof EnumConstantDeclaration) {
 			handleBracedCode(node, null, this.options.brace_position_for_enum_constant,
-					this.options.indent_body_declarations_compare_to_enum_constant_header,
-					this.options.insert_new_line_in_empty_enum_constant);
+					this.options.indent_body_declarations_compare_to_enum_constant_header);
 		} else {
 			handleBracedCode(node, null, this.options.brace_position_for_anonymous_type_declaration,
-					this.options.indent_body_declarations_compare_to_type_header,
-					this.options.insert_new_line_in_empty_anonymous_type_declaration);
+					this.options.indent_body_declarations_compare_to_type_header);
 		}
 		handleBodyDeclarations(node.bodyDeclarations());
 		return true;
@@ -297,9 +292,7 @@
 
 		String bracePosition = node.isConstructor() ? this.options.brace_position_for_constructor_declaration
 				: this.options.brace_position_for_method_declaration;
-		handleBracedCode(node.getBody(), null, bracePosition,
-				this.options.indent_statements_compare_to_body,
-				this.options.insert_new_line_in_empty_method_body);
+		handleBracedCode(node.getBody(), null, bracePosition, this.options.indent_statements_compare_to_body);
 		Token openBrace = this.tm.firstTokenIn(node.getBody(), TokenNameLBRACE);
 		if (openBrace.getLineBreaksAfter() > 0) // if not, these are empty braces
 			openBrace.putLineBreaksAfter(this.options.blank_lines_at_beginning_of_method_body + 1);
@@ -308,18 +301,14 @@
 
 	@Override
 	public boolean visit(Block node) {
-		if (this.options.keep_guardian_clause_on_one_line && this.tm.isGuardClause(node))
-			return true;
-
 		List<Statement> statements = node.statements();
 		for (Statement statement : statements) {
 			if (this.options.put_empty_statement_on_new_line || !(statement instanceof EmptyStatement))
 				breakLineBefore(statement);
 		}
-		if (node.getParent().getLength() == 0)
-			return true; // this is a fake block created by parsing in statements mode
-
 		ASTNode parent = node.getParent();
+		if (parent.getLength() == 0)
+			return true; // this is a fake block created by parsing in statements mode
 		if (parent instanceof MethodDeclaration)
 			return true; // braces have been handled in #visit(MethodDeclaration)
 
@@ -333,8 +322,7 @@
 		} else if (parent instanceof LambdaExpression) {
 			bracePosition = this.options.brace_position_for_lambda_body;
 		}
-		handleBracedCode(node, null, bracePosition, this.options.indent_statements_compare_to_block,
-				this.options.insert_new_line_in_empty_block);
+		handleBracedCode(node, null, bracePosition, this.options.indent_statements_compare_to_block);
 
 		return true;
 	}
@@ -342,7 +330,7 @@
 	@Override
 	public boolean visit(SwitchStatement node) {
 		handleBracedCode(node, node.getExpression(), this.options.brace_position_for_switch,
-				this.options.indent_switchstatements_compare_to_switch, true);
+				this.options.indent_switchstatements_compare_to_switch);
 
 		List<Statement> statements = node.statements();
 		if (this.options.indent_switchstatements_compare_to_cases) {
@@ -751,8 +739,7 @@
 		// using settings for type declaration and fields for now, add new settings if necessary
 		breakLineBefore(node);
 		handleBracedCode(node, node.getName(), this.options.brace_position_for_type_declaration,
-				this.options.indent_body_declarations_compare_to_type_header,
-				this.options.insert_new_line_in_empty_type_declaration);
+				this.options.indent_body_declarations_compare_to_type_header);
 
 		List<ModuleDirective> statements = node.moduleStatements();
 		ModuleDirective previous = null;
@@ -772,8 +759,7 @@
 		this.tm.firstTokenIn(node, -1).breakBefore();
 	}
 
-	private void handleBracedCode(ASTNode node, ASTNode nodeBeforeOpenBrace, String bracePosition, boolean indentBody,
-			boolean newLineInEmpty) {
+	private void handleBracedCode(ASTNode node, ASTNode nodeBeforeOpenBrace, String bracePosition, boolean indentBody) {
 		int openBraceIndex = nodeBeforeOpenBrace == null
 				? this.tm.firstIndexIn(node, TokenNameLBRACE)
 				: this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
@@ -782,18 +768,9 @@
 		Token closeBraceToken = this.tm.get(closeBraceIndex);
 		handleBracePosition(openBraceToken, closeBraceIndex, bracePosition);
 
-		boolean isEmpty = true;
-		for (int i = openBraceIndex + 1; i < closeBraceIndex; i++) {
-			if (!this.tm.get(i).isComment()) {
-				isEmpty = false;
-				break;
-			}
-		}
+		openBraceToken.breakAfter();
+		closeBraceToken.breakBefore();
 
-		if (!isEmpty || newLineInEmpty) {
-			openBraceToken.breakAfter();
-			closeBraceToken.breakBefore();
-		}
 		if (indentBody) {
 			adjustEmptyLineAfter(openBraceIndex, 1);
 			this.tm.get(openBraceIndex + 1).indent();
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
new file mode 100644
index 0000000..9d9763f
--- /dev/null
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/OneLineEnforcer.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2018 Mateusz Matela and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Mateusz Matela <mateusz.matela@gmail.com> - Initial API and implementation
+ *     
+ *******************************************************************************/
+package org.eclipse.jdt.internal.formatter;
+
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameRBRACE;
+import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNamewhile;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.Assignment;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.DoStatement;
+import org.eclipse.jdt.core.dom.EnhancedForStatement;
+import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
+import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.ForStatement;
+import org.eclipse.jdt.core.dom.IfStatement;
+import org.eclipse.jdt.core.dom.LambdaExpression;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.ModuleDeclaration;
+import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.ReturnStatement;
+import org.eclipse.jdt.core.dom.Statement;
+import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.WhileStatement;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+/** Implementation of the "Keep braced code on one line" feature. */
+public class OneLineEnforcer extends ASTVisitor {
+	private final TokenManager tm;
+	private final DefaultCodeFormatterOptions options;
+
+	public OneLineEnforcer(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
+		this.tm = tokenManager;
+		this.options = options;
+	}
+
+	@Override
+	public void endVisit(TypeDeclaration node) {
+		if (node.getParent().getLength() == 0)
+			return; // this is a fake block created by parsing in statements mode
+		tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(), this.options.keep_type_declaration_on_one_line);
+	}
+
+	@Override
+	public void endVisit(EnumDeclaration node) {
+		List<ASTNode> items = new ArrayList<>();
+		items.addAll(node.bodyDeclarations());
+		items.addAll(node.enumConstants());
+		tryKeepOnOneLine(node, node.getName(), items, this.options.keep_enum_declaration_on_one_line);
+	}
+
+	@Override
+	public void endVisit(AnnotationTypeDeclaration node) {
+		tryKeepOnOneLine(node, node.getName(), node.bodyDeclarations(),
+				this.options.keep_annotation_declaration_on_one_line);
+	}
+
+	@Override
+	public void endVisit(AnonymousClassDeclaration node) {
+		if (node.getParent() instanceof EnumConstantDeclaration) {
+			tryKeepOnOneLine(node, null, node.bodyDeclarations(),
+					this.options.keep_enum_constant_declaration_on_one_line);
+		} else {
+			tryKeepOnOneLine(node, null, node.bodyDeclarations(),
+					this.options.keep_anonymous_type_declaration_on_one_line);
+		}
+	}
+
+	@Override
+	public void endVisit(Block node) {
+		ASTNode parent = node.getParent();
+		List<Statement> statements = node.statements();
+		if (parent.getLength() == 0)
+			return; // this is a fake block created by parsing in statements mode
+		String oneLineOption;
+		if (parent instanceof MethodDeclaration) {
+			oneLineOption = this.options.keep_method_body_on_one_line;
+			if (this.options.keep_simple_getter_setter_on_one_line) {
+				MethodDeclaration method = (MethodDeclaration) parent;
+				String name = method.getName().getIdentifier();
+				Type returnType = method.getReturnType2();
+				boolean returnsVoid = returnType instanceof PrimitiveType
+						&& ((PrimitiveType) returnType).getPrimitiveTypeCode() == PrimitiveType.VOID;
+				boolean isGetter = name.matches("(is|get)\\p{Lu}.*") //$NON-NLS-1$
+						&& !method.isConstructor() && !returnsVoid && method.parameters().isEmpty()
+						&& statements.size() == 1 && statements.get(0) instanceof ReturnStatement;
+				boolean isSetter = name.matches("set\\p{Lu}.*") //$NON-NLS-1$
+						&& !method.isConstructor() && returnsVoid && method.parameters().size() == 1
+						&& statements.size() == 1 && statements.get(0) instanceof ExpressionStatement
+						&& ((ExpressionStatement) statements.get(0)).getExpression() instanceof Assignment;
+				if (isGetter || isSetter)
+					oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+			}
+		} else if (parent instanceof IfStatement && ((IfStatement) parent).getElseStatement() == null) {
+			oneLineOption = this.options.keep_if_then_body_block_on_one_line;
+			if (this.options.keep_guardian_clause_on_one_line) {
+				boolean isGuardian = statements.size() == 1 && (statements.get(0) instanceof ReturnStatement
+						|| statements.get(0) instanceof ThrowStatement);
+				// guard clause cannot start with a comment: https://bugs.eclipse.org/58565
+				int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
+				isGuardian = isGuardian && !this.tm.get(openBraceIndex + 1).isComment();
+				if (isGuardian)
+					oneLineOption = DefaultCodeFormatterConstants.ONE_LINE_ALWAYS;
+			}
+		} else if (parent instanceof LambdaExpression) {
+			oneLineOption = this.options.keep_lambda_body_block_on_one_line;
+		} else if (parent instanceof ForStatement || parent instanceof EnhancedForStatement
+				|| parent instanceof WhileStatement) {
+			oneLineOption = this.options.keep_loop_body_block_on_one_line;
+		} else if (parent instanceof DoStatement) {
+			oneLineOption = this.options.keep_loop_body_block_on_one_line;
+			int openBraceIndex = this.tm.firstIndexIn(node, TokenNameLBRACE);
+			int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
+			Token whileToken = this.tm.firstTokenAfter(node, TokenNamewhile);
+			int lastIndex = whileToken.getLineBreaksBefore() == 0 ? this.tm.lastIndexIn(parent, -1) : closeBraceIndex;
+			tryKeepOnOneLine(openBraceIndex, closeBraceIndex, lastIndex, statements, oneLineOption);
+			return;
+		} else {
+			oneLineOption = this.options.keep_code_block_on_one_line;
+		}
+		tryKeepOnOneLine(node, null, statements, oneLineOption);
+	}
+
+	@Override
+	public void endVisit(ModuleDeclaration node) {
+		tryKeepOnOneLine(node, node.getName(), node.moduleStatements(), this.options.keep_type_declaration_on_one_line);
+	}
+
+	private void tryKeepOnOneLine(ASTNode node, ASTNode nodeBeforeOpenBrace, List<? extends ASTNode> items,
+			String oneLineOption) {
+		int openBraceIndex = nodeBeforeOpenBrace == null ? this.tm.firstIndexIn(node, TokenNameLBRACE)
+				: this.tm.firstIndexAfter(nodeBeforeOpenBrace, TokenNameLBRACE);
+		int closeBraceIndex = this.tm.lastIndexIn(node, TokenNameRBRACE);
+		tryKeepOnOneLine(openBraceIndex, closeBraceIndex, closeBraceIndex, items, oneLineOption);
+	}
+
+	private void tryKeepOnOneLine(int openBraceIndex, int closeBraceIndex, int lastIndex, List<? extends ASTNode> items,
+			String oneLineOption) {
+		if (DefaultCodeFormatterConstants.ONE_LINE_NEVER.equals(oneLineOption))
+			return;
+		if (DefaultCodeFormatterConstants.ONE_LINE_IF_EMPTY.equals(oneLineOption) && !items.isEmpty())
+			return;
+		if (DefaultCodeFormatterConstants.ONE_LINE_IF_SINGLE_ITEM.equals(oneLineOption) && items.size() > 1)
+			return;
+		if (DefaultCodeFormatterConstants.ONE_LINE_PRESERVE.equals(oneLineOption)
+				&& this.tm.countLineBreaksBetween(this.tm.get(openBraceIndex), this.tm.get(lastIndex)) > 0)
+			return;
+
+		Set<Integer> breakIndexes = items.stream().map(n -> this.tm.firstIndexIn(n, -1)).collect(Collectors.toSet());
+		breakIndexes.add(openBraceIndex + 1);
+		breakIndexes.add(closeBraceIndex);
+		Token prev = this.tm.get(openBraceIndex);
+		int startPos = this.tm.getPositionInLine(openBraceIndex);
+		int pos = startPos + this.tm.getLength(prev, startPos);
+		for (int i = openBraceIndex + 1; i <= lastIndex; i++) {
+			Token token = this.tm.get(i);
+			int preexistingBreaks = this.tm.countLineBreaksBetween(prev, token);
+			if (this.options.number_of_empty_lines_to_preserve > 0 && preexistingBreaks > 1)
+				return; // blank line will be preserved
+			boolean isSpace = prev.isSpaceAfter() || token.isSpaceBefore();
+			if (prev.isComment() || token.isComment()) {
+				if (preexistingBreaks > 0)
+					return; // line break around a comment will be preserved
+				char charBefore = this.tm.charAt(token.originalStart - 1);
+				isSpace = isSpace || charBefore == ' ' || charBefore == '\t';
+			}
+			if (prev.getLineBreaksAfter() > 0 || token.getLineBreaksBefore() > 0) {
+				if (!breakIndexes.contains(i))
+					return; // extra line break within an item, can't remove it
+				isSpace = isSpace || !(i == closeBraceIndex && i == openBraceIndex + 1);
+			}
+			if (isSpace)
+				pos++;
+			pos += this.tm.getLength(token, pos);
+			prev = token;
+		}
+		if (!items.isEmpty()) {
+			if (items.get(0).getParent().getParent() instanceof LambdaExpression)
+				pos -= startPos; // lambda body could be put in a wrapped line, so only check its own width
+			if (pos > this.options.page_width)
+				return; // line width limit exceeded
+		}
+
+		for (Integer i : breakIndexes) {
+			prev = this.tm.get(i - 1);
+			prev.clearLineBreaksAfter();
+			Token token = this.tm.get(i);
+			token.clearLineBreaksBefore();
+			if (!items.isEmpty())
+				token.spaceBefore();
+		}
+	}
+}
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 4de1ca8..45c74ec 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
@@ -579,11 +579,6 @@
 		Statement thenStatement = node.getThenStatement();
 		handleTokenBefore(thenStatement, TokenNameRPAREN, this.options.insert_space_before_closing_paren_in_if, false);
 
-		if (thenStatement instanceof Block && this.tm.isGuardClause((Block) thenStatement)) {
-			handleToken(thenStatement, TokenNameLBRACE, false, true);
-			this.tm.lastTokenIn(node, TokenNameRBRACE).spaceBefore();
-		}
-
 		handleLoopBody(thenStatement);
 		handleSemicolon(thenStatement);
 		return true;
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
index 5783e12..4e42073 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/TokenManager.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2014, 2016 Mateusz Matela and others.
+ * Copyright (c) 2014, 2018 Mateusz Matela and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -15,7 +15,6 @@
 
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_JAVADOC;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameLBRACE;
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameNotAToken;
 import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameStringLiteral;
 
@@ -27,10 +26,6 @@
 import java.util.regex.Pattern;
 
 import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.Block;
-import org.eclipse.jdt.core.dom.IfStatement;
-import org.eclipse.jdt.core.dom.ReturnStatement;
-import org.eclipse.jdt.core.dom.ThrowStatement;
 import org.eclipse.jdt.internal.formatter.Token.WrapMode;
 import org.eclipse.jdt.internal.formatter.linewrap.CommentWrapExecutor;
 
@@ -177,21 +172,6 @@
 		return this.tokens.iterator();
 	}
 
-	public boolean isGuardClause(Block node) {
-		if (node.statements().size() != 1)
-			return false;
-		ASTNode parent = node.getParent();
-		if (!(parent instanceof IfStatement) || ((IfStatement) parent).getElseStatement() != null)
-			return false;
-		Object statement = node.statements().get(0);
-		if (!(statement instanceof ReturnStatement) && !(statement instanceof ThrowStatement))
-			return false;
-		// guard clause cannot start with a comment
-		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=58565
-		int openBraceIndex = firstIndexIn(node, TokenNameLBRACE);
-		return !get(openBraceIndex + 1).isComment();
-	}
-
 	public int firstIndexIn(ASTNode node, int tokenType) {
 		int index = findIndex(node.getStartPosition(), tokenType, true);
 		assert tokenInside(node, index);
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
index 47d3357..011565e 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/Aligner.java
@@ -1,9 +1,12 @@
 /*******************************************************************************
  * Copyright (c) 2014, 2018 Mateusz Matela and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
  * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
  *
  * Contributors:
  *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
@@ -90,7 +93,7 @@
 	}
 
 	public void handleAlign(List<BodyDeclaration> bodyDeclarations) {
-		if (!this.options.align_type_members_on_columns)
+		if (!this.options.align_type_members_on_columns || areKeptOnOneLine(bodyDeclarations))
 			return;
 		List<List<FieldDeclaration>> fieldGroups = toAlignGroups(bodyDeclarations,
 				n -> optionalCast(n, FieldDeclaration.class));
@@ -107,12 +110,18 @@
 
 	public void handleAlign(Block block) {
 		List<Statement> statements = block.statements();
+		if (areKeptOnOneLine(statements))
+			return;
 		if (this.options.align_variable_declarations_on_columns)
 			alignDeclarations(statements);
 		if (this.options.align_assignment_statements_on_columns)
 			alignAssignmentStatements(statements);
 	}
 
+	private boolean areKeptOnOneLine(List<? extends ASTNode> nodes) {
+		return nodes.stream().allMatch(n -> this.tm.firstTokenIn(n, -1).getLineBreaksBefore() == 0);
+	}
+
 	private void alignDeclarations(List<Statement> statements) {
 		List<List<VariableDeclarationStatement>> variableGroups = toAlignGroups(statements,
 				n -> optionalCast(n, VariableDeclarationStatement.class));
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java
deleted file mode 100644
index 4521fbe..0000000
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/FieldAligner.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2014, 2016 Mateusz Matela and others.
- *
- * This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Mateusz Matela <mateusz.matela@gmail.com> - [formatter] Formatter does not format Java code correctly, especially when max line width is set - https://bugs.eclipse.org/303519
- *     Lars Vogel <Lars.Vogel@vogella.com> - Contributions for Bug 473178
- *******************************************************************************/
-package org.eclipse.jdt.internal.formatter.linewrap;
-
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_BLOCK;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameCOMMENT_LINE;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameEQUAL;
-import static org.eclipse.jdt.internal.compiler.parser.TerminalTokens.TokenNameIdentifier;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jdt.core.dom.BodyDeclaration;
-import org.eclipse.jdt.core.dom.FieldDeclaration;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
-import org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions;
-import org.eclipse.jdt.internal.formatter.Token;
-import org.eclipse.jdt.internal.formatter.TokenManager;
-import org.eclipse.jdt.internal.formatter.TokenTraverser;
-
-/** Implementation of the "Align fields on columns" feature */
-public class FieldAligner {
-	private class PositionCounter extends TokenTraverser {
-		int stoppingIndex;
-		int maxPosition;
-
-		public PositionCounter() {
-			// nothing to do
-		}
-
-		@Override
-		protected boolean token(Token token, int index) {
-			if (index == this.stoppingIndex)
-				return false;
-			if (getLineBreaksBefore() > 0)
-				this.counter = FieldAligner.this.tm.getPositionInLine(index);
-			if (token.getAlign() > 0)
-				this.counter = token.getAlign();
-			this.counter += FieldAligner.this.tm.getLength(token, this.counter);
-			if (isSpaceAfter() && getLineBreaksAfter() == 0)
-				this.counter++;
-			this.maxPosition = Math.max(this.maxPosition, this.counter);
-			return true;
-		}
-
-		public int findMaxPosition(int fromIndex, int toIndex) {
-			this.counter = FieldAligner.this.tm.getPositionInLine(fromIndex);
-			this.stoppingIndex = toIndex;
-			this.maxPosition = 0;
-			FieldAligner.this.tm.traverse(fromIndex, this);
-			return this.maxPosition;
-		}
-	}
-
-	private final List<List<FieldDeclaration>> fieldAlignGroups = new ArrayList<>();
-
-	private final DefaultCodeFormatterOptions options;
-
-	final TokenManager tm;
-
-	public FieldAligner(TokenManager tokenManager, DefaultCodeFormatterOptions options) {
-		this.tm = tokenManager;
-		this.options = options;
-	}
-
-	public void handleAlign(List<FieldDeclaration> bodyDeclarations) {
-		if (!this.options.align_type_members_on_columns)
-			return;
-		ArrayList<FieldDeclaration> alignGroup = new ArrayList<>();
-		BodyDeclaration previous = null;
-		for (BodyDeclaration declaration : bodyDeclarations) {
-			if (declaration instanceof FieldDeclaration) {
-				if (isNewGroup(declaration, previous)) {
-					alignFields(alignGroup);
-					alignGroup = new ArrayList<>();
-				}
-				alignGroup.add((FieldDeclaration) declaration);
-			}
-			previous = declaration;
-		}
-		alignFields(alignGroup);
-	}
-
-	private boolean isNewGroup(BodyDeclaration declaration, BodyDeclaration previousDeclaration) {
-		if (!(previousDeclaration instanceof FieldDeclaration))
-			return true;
-		int lineBreaks = 0;
-		int from = this.tm.lastIndexIn(previousDeclaration, -1);
-		int to = this.tm.firstIndexIn(declaration, -1);
-		Token previous = this.tm.get(from);
-		for (int i = from + 1; i <= to; i++) {
-			Token token = this.tm.get(i);
-			lineBreaks += Math.min(this.tm.countLineBreaksBetween(previous, token),
-					this.options.number_of_empty_lines_to_preserve + 1);
-			previous = token;
-		}
-		return lineBreaks > this.options.align_fields_grouping_blank_lines;
-	}
-
-	private void alignFields(ArrayList<FieldDeclaration> alignGroup) {
-		if (alignGroup.size() < 2)
-			return;
-		this.fieldAlignGroups.add(alignGroup);
-
-		int maxNameAlign = 0;
-		for (FieldDeclaration declaration : alignGroup) {
-			List<VariableDeclarationFragment> fragments = declaration.fragments();
-			SimpleName fieldName = fragments.get(0).getName();
-			int nameIndex = this.tm.firstIndexIn(fieldName, TokenNameIdentifier);
-			int positionInLine = this.tm.getPositionInLine(nameIndex);
-			maxNameAlign = Math.max(maxNameAlign, positionInLine);
-		}
-		maxNameAlign = normalizedAlign(maxNameAlign);
-
-		int maxAssignAlign = 0;
-		for (FieldDeclaration declaration : alignGroup) {
-			List<VariableDeclarationFragment> fragments = declaration.fragments();
-			VariableDeclarationFragment fragment = fragments.get(0);
-			int nameIndex = this.tm.firstIndexIn(fragment.getName(), TokenNameIdentifier);
-			Token nameToken = this.tm.get(nameIndex);
-
-			nameToken.setAlign(maxNameAlign);
-
-			if (fragment.getInitializer() != null) {
-				int equalIndex = this.tm.firstIndexAfter(fragment.getName(), TokenNameEQUAL);
-				int positionInLine = this.tm.getPositionInLine(equalIndex);
-				maxAssignAlign = Math.max(maxAssignAlign, positionInLine);
-			}
-		}
-		maxAssignAlign = normalizedAlign(maxAssignAlign);
-
-		for (FieldDeclaration declaration : alignGroup) {
-			List<VariableDeclarationFragment> fragments = declaration.fragments();
-			VariableDeclarationFragment fragment = fragments.get(0);
-			if (fragment.getInitializer() != null) {
-				int assingIndex = this.tm.firstIndexAfter(fragment.getName(), TokenNameEQUAL);
-				Token assignToken = this.tm.get(assingIndex);
-				assignToken.setAlign(maxAssignAlign);
-			}
-		}
-	}
-
-	public void alignComments() {
-		if (this.fieldAlignGroups.isEmpty())
-			return;
-		boolean alignLineComments = !this.options.comment_preserve_white_space_between_code_and_line_comments;
-		PositionCounter positionCounter = new PositionCounter();
-		// align comments after field declarations
-		for (List<FieldDeclaration> alignGroup : this.fieldAlignGroups) {
-			int maxCommentAlign = 0;
-			for (FieldDeclaration declaration : alignGroup) {
-				int typeIndex = this.tm.firstIndexIn(declaration.getType(), -1);
-				int firstIndexInLine = this.tm.findFirstTokenInLine(typeIndex);
-				int lastIndex = this.tm.lastIndexIn(declaration, -1) + 1;
-				maxCommentAlign = Math.max(maxCommentAlign,
-						positionCounter.findMaxPosition(firstIndexInLine, lastIndex));
-			}
-			maxCommentAlign = normalizedAlign(maxCommentAlign);
-
-			for (FieldDeclaration declaration : alignGroup) {
-				int typeIndex = this.tm.firstIndexIn(declaration.getType(), -1);
-				int firstIndexInLine = this.tm.findFirstTokenInLine(typeIndex);
-				int lastIndex = this.tm.lastIndexIn(declaration, -1);
-				lastIndex = Math.min(lastIndex, this.tm.size() - 2);
-				for (int i = firstIndexInLine; i <= lastIndex; i++) {
-					Token token = this.tm.get(i);
-					Token next = this.tm.get(i + 1);
-					boolean lineBreak = token.getLineBreaksAfter() > 0 || next.getLineBreaksBefore() > 0;
-					if (lineBreak) {
-						if (token.tokenType == TokenNameCOMMENT_BLOCK) {
-							token.setAlign(maxCommentAlign);
-						} else if (alignLineComments) {
-							this.tm.addNLSAlignIndex(i, maxCommentAlign);
-						}
-					} else if (next.tokenType == TokenNameCOMMENT_LINE && alignLineComments
-							|| (next.tokenType == TokenNameCOMMENT_BLOCK && i == lastIndex)) {
-						next.setAlign(maxCommentAlign);
-					}
-				}
-			}
-		}
-	}
-
-	private int normalizedAlign(int desiredAlign) {
-		if (this.options.align_with_spaces)
-			return desiredAlign;
-		return this.tm.toIndent(desiredAlign, false);
-	}
-}
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
index c3fe50c..935c5ed 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/linewrap/WrapPreparator.java
@@ -190,10 +190,10 @@
 	 * temporary values used when calling {@link #handleWrap(int)} to avoid ArrayList initialization and long lists of
 	 * parameters
 	 */
-	private List<Integer> wrapIndexes = new ArrayList<Integer>();
+	private List<Integer> wrapIndexes = new ArrayList<>();
 	/** Indexes for wraps that shouldn't happen but should be indented if cannot be removed */
-	private List<Integer> secondaryWrapIndexes = new ArrayList<Integer>();
-	private List<Float> wrapPenalties = new ArrayList<Float>();
+	private List<Integer> secondaryWrapIndexes = new ArrayList<>();
+	private List<Float> wrapPenalties = new ArrayList<>();
 	private int wrapParentIndex = -1;
 	private int wrapGroupEnd = -1;
 
@@ -777,6 +777,23 @@
 	public boolean visit(LambdaExpression node) {
 		if (node.getBody() instanceof Block) {
 			forceContinuousWrapping(node.getBody(), this.tm.firstIndexIn(node, -1));
+
+			List<Statement> statements = ((Block) node.getBody()).statements();
+			if (!statements.isEmpty()) {
+				int openBraceIndex = this.tm.firstIndexBefore(statements.get(0), TokenNameLBRACE);
+				int closeBraceIndex = this.tm.firstIndexAfter(statements.get(statements.size() - 1), TokenNameRBRACE);
+				boolean areKeptOnOneLine = statements.stream()
+						.allMatch(n -> this.tm.firstTokenIn(n, -1).getLineBreaksBefore() == 0);
+				if (areKeptOnOneLine) {
+					for (Statement statement : statements)
+						this.wrapIndexes.add(this.tm.firstIndexIn(statement, -1));
+					this.wrapParentIndex = openBraceIndex;
+					this.wrapGroupEnd = closeBraceIndex;
+					handleWrap(Alignment.M_ONE_PER_LINE_SPLIT, node);
+					this.tm.get(closeBraceIndex).setWrapPolicy(new WrapPolicy(WrapMode.TOP_PRIORITY, openBraceIndex,
+							closeBraceIndex, 0, this.currentDepth, 1, false, false));
+				}
+			}
 		}
 		if (node.hasParentheses()) {
 			List<VariableDeclaration> parameters = node.parameters();
@@ -1071,6 +1088,8 @@
 		} else if (parentNode instanceof DoStatement) {
 			extraIndent = 0;
 			this.wrapParentIndex = this.tm.firstIndexIn(parentNode, -1); // only if !indoentOnColumn
+		} else if (parentNode instanceof LambdaExpression) {
+			extraIndent = 1;
 		} else if ((wrappingOption & Alignment.M_INDENT_BY_ONE) != 0) {
 			extraIndent = 1;
 		} else if (parentNode instanceof ArrayInitializer) {
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 68bdc82..4ab376b 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
@@ -3071,6 +3071,21 @@
 	}
 
 	/**
+	 * Returns whether the given version of Java or Java Runtime is supported 
+	 * by the Java Development Toolkit.
+	 * 
+	 * A true indicates that the given version is supported. For e.g., if the argument
+	 * is <code>11.0.1</code> and {@link #getAllVersions()} contains <code>11</code>, 
+	 * the method returns <code>true</code>.
+	 * 
+	 * @return a boolean indicating support for the given version of Java or Java Runtime.
+	 * @since 3.16
+	 */
+	public static boolean isSupportedJavaVersion(String version) {
+		return CompilerOptions.versionToJdkLevel(version, false) > 0;
+	}
+
+	/**
 	 * Configurable option value: {@value}.
 	 * @since 2.0
 	 * @category OptionValue
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
index d63e36f..277dc1a 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFile.java
@@ -257,7 +257,14 @@
 	// TODO(sxenos): setup the external annotation provider if the IBinaryType came from the index
 	if (root.getKind() == IPackageFragmentRoot.K_BINARY) {
 		JavaProject javaProject = (JavaProject) getAncestor(IJavaElement.JAVA_PROJECT);
-		IClasspathEntry entry = javaProject.getClasspathEntryFor(getPath());
+		IClasspathEntry entry;
+		try {
+			entry = javaProject.getClasspathEntryFor(getPath());
+		} catch (JavaModelException jme) {
+			// Access via cached ClassFile/PF/PFR of a closed project?
+			// Ignore and continue with result undecorated
+			return result;
+		}
 		if (entry != null) {
 			PackageFragment pkg = (PackageFragment) getParent();
 			String entryName = Util.concatWith(pkg.names, getElementName(), '/');
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
index d47c3a2..4bc3712 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java
@@ -92,12 +92,7 @@
 		this.workingCopies = workingCopies;
 		this.nameLookup = project.newNameLookup(workingCopies, excludeTestCode);
 		if (CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_COMPLIANCE, true)) >= ClassFileConstants.JDK9) {
-			for (IPackageFragmentRoot root : project.getPackageFragmentRoots()) {
-				if (root.getModuleDescription() != null) {
-					this.knownModuleLocations = new HashMap<>();
-					break;
-				}
-			}
+			this.knownModuleLocations = new HashMap<>();
 		}
 		if (CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_COMPLIANCE, true)) >= ClassFileConstants.JDK9) {
 			this.moduleUpdater = new ModuleUpdater(project);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
index e28e445..592f193 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathJar.java
@@ -166,6 +166,7 @@
 		}
 	} catch (CoreException e) {
 		// ignore
+		this.zipFilename = ""; //$NON-NLS-1$
 	}
 	this.zipFile = null;
 	this.knownPackageNames = null;