merged BETA_JAVA7 into R3_7_maintenance
diff --git a/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
index eedf8ec..e229edc 100644
--- a/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.text.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Plugin.name
 Bundle-SymbolicName: org.eclipse.jdt.text.tests
-Bundle-Version: 3.7.0.qualifier
+Bundle-Version: 3.7.1.qualifier
 Bundle-ClassPath: jdttexttests.jar
 Bundle-Activator: org.eclipse.jdt.text.tests.JdtTextTestPlugin
 Bundle-ActivationPolicy: lazy
@@ -22,10 +22,10 @@
  org.eclipse.jface.text;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.ui;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.7.1,4.0.0)",
  org.junit;bundle-version="4.8.1",
  org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.7.1,4.0.0)",
  org.eclipse.ui.ide;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.jdt.debug;bundle-version="[3.4.0,4.0.0)",
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JavaHeuristicScannerTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JavaHeuristicScannerTest.java
index e525016..3019af2 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JavaHeuristicScannerTest.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JavaHeuristicScannerTest.java
@@ -870,6 +870,17 @@
 		Assert.assertEquals("\t\t", indent);
 	}
 
+	public void testContinuationIndentationOfForEachStatement2() throws Exception {
+		// Bug 348198
+		fDocument.set("\tfor (int value : values)\n" +
+				"\t\tsum += value;\n" +
+				"\t\t\t\tSystem.out.println(sum);\n" +
+				"\t}");
+
+		String indent= fScanner.computeIndentation(44).toString();
+		Assert.assertEquals("\t", indent);
+	}
+
 	public void testContinuationIndentationOfBooleanExpression() throws Exception {
 		fDocument.set("\tboolean a = true || false;\n" +
 				"\tboolean b = a || false;\n");
@@ -1067,4 +1078,30 @@
 		String indent= fScanner.computeIndentation(29).toString();
 		Assert.assertEquals("\t\t\t", indent);
 	}
+
+	public void testIndentationTryWithResources() throws Exception {
+		String s= "class A {\n" +
+				"	void foo() throws Throwable {\n" +
+				"		try (FileReader reader1 = new FileReader(\"file1\");\n" +
+				"			FileReader reader2 = new FileReader(\"file2\");\n" +
+				"			FileReader reader3 = new FileReader(\"file3\");\n" +
+				"			FileReader reader4 = new FileReader(\"file4\");\n" +
+				"			FileReader reader5 = new FileReader(\"file5\")) {\n" +
+				"			int ch;\n" +
+				"			while ((ch = reader1.read()) != -1) {\n" +
+				"				System.out.println(ch);\n" +
+				"			}\n" +
+				"		}\n" +
+				"	}\n";
+
+		fDocument.set(s);
+
+		int offset= s.indexOf("FileReader reader2");
+		String indent= fScanner.computeIndentation(offset).toString();
+		Assert.assertEquals("\t\t\t", indent);
+
+		offset= s.indexOf("FileReader reader5");
+		indent= fScanner.computeIndentation(offset).toString();
+		Assert.assertEquals("\t\t\t", indent);
+	}
 }
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java
index d2dd742..f39cdfe 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/JdtTextTestSuite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -41,6 +41,7 @@
 		suite.addTest(PropertiesFileAutoEditStrategyTest.suite());
 //		suite.addTest(PartitionTokenScannerTest.suite());
 		suite.addTest(MarkOccurrenceTest.suite());
+		suite.addTest(MarkOccurrenceTest17.suite());
 		suite.addTest(PluginsNotLoadedTest.suite());
 		PluginsNotLoadedTest.addLoadedPlugIns(
 				new String[] {
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/MarkOccurrenceTest17.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/MarkOccurrenceTest17.java
new file mode 100644
index 0000000..cc9631c
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/MarkOccurrenceTest17.java
@@ -0,0 +1,472 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
+import org.eclipse.jdt.internal.ui.search.ExceptionOccurrencesFinder;
+import org.eclipse.jdt.internal.ui.search.IOccurrencesFinder;
+import org.eclipse.jdt.internal.ui.search.IOccurrencesFinder.OccurrenceLocation;
+import org.eclipse.jdt.internal.ui.search.MethodExitsFinder;
+
+/**
+ * Tests the Java Editor's occurrence marking feature.
+ */
+public class MarkOccurrenceTest17 extends TestCase {
+	private static final Class THIS= MarkOccurrenceTest17.class;
+
+	public static Test suite() {
+		return new Java17ProjectTestSetup(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+	private ASTParser fParser;
+
+	private IOccurrencesFinder fFinder;
+
+	private IJavaProject fJProject1;
+
+	private IPackageFragmentRoot fSourceFolder;
+
+	/*
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		fParser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
+
+		fJProject1= Java17ProjectTestSetup.getProject();
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.EDITOR_MARK_OCCURRENCES, true);
+		JavaPlugin.getDefault().getPreferenceStore().setValue(PreferenceConstants.EDITOR_MARK_IMPLEMENTORS, true);
+	}
+
+	/* (non-Javadoc)
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+	private OccurrenceLocation[] getHighlights(StringBuffer source, int offset, int length) throws Exception {
+		CompilationUnit root= createCompilationUnit(source);
+		String errorString= fFinder.initialize(root, offset, length);
+		assertNull(errorString, errorString);
+		return fFinder.getOccurrences();
+	}
+
+	private CompilationUnit createCompilationUnit(StringBuffer source) throws JavaModelException {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", source.toString(), false, null);
+		fParser.setSource(cu);
+		fParser.setResolveBindings(true);
+		return (CompilationUnit)fParser.createAST(null);
+	}
+
+	private void checkSelection(StringBuffer s, int offset, int length, OccurrenceLocation[] expected) throws Exception {
+		OccurrenceLocation[] selectedNodes= getHighlights(s, offset, length);
+		assertEquals("number of selections", expected.length, selectedNodes.length);
+		sortByStartIndex(selectedNodes);
+		sortByStartIndex(expected);
+		for (int i= 0; i < selectedNodes.length; i++) {
+			assertEquals(expected[i].getOffset(), selectedNodes[i].getOffset());
+			assertEquals(expected[i].getLength(), selectedNodes[i].getLength());
+		}
+	}
+
+	private void sortByStartIndex(OccurrenceLocation[] OccurrenceLocations) {
+		Arrays.sort(OccurrenceLocations, new Comparator() {
+			public int compare(Object arg0, Object arg1) {
+				OccurrenceLocation node0= (OccurrenceLocation)arg0;
+				OccurrenceLocation node1= (OccurrenceLocation)arg1;
+				return node0.getOffset() - node1.getOffset();
+			}
+		});
+	}
+
+	//pattern must be found - otherwise it's assumed to be an error
+	private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence) {
+		if (ithOccurrence < 1)
+			throw new IllegalStateException("ithOccurrence = " + ithOccurrence);
+		return find(s, pattern, ithOccurrence, 0);
+	}
+
+	private OccurrenceLocation find(StringBuffer s, String pattern, int ithOccurrence, int startIdx) {
+		if (startIdx < 0 || startIdx > s.length())
+			throw new IllegalStateException("startIdx = " + startIdx);
+		int idx= s.indexOf(pattern, startIdx);
+		if (idx == -1)
+			throw new IllegalStateException("not found \"" + pattern + "\" in \"" + s.substring(startIdx));
+		if (ithOccurrence == 1)
+			return new OccurrenceLocation(idx, pattern.length(), 0, "");
+		return find(s, pattern, ithOccurrence - 1, idx + 1);
+	}
+
+	public void testMarkMethodExits1() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("class A{\n");
+		s.append("   int foo(String s) throws Exception {\n");
+		s.append("      try {\n");
+		s.append("         if (s == null)\n");
+		s.append("            throw new NullPointerException();\n");
+		s.append("         else if (s.length() > 10)\n");
+		s.append("            throw new IllegalArgumentException();\n");
+		s.append("         else\n");
+		s.append("            throw new Exception();\n");
+		s.append("      } catch (NullPointerException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      } catch (IllegalArgumentException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("      return s.length();\n");
+		s.append("   }\n");
+		s.append("}\n");
+		int offset= 1 + s.indexOf("int");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "int", 1), find(s, "throw", 4), find(s, "return s.length();", 1) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits2() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("class A{\n");
+		s.append("   int foo(String s) throws Exception {\n");
+		s.append("      try {\n");
+		s.append("         if (s == null)\n");
+		s.append("            throw new NullPointerException();\n");
+		s.append("         else if (s.length() > 10)\n");
+		s.append("            throw new IllegalArgumentException();\n");
+		s.append("         else\n");
+		s.append("            throw new Exception();\n");
+		s.append("      } catch (NullPointerException | IllegalArgumentException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("      return s.length();\n");
+		s.append("   }\n");
+		s.append("}\n");
+		int offset= 1 + s.indexOf("int");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "int", 1), find(s, "throw", 4), find(s, "return s.length();", 1) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits3() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.BufferedReader;\n");
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.LineNumberReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
+		s.append("            new FileReader(\"somefile\")))) {\n");
+		s.append("         String line;\n");
+		s.append("         while ((line = reader.readLine()) != null) {\n");
+		s.append("            System.out.println(line);\n");
+		s.append("         }\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("void");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "FileReader", 2), find(s, "readLine", 1), find(s, "}", 2), find(s, "}", 3) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits4() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.BufferedReader;\n");
+		s.append("import java.io.FileNotFoundException;\n");
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.LineNumberReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
+		s.append("            new FileReader(\"somefile\")))) {\n");
+		s.append("         String line;\n");
+		s.append("         while ((line = reader.readLine()) != null) {\n");
+		s.append("            System.out.println(line);\n");
+		s.append("         }\n");
+		s.append("      } catch (FileNotFoundException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("void");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "readLine", 1), find(s, "}", 2), find(s, "}", 4) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits5() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.BufferedReader;\n");
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.IOException;\n");
+		s.append("import java.io.LineNumberReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
+		s.append("            new FileReader(\"somefile\")))) {\n");
+		s.append("         String line;\n");
+		s.append("         while ((line = reader.readLine()) != null) {\n");
+		s.append("            System.out.println(line);\n");
+		s.append("         }\n");
+		s.append("      } catch (IOException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("void");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "}", 4) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits6() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.FileReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
+		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
+		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
+		s.append("         int ch;\n");
+		s.append("         while ((ch = reader1.read()) != -1) {\n");
+		s.append("            System.out.println(ch);\n");
+		s.append("         }\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("void");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "void", 1),
+				find(s, "reader1", 1), find(s, "FileReader", 3),
+				find(s, "reader2", 1), find(s, "FileReader", 5),
+				find(s, "reader3", 1), find(s, "FileReader", 7),
+				find(s, "read", 5), find(s, "}", 2), find(s, "}", 3) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testMarkMethodExits7() throws Exception {
+		fFinder= new MethodExitsFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.FileReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (ACloseable closeable = new ACloseable();\n");
+		s.append("               FileReader reader = new FileReader(\"file1\")) {\n");
+		s.append("         int ch;\n");
+		s.append("         while ((ch = reader.read()) != -1) {\n");
+		s.append("            System.out.println(ch);\n");
+		s.append("         }\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+		s.append("class ACloseable implements AutoCloseable {\n");
+		s.append("    @Override\n");
+		s.append("    public void close() { }\n");
+		s.append("}\n");
+		int offset= 1 + s.indexOf("void");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "void", 1), find(s, "reader", 1), find(s, "FileReader", 3), find(s, "read", 3), find(s, "}", 2), find(s, "}", 3) };
+		checkSelection(s, offset, length, ranges);
+	}
+	
+	public void testThrowingException1() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("class A{\n");
+		s.append("   int foo(String s) throws Exception {\n");
+		s.append("      try {\n");
+		s.append("         if (s == null)\n");
+		s.append("            throw new NullPointerException();\n");
+		s.append("         else if (s.length() > 10)\n");
+		s.append("            throw new IllegalArgumentException();\n");
+		s.append("         else\n");
+		s.append("            throw new Exception();\n");
+		s.append("      } catch (NullPointerException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      } catch (IllegalArgumentException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("      return s.length();\n");
+		s.append("   }\n");
+		s.append("}\n");
+		int offset= 1 + s.indexOf("NullPointerException e");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "throw", 2), find(s, "NullPointerException", 2) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testThrowingException2() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("class A{\n");
+		s.append("   int foo(String s) throws Exception {\n");
+		s.append("      try {\n");
+		s.append("         if (s == null)\n");
+		s.append("            throw new NullPointerException();\n");
+		s.append("         else if (s.length() > 10)\n");
+		s.append("            throw new IllegalArgumentException();\n");
+		s.append("         else\n");
+		s.append("            throw new Exception();\n");
+		s.append("      } catch (NullPointerException | IllegalArgumentException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("      return s.length();\n");
+		s.append("   }\n");
+		s.append("}\n");
+		int offset= 1 + s.indexOf("NullPointerException | ");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "throw", 2), find(s, "NullPointerException", 2) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testThrowingException3() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.BufferedReader;\n");
+		s.append("import java.io.FileNotFoundException;\n");
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.LineNumberReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
+		s.append("            new FileReader(\"somefile\")))) {\n");
+		s.append("         String line;\n");
+		s.append("         while ((line = reader.readLine()) != null) {\n");
+		s.append("            System.out.println(line);\n");
+		s.append("         }\n");
+		s.append("      } catch (FileNotFoundException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("FileNotFoundException e");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "FileNotFoundException", 2), find(s, "FileReader", 2) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testThrowingException4() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.BufferedReader;\n");
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.IOException;\n");
+		s.append("import java.io.LineNumberReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (LineNumberReader reader = new LineNumberReader(new BufferedReader(\n");
+		s.append("            new FileReader(\"somefile\")))) {\n");
+		s.append("         String line;\n");
+		s.append("         while ((line = reader.readLine()) != null) {\n");
+		s.append("            System.out.println(line);\n");
+		s.append("         }\n");
+		s.append("      } catch (IOException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("IOException e");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "IOException", 2), find(s, "FileReader", 2), find(s, "readLine", 1), find(s, "}", 2), find(s, "reader", 1) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testThrowingException5() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.FileReader;\n");
+		s.append("import java.io.IOException;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
+		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
+		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
+		s.append("         int ch;\n");
+		s.append("         while ((ch = reader1.read()) != -1) {\n");
+		s.append("            System.out.println(ch);\n");
+		s.append("         }\n");
+		s.append("      } catch (IOException e) {\n");
+		s.append("         e.printStackTrace();\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("IOException e");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "IOException", 2), find(s, "FileReader", 3), find(s, "FileReader", 5), find(s, "FileReader", 7), find(s, "read", 5),
+				find(s, "}", 2), find(s, "reader1", 1), find(s, "reader2", 1), find(s, "reader3", 1) };
+		checkSelection(s, offset, length, ranges);
+	}
+
+	public void testThrowingException6() throws Exception {
+		fFinder= new ExceptionOccurrencesFinder();
+		StringBuffer s= new StringBuffer();
+		s.append("import java.io.FileReader;\n");
+		s.append("class A {\n");
+		s.append("   void foo() throws Throwable {\n");
+		s.append("      try (FileReader reader1 = new FileReader(\"file1\");\n");
+		s.append("      FileReader reader2 = new FileReader(\"file2\");\n");
+		s.append("      FileReader reader3 = new FileReader(\"file3\")) {\n");
+		s.append("         int ch;\n");
+		s.append("         while ((ch = reader1.read()) != -1) {\n");
+		s.append("            System.out.println(ch);\n");
+		s.append("         }\n");
+		s.append("      }\n");
+		s.append("   }\n");
+		s.append("}\n");
+
+		int offset= 1 + s.indexOf("Throwable");//middle of word
+		int length= 0;
+		OccurrenceLocation[] ranges= { find(s, "Throwable", 1),
+				find(s, "reader1", 1), find(s, "FileReader", 3),
+				find(s, "reader2", 1), find(s, "FileReader", 5),
+				find(s, "reader3", 1), find(s, "FileReader", 7),
+				find(s, "read", 5), find(s, "}", 2) };
+		checkSelection(s, offset, length, ranges);
+	}
+}
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/AbstractCompletionTest.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/AbstractCompletionTest.java
index 5c8bbf4..f68581f 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/AbstractCompletionTest.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/AbstractCompletionTest.java
@@ -105,6 +105,10 @@
 		fWaitBeforeCompleting= false;
 	}
 
+	protected IPackageFragment getAnonymousTestPackage() throws CoreException {
+		return CompletionTestSetup.getAnonymousTestPackage();
+	}
+
 	protected void configureCoreOptions(Hashtable options) {
 		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "1");
 		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
@@ -318,7 +322,7 @@
 	}
 
 	private void assertProposal(String selector, StringBuffer contents, IRegion preSelection, StringBuffer result, IRegion expectedSelection) throws CoreException {
-		fCU= createCU(CompletionTestSetup.getAnonymousTestPackage(), contents.toString());
+		fCU= createCU(getAnonymousTestPackage(), contents.toString());
 		fEditor= (JavaEditor) EditorUtility.openInEditor(fCU);
 		IDocument doc;
 		ITextSelection postSelection;
@@ -338,7 +342,7 @@
 	}
 
 	private void assertIncrementalCompletion(StringBuffer contents, IRegion preSelection, StringBuffer result, IRegion expectedSelection) throws CoreException {
-		fCU= createCU(CompletionTestSetup.getAnonymousTestPackage(), contents.toString());
+		fCU= createCU(getAnonymousTestPackage(), contents.toString());
 		fEditor= (JavaEditor) EditorUtility.openInEditor(fCU);
 		IDocument doc;
 		ITextSelection postSelection;
@@ -357,7 +361,7 @@
 	}
 
 	private void assertNoProposal(String selector, StringBuffer contents, IRegion preSelection) throws CoreException {
-		fCU= createCU(CompletionTestSetup.getAnonymousTestPackage(), contents.toString());
+		fCU= createCU(getAnonymousTestPackage(), contents.toString());
 		fEditor= (JavaEditor) EditorUtility.openInEditor(fCU);
 		try {
 			assertNull(findNamedProposal(selector, preSelection));
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistTestSuite.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistTestSuite.java
index c63873d..ea8574f 100644
--- a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistTestSuite.java
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/ContentAssistTestSuite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * Copyright (c) 2005, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -33,6 +33,7 @@
 		suite.addTest(MethodParamsCompletionTest.suite());
 		suite.addTest(MethodParameterGuessingCompletionTest.suite());
 		suite.addTest(TypeCompletionTest.suite());
+		suite.addTest(TypeCompletionTest17.suite());
 		suite.addTest(SpecialMethodsCompletionTest.suite());
 		suite.addTest(CodeCompletionTest.suite());
 		//$JUnit-END$
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/Java17CompletionTestSetup.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/Java17CompletionTestSetup.java
new file mode 100644
index 0000000..bd99f44
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/Java17CompletionTestSetup.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests.contentassist;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+
+class Java17CompletionTestSetup extends Java17ProjectTestSetup {
+
+	public static IPackageFragment getTestPackage() throws CoreException {
+		IJavaProject project= getProject();
+		IPackageFragmentRoot root= project.getPackageFragmentRoot("src");
+		if (!root.exists())
+			root= JavaProjectHelper.addSourceContainer(project, "src");
+
+		IPackageFragment fragment= root.getPackageFragment("test1");
+		if (!fragment.exists())
+			fragment= root.createPackageFragment("test1", false, null);
+
+		return fragment;
+	}
+
+	private static int fAnonymousSoureFolderCounter= 0;
+	public static IPackageFragment getAnonymousTestPackage() throws CoreException {
+		IJavaProject project= getProject();
+		String sourceFolder= "src" + fAnonymousSoureFolderCounter++;
+		IPackageFragmentRoot root= project.getPackageFragmentRoot(sourceFolder);
+		if (!root.exists())
+			root= JavaProjectHelper.addSourceContainer(project, sourceFolder);
+
+		IPackageFragment fragment= root.getPackageFragment("test1");
+		if (!fragment.exists())
+			fragment= root.createPackageFragment("test1", false, null);
+
+		return fragment;
+	}
+
+	public Java17CompletionTestSetup(Test test) {
+		super(test);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/TypeCompletionTest17.java b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/TypeCompletionTest17.java
new file mode 100644
index 0000000..0d7f071
--- /dev/null
+++ b/org.eclipse.jdt.text.tests/src/org/eclipse/jdt/text/tests/contentassist/TypeCompletionTest17.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.text.tests.contentassist;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+
+
+/**
+ * @since 3.7
+ */
+public class TypeCompletionTest17 extends TypeCompletionTest {
+
+	private static final Class THIS= TypeCompletionTest17.class;
+
+	public static Test setUpTest(Test test) {
+		return new Java17CompletionTestSetup(test);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS, suiteName(THIS)));
+	}
+
+	/*
+	 * @see org.eclipse.jdt.text.tests.contentassist.AbstractCompletionTest#setUp()
+	 */
+	protected void setUp() throws Exception {
+		super.setUp();
+		getJDTUIPrefs().setValue(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, true);
+		getJDTUIPrefs().setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, true);
+	}
+
+	protected IPackageFragment getAnonymousTestPackage() throws CoreException {
+		return Java17CompletionTestSetup.getAnonymousTestPackage();
+	}
+
+	public void testGenericParameterGuessingUnambiguos() throws Exception {
+		addImport("java.util.List");
+		expectImport("java.util.ArrayList");
+		expectImport("java.util.List");
+		assertMethodBodyProposal("List<String> list= new A|", "ArrayList()", "List<String> list= new ArrayList<>()|");
+	}
+
+	public void testGenericParameterGuessingExtends() throws Exception {
+		addImport("java.util.List");
+		expectImport("java.util.ArrayList");
+		expectImport("java.util.List");
+		assertMethodBodyProposal("List<? extends Number> list= new A|", "ArrayList()", "List<? extends Number> list= new ArrayList<>()|");
+	}
+
+	public void testGenericParameterGuessingSuper() throws Exception {
+		addImport("java.util.List");
+		expectImport("java.util.ArrayList");
+		expectImport("java.util.List");
+		assertMethodBodyProposal("List<? super Number> list= new A|", "ArrayList()", "List<? super Number> list= new ArrayList<>()|");
+	}
+
+	public void testGenericParameterGuessingMixed() throws Exception {
+		addImport("java.util.Map");
+		expectImport("java.util.HashMap");
+		expectImport("java.util.Map");
+		assertMethodBodyProposal("Map<String, ? extends Number> list= new H|", "HashMap()", "Map<String, ? extends Number> list= new HashMap<>()|");
+	}
+
+	public void testBug182468() throws Exception {
+		IPackageFragmentRoot src= (IPackageFragmentRoot)Java17CompletionTestSetup.getTestPackage().getParent();
+
+		IPackageFragment package1= src.createPackageFragment("package1", true, null);
+		package1.createCompilationUnit("AClass.java", "package " + package1.getElementName() + "; public class AClass {}", true, null);
+
+		IPackageFragment package2= src.createPackageFragment("package2", true, null);
+		package1.createCompilationUnit("AClass.java", "package " + package2.getElementName() + "; public class AClass {}", true, null);
+
+		waitBeforeCompleting(true);
+
+		addImport(package1.getElementName() + ".AClass");
+		expectImport(package1.getElementName() + ".AClass");
+		assertMethodBodyProposal("new AClass|", "AClass() - " + package2.getElementName(), "new " + package2.getElementName() + ".AClass()");
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui.tests.refactoring/META-INF/MANIFEST.MF
index 9f3ad37..e7b624d 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.ui.tests.refactoring/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Plugin.name
 Bundle-SymbolicName: org.eclipse.jdt.ui.tests.refactoring; singleton:=true
-Bundle-Version: 3.7.0.qualifier
+Bundle-Version: 3.7.1.qualifier
 Bundle-ClassPath: refactoringtests.jar
 Bundle-Activator: org.eclipse.jdt.ui.tests.refactoring.infra.RefactoringTestPlugin
 Bundle-ActivationPolicy: lazy
@@ -27,7 +27,7 @@
  org.eclipse.core.runtime,
  org.eclipse.jdt.core,
  org.eclipse.jdt.core.manipulation,
- org.eclipse.jdt.ui;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.7.1,4.0.0)",
  org.eclipse.jdt.ui.tests,
  org.eclipse.jface.text,
  org.eclipse.ltk.core.refactoring,
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/negative17/A_testUnionType_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/negative17/A_testUnionType_in.java
new file mode 100644
index 0000000..9241dcd
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/negative17/A_testUnionType_in.java
@@ -0,0 +1,16 @@
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+public class A_testUnionType_in {
+
+	void foo(int a) {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			ex.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_in.java
new file mode 100644
index 0000000..06241d4
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_in.java
@@ -0,0 +1,14 @@
+import java.io.FileReader;
+import java.io.IOException;
+
+public class A_testTryWithResources_in {
+
+	void foo() throws IOException{
+		try (FileReader reader = new FileReader("file")) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_out.java
new file mode 100644
index 0000000..7f6e2ba
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ChangeTypeRefactoring/positive17/A_testTryWithResources_out.java
@@ -0,0 +1,15 @@
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class A_testTryWithResources_in {
+
+	void foo() throws IOException{
+		try (InputStreamReader reader = new FileReader("file")) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_in.java
new file mode 100644
index 0000000..34e6051
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_in.java
@@ -0,0 +1,7 @@
+//5, 16 -> 5, 17   AllowLoadtime == false
+package p;
+class A {
+	void f() {
+		int i= 0;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_out.java
new file mode 100644
index 0000000..d327be8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/canExtract17/A_test0_out.java
@@ -0,0 +1,9 @@
+//5, 16 -> 5, 17   AllowLoadtime == false
+package p;
+class A {
+	private static final int CONSTANT= 0;
+
+	void f() {
+		int i= CONSTANT;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/cannotExtract17/A_testFail0.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/cannotExtract17/A_testFail0.java
new file mode 100644
index 0000000..aabd581
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractConstant/cannotExtract17/A_testFail0.java
@@ -0,0 +1,17 @@
+//10, 14 -> 10, 56   AllowLoadtime == true
+package p;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A {
+
+	void foo() throws IOException{
+		try (FileReader reader = new FileReader("file")) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.classpath b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.classpath
index 3baf1bd..63c4028 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.classpath
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.classpath
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <classpath>

 	<classpathentry kind="src" path=""/>

-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>

 	<classpathentry kind="output" path="bin"/>

 </classpath>

diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.settings/org.eclipse.jdt.core.prefs
index a70de19..708e506 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.settings/org.eclipse.jdt.core.prefs
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/.settings/org.eclipse.jdt.core.prefs
@@ -1,70 +1,70 @@
-#Fri Nov 19 13:46:34 CET 2004

-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled

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

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

-org.eclipse.jdt.core.compiler.debug.lineNumber=generate

-org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore

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

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

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

-org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled

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

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

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

-org.eclipse.jdt.core.builder.invalidClasspath=abort

-org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch

-org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore

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

-org.eclipse.jdt.core.compiler.debug.localVariable=generate

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

-org.eclipse.jdt.core.compiler.source=1.5

-org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore

-org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore

-org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore

-org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore

-org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve

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

-org.eclipse.jdt.core.compiler.compliance=1.5

-org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore

-org.eclipse.jdt.core.compiler.problem.enumIdentifier=error

-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled

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

-org.eclipse.jdt.core.builder.cleanOutputFolder=clean

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

-org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore

-org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore

-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled

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

-org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore

-org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore

-org.eclipse.jdt.core.classpath.exclusionPatterns=enabled

-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5

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

-org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled

-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public

-org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags

-org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private

-org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore

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

-org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled

-org.eclipse.jdt.core.incompatibleJDKLevel=ignore

-eclipse.preferences.version=1

-org.eclipse.jdt.core.circularClasspath=error

-org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled

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

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

-org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore

-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private

-org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled

-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore

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

-org.eclipse.jdt.core.compiler.debug.sourceFile=generate

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

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

-org.eclipse.jdt.core.incompleteClasspath=error

-org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore

-org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled

-org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled

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

-org.eclipse.jdt.core.builder.duplicateResourceTask=warning

-org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled

+#Mon Jun 20 17:32:45 CEST 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/invalidSelection17/A_test010.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/invalidSelection17/A_test010.java
new file mode 100644
index 0000000..be03681
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/invalidSelection17/A_test010.java
@@ -0,0 +1,16 @@
+package invalidSelection17;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A_test010 {
+
+	void foo() throws IOException{
+		try (/*]*/FileReader reader = new FileReader("file")/*[*/) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test1.java
new file mode 100644
index 0000000..18dde86
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test1.java
@@ -0,0 +1,20 @@
+package try17_in;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+public class A_test1 {
+	public void foo(int a) throws Exception {
+		/*[*/try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+			else
+				throw new IOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			ex.printStackTrace();
+		}/*]*/
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test2.java
new file mode 100644
index 0000000..181eda4
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test2.java
@@ -0,0 +1,17 @@
+package try17_in;
+
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+public class A_test2 {
+	public void foo(int a) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			/*[*/ex.printStackTrace();/*]*/
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test3.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test3.java
new file mode 100644
index 0000000..08af47a
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test3.java
@@ -0,0 +1,15 @@
+package try17_in;
+
+import java.io.FileReader;
+
+public class A_test3 {
+
+	void foo() throws Exception {
+		/*[*/try (FileReader reader1 = new FileReader("file")) {
+			int ch;
+			while ((ch = reader1.read()) != -1) {
+				System.out.println(ch);
+			}
+		}/*]*/
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test4.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test4.java
new file mode 100644
index 0000000..4d42bd6
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test4.java
@@ -0,0 +1,23 @@
+package try17_in;
+
+class Foo4 extends Exception {}
+class Bar4 extends Exception {}
+
+public class A_test4 {
+
+	void foo() throws Exception {
+		/*[*/try (Test4 t = new Test4()) {
+
+		}/*]*/
+	}
+}
+
+class Test4 implements AutoCloseable {
+	Test4() throws Foo4 {
+
+	}
+
+	@Override
+	public void close() throws Bar4 {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test5.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test5.java
new file mode 100644
index 0000000..127d40d
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test5.java
@@ -0,0 +1,19 @@
+package try17_in;
+
+class Foo5 extends Exception {}
+class Bar5 extends Exception {}
+
+public class A_test5 {
+
+	void foo() throws Exception {
+		/*[*/try (Test5 t = new Test5()) {
+
+		}/*]*/
+	}
+}
+
+class Test5 implements AutoCloseable {
+	@Override
+	public void close() throws Bar5 {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test6.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test6.java
new file mode 100644
index 0000000..182e5f6
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test6.java
@@ -0,0 +1,23 @@
+package try17_in;
+
+class Foo6 extends Exception {}
+class Bar6 extends Exception {}
+
+public class A_test6 {
+
+	void foo() throws Exception {
+		/*[*/try (Test6 t = new Test6()) {
+
+		}/*]*/
+	}
+}
+
+class Test6 implements AutoCloseable {
+	Test6() throws Foo6 {
+
+	}
+
+	@Override
+	public void close() {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test7.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test7.java
new file mode 100644
index 0000000..fdd5be0
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_in/A_test7.java
@@ -0,0 +1,16 @@
+package try17_in;
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A_test7 {
+
+	void foo() throws IOException{
+		try (FileReader reader = /*]*/new FileReader("file")/*[*/) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test1.java
new file mode 100644
index 0000000..457fc2a
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test1.java
@@ -0,0 +1,24 @@
+package try17_out;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+public class A_test1 {
+	public void foo(int a) throws Exception {
+		extracted(a);
+	}
+
+	protected void extracted(int a) throws IOException {
+		/*[*/try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+			else
+				throw new IOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			ex.printStackTrace();
+		}/*]*/
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test2.java
new file mode 100644
index 0000000..49c258c
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test2.java
@@ -0,0 +1,22 @@
+package try17_out;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+public class A_test2 {
+	public void foo(int a) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			extracted(ex);
+		}
+	}
+
+	protected void extracted(IOException ex) {
+		/*[*/ex.printStackTrace();/*]*/
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test3.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test3.java
new file mode 100644
index 0000000..96aa100
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test3.java
@@ -0,0 +1,21 @@
+package try17_out;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+public class A_test3 {
+
+	void foo() throws Exception {
+		extracted();
+	}
+
+	protected void extracted() throws IOException, FileNotFoundException {
+		/*[*/try (FileReader reader1 = new FileReader("file")) {
+			int ch;
+			while ((ch = reader1.read()) != -1) {
+				System.out.println(ch);
+			}
+		}/*]*/
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test4.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test4.java
new file mode 100644
index 0000000..6df2798
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test4.java
@@ -0,0 +1,27 @@
+package try17_out;
+
+class Foo4 extends Exception {}
+class Bar4 extends Exception {}
+
+public class A_test4 {
+
+	void foo() throws Exception {
+		extracted();
+	}
+
+	protected void extracted() throws Bar4, Foo4 {
+		/*[*/try (Test4 t = new Test4()) {
+
+		}/*]*/
+	}
+}
+
+class Test4 implements AutoCloseable {
+	Test4() throws Foo4 {
+
+	}
+
+	@Override
+	public void close() throws Bar4 {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test5.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test5.java
new file mode 100644
index 0000000..07f4422
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test5.java
@@ -0,0 +1,23 @@
+package try17_out;
+
+class Foo5 extends Exception {}
+class Bar5 extends Exception {}
+
+public class A_test5 {
+
+	void foo() throws Exception {
+		extracted();
+	}
+
+	protected void extracted() throws Bar5 {
+		/*[*/try (Test5 t = new Test5()) {
+
+		}/*]*/
+	}
+}
+
+class Test5 implements AutoCloseable {
+	@Override
+	public void close() throws Bar5 {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test6.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test6.java
new file mode 100644
index 0000000..46f5685
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test6.java
@@ -0,0 +1,27 @@
+package try17_out;
+
+class Foo6 extends Exception {}
+class Bar6 extends Exception {}
+
+public class A_test6 {
+
+	void foo() throws Exception {
+		extracted();
+	}
+
+	protected void extracted() throws Foo6 {
+		/*[*/try (Test6 t = new Test6()) {
+
+		}/*]*/
+	}
+}
+
+class Test6 implements AutoCloseable {
+	Test6() throws Foo6 {
+
+	}
+
+	@Override
+	public void close() {
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test7.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test7.java
new file mode 100644
index 0000000..45340fc
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractMethodWorkSpace/ExtractMethodTests/try17_out/A_test7.java
@@ -0,0 +1,21 @@
+package try17_out;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+
+class A_test7 {
+
+	void foo() throws IOException{
+		try (FileReader reader = /*]*/extracted()/*[*/) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+
+	protected FileReader extracted() throws FileNotFoundException {
+		return new FileReader("file");
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_in.java
new file mode 100644
index 0000000..20fb7bf
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_in.java
@@ -0,0 +1,17 @@
+package p; //14, 13, 14, 15
+
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+class A {
+	public void foo(int a) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			ex.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_out.java
new file mode 100644
index 0000000..c1730c5
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test110_out.java
@@ -0,0 +1,19 @@
+package p; //14, 13, 14, 15
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+class A {
+	public void foo(int a) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			IOException temp= ex;
+			temp.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_in.java
new file mode 100644
index 0000000..9356ae3
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_in.java
@@ -0,0 +1,10 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		return new ArrayList<>();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_out.java
new file mode 100644
index 0000000..b7c74c5
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test111_out.java
@@ -0,0 +1,11 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		ArrayList<Integer> arrayList= new ArrayList<>();
+		return arrayList;
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_in.java
new file mode 100644
index 0000000..887dad9
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_in.java
@@ -0,0 +1,14 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		return foo(new ArrayList<>());
+	}
+
+	private ArrayList<Integer> foo(ArrayList<Object> arrayList) {
+		return new ArrayList<>();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_out.java
new file mode 100644
index 0000000..69d99d1
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test112_out.java
@@ -0,0 +1,15 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		ArrayList<Object> arrayList= new ArrayList<>();
+		return foo(arrayList);
+	}
+
+	private ArrayList<Integer> foo(ArrayList<Object> arrayList) {
+		return new ArrayList<>();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_in.java
new file mode 100644
index 0000000..887dad9
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_in.java
@@ -0,0 +1,14 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		return foo(new ArrayList<>());
+	}
+
+	private ArrayList<Integer> foo(ArrayList<Object> arrayList) {
+		return new ArrayList<>();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_out.java
new file mode 100644
index 0000000..6db3521
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test113_out.java
@@ -0,0 +1,15 @@
+package p;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Snippet {
+	List<Integer> m() {
+		return foo(new ArrayList<>());
+	}
+
+	private ArrayList<Integer> foo(ArrayList<Object> arrayList) {
+		ArrayList<Integer> arrayList2= new ArrayList<>();
+		return arrayList2;
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_in.java
new file mode 100644
index 0000000..d462906
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_in.java
@@ -0,0 +1,16 @@
+package p; //9, 34, 9, 56
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A {
+
+	void foo() throws IOException{
+		try (FileReader reader = new FileReader("file")) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_out.java
new file mode 100644
index 0000000..e9dc83e
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/canExtract17/A_test114_out.java
@@ -0,0 +1,17 @@
+package p; //9, 34, 9, 56
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A {
+
+	void foo() throws IOException{
+		FileReader fileReader= new FileReader("file");
+		try (FileReader reader = fileReader) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/cannotExtract17/A_testFail1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/cannotExtract17/A_testFail1.java
new file mode 100644
index 0000000..3fd02ce
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/ExtractTemp/cannotExtract17/A_testFail1.java
@@ -0,0 +1,16 @@
+package p; //9, 14, 9, 56
+
+import java.io.FileReader;
+import java.io.IOException;
+
+class A {
+
+	void foo() throws IOException{
+		try (FileReader reader = new FileReader("file")) {
+			int ch;
+			while ((ch = reader.read()) != -1) {
+				System.out.println(ch);
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/in/C.java b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/in/C.java
new file mode 100644
index 0000000..4a1637e
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/in/C.java
@@ -0,0 +1,23 @@
+// 5, 28 -> 5, 33  replaceAll == true, removeDeclaration == false
+package p;
+
+class C<T> {
+	static final C<String> CONST = new C<>(null);
+	
+    T field1;
+    public C(T param){
+        field1 = param;
+    }
+    public static void main(String[] args) {
+        C.testFunction(CONST.getField());
+    }
+    public static void testFunction(String param){
+        System.out.println("S " + param);
+    }
+    public static void testFunction(Object param){
+        System.out.println("O " + param);
+    }
+    public T getField(){
+        return field1;
+    }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/out/C.java b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/out/C.java
new file mode 100644
index 0000000..2217fe8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineConstant/canInline17/test0/out/C.java
@@ -0,0 +1,23 @@
+// 5, 28 -> 5, 33  replaceAll == true, removeDeclaration == false
+package p;
+
+class C<T> {
+	static final C<String> CONST = new C<>(null);
+	
+    T field1;
+    public C(T param){
+        field1 = param;
+    }
+    public static void main(String[] args) {
+        C.testFunction(new C<String>(null).getField());
+    }
+    public static void testFunction(String param){
+        System.out.println("S " + param);
+    }
+    public static void testFunction(Object param){
+        System.out.println("O " + param);
+    }
+    public T getField(){
+        return field1;
+    }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_in.java b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_in.java
new file mode 100644
index 0000000..152c521
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_in.java
@@ -0,0 +1,20 @@
+package p;
+class A<T> {
+    T field1;
+    public A(T param){
+        field1 = param;
+    }
+    public static void main(String[] args) {
+        A<String> temp = new A<>(null);
+        A.testFunction(temp.getField());
+    }
+    public static void testFunction(String param){
+        System.out.println("S " + param);
+    }
+    public static void testFunction(Object param){
+        System.out.println("O " + param);
+    }
+    public T getField(){
+        return field1;
+    }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_out.java b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_out.java
new file mode 100644
index 0000000..cc74ee9
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/InlineTemp/canInline17/A_test0_out.java
@@ -0,0 +1,19 @@
+package p;
+class A<T> {
+    T field1;
+    public A(T param){
+        field1 = param;
+    }
+    public static void main(String[] args) {
+        A.testFunction(new A<String>(null).getField());
+    }
+    public static void testFunction(String param){
+        System.out.println("S " + param);
+    }
+    public static void testFunction(Object param){
+        System.out.println("O " + param);
+    }
+    public T getField(){
+        return field1;
+    }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/in/Foo.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/in/Foo.java
new file mode 100644
index 0000000..a25e478
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/in/Foo.java
@@ -0,0 +1,19 @@
+package p;
+
+public class Foo<T> {
+	
+	// Test qualification with outer type
+	void foo() {
+		
+		Bar bar= new Bar() {
+			{
+				foo(); // <--- invoke here
+			}
+		};
+	}
+	
+}
+
+class Bar {
+	
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/out/Foo.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/out/Foo.java
new file mode 100644
index 0000000..feb3d3c
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_32/out/Foo.java
@@ -0,0 +1,26 @@
+package p;
+
+public class Foo<T> {
+	
+	/**
+	 * @param foo
+	 */
+	public static <T> void foo(Foo<T> foo) {
+		foo.foo();
+	}
+
+	// Test qualification with outer type
+	void foo() {
+		
+		Bar bar= new Bar() {
+			{
+				Foo.foo(Foo.this); // <--- invoke here
+			}
+		};
+	}
+	
+}
+
+class Bar {
+	
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/in/Foo.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/in/Foo.java
new file mode 100644
index 0000000..62a9a22
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/in/Foo.java
@@ -0,0 +1,15 @@
+package p;
+class C {
+}
+
+interface I {
+}
+
+public class Foo<T extends C & I> {
+    
+	<U extends C & I> Foo<U> getX() {
+        return null;
+    }
+
+    Foo<?> f2 = getX();
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/out/Foo.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/out/Foo.java
new file mode 100644
index 0000000..add5788
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_33/out/Foo.java
@@ -0,0 +1,23 @@
+package p;
+class C {
+}
+
+interface I {
+}
+
+public class Foo<T extends C & I> {
+    
+	/**
+	 * @param foo
+	 * @return
+	 */
+	public static <T extends C & I, U extends C & I> Foo<U> getX(Foo<T> foo) {
+		return foo.getX();
+	}
+
+	<U extends C & I> Foo<U> getX() {
+        return null;
+    }
+
+    Foo<?> f2 = Foo.getX(this);
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_34/in/Foo.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_34/in/Foo.java
new file mode 100644
index 0000000..87f2a34
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test17_34/in/Foo.java
@@ -0,0 +1,9 @@
+package p;
+
+import java.lang.invoke.MethodHandle;
+
+public class Foo {
+    void m(MethodHandle mh) throws Throwable {
+    	mh.invoke(1, "abc", null);
+    }
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch1.java
new file mode 100644
index 0000000..95d9756
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch1.java
@@ -0,0 +1,15 @@
+//selection: 12, 13, 12, 15
+//name: fileNotFoundException -> first
+package simple;
+
+import java.io.FileNotFoundException;
+
+public class Catch1 {
+	public void foo() {
+		try {
+			throw new FileNotFoundException();
+		} catch (FileNotFoundException ex) {
+			ex.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch2.java
new file mode 100644
index 0000000..48403bf
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/Catch2.java
@@ -0,0 +1,19 @@
+//selection: 16, 13, 16, 15
+//name: exception -> second
+package simple;
+
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+public class Catch1 {
+	public void foo(int a) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			ex.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch1.java
new file mode 100644
index 0000000..cd3d561
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch1.java
@@ -0,0 +1,15 @@
+//selection: 12, 13, 12, 15
+//name: fileNotFoundException -> first
+package simple.out;
+
+import java.io.FileNotFoundException;
+
+public class Catch1 {
+	public void foo(FileNotFoundException first) {
+		try {
+			throw new FileNotFoundException();
+		} catch (FileNotFoundException ex) {
+			first.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch2.java
new file mode 100644
index 0000000..681215b
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceParameter/simple17/out/Catch2.java
@@ -0,0 +1,20 @@
+//selection: 16, 13, 16, 15
+//name: exception -> second
+package simple.out;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+public class Catch1 {
+	public void foo(int a, IOException second) throws Exception {
+		try {
+			if (a < 10)
+				throw new FileNotFoundException();
+			else if (a < 20)
+				throw new InterruptedIOException();
+		} catch (FileNotFoundException | InterruptedIOException ex) {
+			second.printStackTrace();
+		}
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple1.java
new file mode 100644
index 0000000..dfed628
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple1.java
@@ -0,0 +1,13 @@
+package trycatch17_in;
+
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+class TestSimple1 {
+	void foo(int a) {
+		/*[*/if (a < 10)
+			throw new FileNotFoundException();
+		else
+			throw new InterruptedIOException();/*]*/
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple2.java
new file mode 100644
index 0000000..b204b2b
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_in/TestSimple2.java
@@ -0,0 +1,10 @@
+package trycatch17_in;
+
+import java.io.FileNotFoundException;
+
+class TestSimple2 {
+	void foo(int a) {
+		/*[*/if (a < 10)
+			throw new FileNotFoundException();/*]*/
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple1.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple1.java
new file mode 100644
index 0000000..f51683d
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple1.java
@@ -0,0 +1,16 @@
+package trycatch17_out;
+
+import java.io.FileNotFoundException;
+import java.io.InterruptedIOException;
+
+class TestSimple1 {
+	void foo(int a) {
+		try {
+			/*[*/if (a < 10)
+				throw new FileNotFoundException();
+			else
+				throw new InterruptedIOException();/*]*/
+		} catch (FileNotFoundException | InterruptedIOException e) {
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple2.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple2.java
new file mode 100644
index 0000000..2e1c5e5
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch17_out/TestSimple2.java
@@ -0,0 +1,13 @@
+package trycatch17_out;
+
+import java.io.FileNotFoundException;
+
+class TestSimple2 {
+	void foo(int a) {
+		try {
+			/*[*/if (a < 10)
+				throw new FileNotFoundException();/*]*/
+		} catch (FileNotFoundException e) {
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch_out/TestAlreadyCaught.java b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch_out/TestAlreadyCaught.java
index a55d630..97678bf 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch_out/TestAlreadyCaught.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/SurroundWithWorkSpace/SurroundWithTests/trycatch_out/TestAlreadyCaught.java
@@ -1,4 +1,4 @@
-package trycatch_in;
+package trycatch_out;
 
 import java.io.File;
 import java.net.MalformedURLException;
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
index af4d041..4310a79 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllRefactoringTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -23,17 +23,22 @@
 
 		//--code
 		suite.addTest(ExtractMethodTests.suite());
+		suite.addTest(ExtractMethodTests17.suite());
 		suite.addTest(InlineMethodTests.suite());
 		suite.addTest(ReplaceInvocationsTests.suite());
 		suite.addTest(SefTests.suite());
 		suite.addTest(InlineTempTests.suite());
+		suite.addTest(InlineTempTests17.suite());
 		suite.addTest(ExtractTempTests.suite());
+		suite.addTest(ExtractTempTests17.suite());
 		suite.addTest(RenameTempTests.suite());
 		suite.addTest(ExtractConstantTests.suite());
 		suite.addTest(PromoteTempToFieldTests.suite());
 		suite.addTest(ConvertAnonymousToNestedTests.suite());
 		suite.addTest(InlineConstantTests.suite());
+		suite.addTest(InlineConstantTests17.suite());
 		suite.addTest(IntroduceParameterTests.suite());
+		suite.addTest(IntroduceParameterTests17.suite());
 		suite.addTest(IntroduceFactoryTests.suite());
 
 		//-- structure
@@ -59,11 +64,13 @@
 		suite.addTest(RenameParametersTests.suite());
 		suite.addTest(MoveInstanceMethodTests.suite());
 		suite.addTest(IntroduceIndirectionTests.suite());
+		suite.addTest(IntroduceIndirectionTests17.suite());
 
 		//--types
 		suite.addTest(RenameTypeTests.suite());
 		suite.addTest(RenameTypeParameterTests.suite());
 		suite.addTest(ChangeTypeRefactoringTests.suite());
+		suite.addTest(ChangeTypeRefactoringTests17.suite());
 
 		//--packages
 		suite.addTest(RenamePackageTests.suite());
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
index 0e1e4bc..b6cc18b 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/AllTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -25,6 +25,7 @@
 		suite.addTest(PathTransformationTests.suite());
 		suite.addTest(RefactoringScannerTests.suite());
 		suite.addTest(SurroundWithTests.suite());
+		suite.addTest(SurroundWithTests17.suite());
 		return suite;
 	}
 }
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests.java
index 76d1401..7d7bbeb 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -65,13 +65,13 @@
 		return new RefactoringTestSetup(test);
 	}
 
-	private String getSimpleTestFileName(boolean input) {
+	protected String getSimpleTestFileName(boolean input) {
 		String fileName= "A_" + getName() + (input ? "_in" : "_out") + ".java";
 
 		return fileName;
 	}
 
-	private String getTestFileName(boolean positive, boolean input){
+	protected String getTestFileName(boolean positive, boolean input) {
 		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
 
 		fileName += (positive ? "positive/": "negative/");
@@ -88,7 +88,7 @@
 		return createCU(pack, fileName + ".java", getFileContents(fullName));
 	}
 
-	private ChangeTypeRefactoring helper1(int startLine, int startColumn, int endLine, int endColumn, String selectedTypeName)
+	protected ChangeTypeRefactoring helper1(int startLine, int startColumn, int endLine, int endColumn, String selectedTypeName)
 		throws Exception {
 		ICompilationUnit	cu= createCUfromTestFile(getPackageP(), true, true);
 		ISourceRange		selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
@@ -118,7 +118,7 @@
 		return ref;
 	}
 
-	private void failHelper1(int startLine, int startColumn, int endLine, int endColumn,
+	protected void failHelper1(int startLine, int startColumn, int endLine, int endColumn,
 							 int expectedStatus, String selectedTypeName) throws Exception {
 		ICompilationUnit	cu= createCUfromTestFile(getPackageP(), false, true);
 		ISourceRange		selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests17.java
new file mode 100644
index 0000000..ad3882a
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ChangeTypeRefactoringTests17.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import java.util.Collection;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.testplugin.StringAsserts;
+
+public class ChangeTypeRefactoringTests17 extends ChangeTypeRefactoringTests {
+
+	private static final Class clazz= ChangeTypeRefactoringTests17.class;
+
+	public ChangeTypeRefactoringTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return new Java17Setup(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test someTest) {
+		return new Java17Setup(someTest);
+	}
+
+	@Override
+	protected String getTestFileName(boolean positive, boolean input) {
+		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
+
+		fileName+= (positive ? "positive17/" : "negative17/");
+		fileName += getSimpleTestFileName(input);
+		return fileName;
+	}
+
+	//--- TESTS
+	public void testTryWithResources() throws Exception {
+		Collection types= helper1(7, 25, 7, 31, "java.io.InputStreamReader").getValidTypeNames();
+		String[] actual= (String[])types.toArray(new String[types.size()]);
+		String[] expected= { "java.io.InputStreamReader", "java.io.Reader" };
+		StringAsserts.assertEqualStringsIgnoreOrder(actual, expected);
+	}
+
+	// tests that are supposed to fail
+
+	public void testUnionType() throws Exception {
+		failHelper1(12, 65, 12, 67, 4, "java.lang.Object");
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests.java
index 5153db4..3bcc59a 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests.java
@@ -61,14 +61,14 @@
 		return new RefactoringTestSetup(test);
 	}
 
-	private String getSimpleTestFileName(boolean canInline, boolean input){
+	protected String getSimpleTestFileName(boolean canInline, boolean input) {
 		String fileName = "A_" + getName();
 		if (canInline)
 			fileName += input ? "_in": "_out";
 		return fileName + ".java";
 	}
 
-	private String getTestFileName(boolean canExtract, boolean input){
+	protected String getTestFileName(boolean canExtract, boolean input) {
 		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
 		fileName += (canExtract ? "canExtract/": "cannotExtract/");
 		return fileName + getSimpleTestFileName(canExtract, input);
@@ -139,11 +139,11 @@
 		assertEqualLines(getFileContents(getTestFileName(true, false)), newcu.getSource());
 	}
 
-	private void helper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean allowLoadtime, String constantName, String guessedConstantName) throws Exception{
+	protected void helper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean allowLoadtime, String constantName, String guessedConstantName) throws Exception {
 		helper1(startLine, startColumn, endLine, endColumn, replaceAll, allowLoadtime, false, constantName, guessedConstantName);
 	}
 
-	private void failHelper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean allowLoadtime, String constantName) throws Exception {
+	protected void failHelper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean allowLoadtime, String constantName) throws Exception {
 		failHelper1(startLine, startColumn, endLine, endColumn, replaceAll, allowLoadtime, constantName, 0, false);
 	}
 
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests17.java
new file mode 100644
index 0000000..b999550
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractConstantTests17.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+
+import junit.framework.Test;
+
+public class ExtractConstantTests17 extends ExtractConstantTests {
+
+	private static final Class clazz = ExtractConstantTests17.class;
+
+	public ExtractConstantTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return new Java17Setup(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17Setup(test);
+	}
+
+	@Override
+	protected String getTestFileName(boolean canExtract, boolean input) {
+		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
+		fileName+= (canExtract ? "canExtract17/" : "cannotExtract17/");
+		return fileName + getSimpleTestFileName(canExtract, input);
+	}
+
+	//--- TESTS
+
+	// -- testing failing preconditions
+	public void testFail0() throws Exception{
+		failHelper1(10, 14, 10, 56, true, true, "CONSTANT");
+	}
+}
+
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTestSetup17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTestSetup17.java
new file mode 100644
index 0000000..8449444
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTestSetup17.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+import org.eclipse.ltk.core.refactoring.RefactoringCore;
+
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+public class ExtractMethodTestSetup17 extends Java17Setup {
+
+	private IPackageFragment fTry17Package;
+	private IPackageFragment fInvalidSelectionPackage;
+
+	public ExtractMethodTestSetup17(Test test) {
+		super(test);
+	}
+
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		RefactoringCore.getUndoManager().flush();
+
+		IPackageFragmentRoot root= getDefaultSourceFolder();
+		fTry17Package= root.createPackageFragment("try17_in", true, null);
+		fInvalidSelectionPackage= root.createPackageFragment("invalidSelection17", true, null);
+	}
+
+	public IPackageFragment getTry17Package() {
+		return fTry17Package;
+	}
+
+	public IPackageFragment getInvalidSelectionPackage() {
+		return fInvalidSelectionPackage;
+	}
+}
+
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTests17.java
new file mode 100644
index 0000000..fe9e8d9
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractMethodTests17.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class ExtractMethodTests17 extends ExtractMethodTests {
+	private static ExtractMethodTestSetup17 fgTestSetup;
+
+	public ExtractMethodTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		fgTestSetup= new ExtractMethodTestSetup17(new NoSuperTestsSuite(ExtractMethodTests17.class));
+		return fgTestSetup;
+	}
+
+	public static Test setUpTest(Test test) {
+		fgTestSetup= new ExtractMethodTestSetup17(test);
+		return fgTestSetup;
+	}
+
+	protected void try17Test() throws Exception {
+		performTest(fgTestSetup.getTry17Package(), "A", COMPARE_WITH_OUTPUT, "try17_out");
+	}
+
+	protected void invalidSelectionTest() throws Exception {
+		performTest(fgTestSetup.getInvalidSelectionPackage(), "A", INVALID_SELECTION, null);
+	}
+
+	//====================================================================================
+	// Testing Extracted result
+	//====================================================================================
+
+	//---- Test Try / catch block
+
+	public void test1() throws Exception {
+		try17Test();
+	}
+
+	public void test2() throws Exception {
+		try17Test();
+	}
+
+	public void test3() throws Exception {
+		try17Test();
+	}
+
+	public void test4() throws Exception {
+		try17Test();
+	}
+
+	public void test5() throws Exception {
+		try17Test();
+	}
+
+	public void test6() throws Exception {
+		try17Test();
+	}
+
+	public void test7() throws Exception {
+		try17Test();
+	}
+
+	//=====================================================================================
+	// Testing invalid selections
+	//=====================================================================================
+
+	public void test010() throws Exception {
+		invalidSelectionTest();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests.java
index ad987cf..d4a7649 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests.java
@@ -55,14 +55,14 @@
 		return new RefactoringTestSetup(someTest);
 	}
 
-	private String getSimpleTestFileName(boolean canExtract, boolean input){
+	protected String getSimpleTestFileName(boolean canExtract, boolean input){
 		String fileName = "A_" + getName();
 		if (canExtract)
 			fileName += input ? "_in": "_out";
 		return fileName + ".java";
 	}
 
-	private String getTestFileName(boolean canExtract, boolean input){
+	protected String getTestFileName(boolean canExtract, boolean input){
 		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
 		fileName += canExtract ? "canExtract/": "cannotExtract/";
 		return fileName + getSimpleTestFileName(canExtract, input);
@@ -89,7 +89,7 @@
 		JavaCore.setOptions(options);
 	}
 
-	private void helper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean makeFinal, String tempName, String guessedTempName) throws Exception{
+	protected void helper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean makeFinal, String tempName, String guessedTempName) throws Exception{
 		ICompilationUnit cu= createCUfromTestFile(getPackageP(), true, true);
 		ISourceRange selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
 		ExtractTempRefactoring ref= new ExtractTempRefactoring(cu, selection.getOffset(), selection.getLength());
@@ -141,7 +141,7 @@
 		assertEqualLines(getFileContents(getTestFileName(true, false)), newcu.getSource());
 	}
 
-	private void failHelper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean makeFinal, String tempName, int expectedStatus) throws Exception{
+	protected void failHelper1(int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean makeFinal, String tempName, int expectedStatus) throws Exception {
 		ICompilationUnit cu= createCUfromTestFile(getPackageP(), false, true);
 		ISourceRange selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
 		ExtractTempRefactoring ref= new ExtractTempRefactoring(cu, selection.getOffset(), selection.getLength());
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests17.java
new file mode 100644
index 0000000..79412fc
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/ExtractTempTests17.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+
+public class ExtractTempTests17 extends ExtractTempTests {
+
+	private static final Class clazz= ExtractTempTests17.class;
+
+	public ExtractTempTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return new Java17Setup(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test someTest) {
+		return new Java17Setup(someTest);
+	}
+
+	@Override
+	protected String getTestFileName(boolean canExtract, boolean input){
+		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
+		fileName+= canExtract ? "canExtract17/" : "cannotExtract17/";
+		return fileName + getSimpleTestFileName(canExtract, input);
+	}
+
+	//--- TESTS
+
+	public void test110() throws Exception {
+		helper1(14, 13, 14, 15, true, false, "temp", "ex2");
+	}
+	
+	public void test111() throws Exception {
+		helper1(8, 16, 8, 33, true, false, "arrayList", "arrayList");
+	}
+	
+	public void test112() throws Exception {
+		helper1(8, 20, 8, 37, true, false, "arrayList", "arrayList");
+	}
+	
+	public void test113() throws Exception {
+		helper1(12, 16, 12, 33, true, false, "arrayList2", "arrayList2");
+	}
+
+	public void test114() throws Exception {
+		helper1(9, 34, 9, 56, true, false, "fileReader", "fileReader");
+	}
+
+	// -- testing failing preconditions
+	public void testFail1() throws Exception {
+		failHelper1(9, 14, 9, 56, false, false, "temp", RefactoringStatus.FATAL);
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests.java
index 4b45dd3..ec59186 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests.java
@@ -33,7 +33,7 @@
 	private static final Class clazz = InlineConstantTests.class;
 	private static final String REFACTORING_PATH = "InlineConstant/";
 
-	private boolean toSucceed;
+	protected boolean toSucceed;
 
 	public InlineConstantTests(String name) {
 		super(name);
@@ -43,7 +43,7 @@
 		return REFACTORING_PATH + successPath();
 	}
 
-	private String successPath() {
+	protected String successPath() {
 		return toSucceed ? "/canInline/" : "/cannotInline/";
 	}
 
@@ -81,10 +81,10 @@
 				return i;
 		return -1;
 	}
-	private void helper1(String cuQName, int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean removeDeclaration) throws Exception{
+	protected void helper1(String cuQName, int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean removeDeclaration) throws Exception{
 		helper1(new String[] {cuQName}, cuQName, startLine, startColumn, endLine, endColumn, replaceAll, removeDeclaration);
 	}
-	private void helper1(String[] cuQNames, String selectionCuQName, int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean removeDeclaration) throws Exception{
+	protected void helper1(String[] cuQNames, String selectionCuQName, int startLine, int startColumn, int endLine, int endColumn, boolean replaceAll, boolean removeDeclaration) throws Exception{
 		int selectionCuIndex= firstIndexOf(selectionCuQName, cuQNames);
 		Assert.isTrue(selectionCuIndex != -1, "parameter selectionCuQName must match some String in cuQNames.");
 		helper1(cuQNames, selectionCuIndex, startLine, startColumn, endLine, endColumn, replaceAll, removeDeclaration);
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests17.java
new file mode 100644
index 0000000..8b099a8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineConstantTests17.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class InlineConstantTests17 extends InlineConstantTests {
+	private static final Class clazz = InlineConstantTests17.class;
+
+	public InlineConstantTests17(String name) {
+		super(name);
+	}
+
+	@Override
+	protected String successPath() {
+		return toSucceed ? "/canInline17/" : "/cannotInline17/";
+	}
+
+	public static Test suite() {
+		return new Java17Setup(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test someTest) {
+		return new Java17Setup(someTest);
+	}
+
+
+	//--- TESTS
+
+	public void test0() throws Exception {
+		helper1("p.C", 5, 28, 5, 33, true, false);
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests.java
index 7d41662..6f67ee9 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests.java
@@ -45,14 +45,14 @@
 		return new RefactoringTestSetup(test);
 	}
 
-	private String getSimpleTestFileName(boolean canInline, boolean input){
+	protected String getSimpleTestFileName(boolean canInline, boolean input){
 		String fileName = "A_" + getName();
 		if (canInline)
 			fileName += input ? "_in": "_out";
 		return fileName + ".java";
 	}
 
-	private String getTestFileName(boolean canInline, boolean input){
+	protected String getTestFileName(boolean canInline, boolean input){
 		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
 		fileName += (canInline ? "canInline/": "cannotInline/");
 		return fileName + getSimpleTestFileName(canInline, input);
@@ -83,13 +83,13 @@
 		assertEqualLines("incorrect inlining", getFileContents(getTestFileName(true, false)), newcu.getSource());
 	}
 
-	private void helper1(int startLine, int startColumn, int endLine, int endColumn) throws Exception{
+	protected void helper1(int startLine, int startColumn, int endLine, int endColumn) throws Exception{
 		ICompilationUnit cu= createCUfromTestFile(getPackageP(), true, true);
 		ISourceRange selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
 		helper1(cu, selection);
 	}
 
-	private void helper2() throws Exception{
+	protected void helper2() throws Exception{
 		ICompilationUnit cu= createCUfromTestFile(getPackageP(), false, true);
 		helper2(cu, getSelection(cu));
 	}
@@ -104,7 +104,7 @@
 		}
 	}
 
-	private void helper2(int startLine, int startColumn, int endLine, int endColumn) throws Exception{
+	protected void helper2(int startLine, int startColumn, int endLine, int endColumn) throws Exception{
 		ICompilationUnit cu= createCUfromTestFile(getPackageP(), false, true);
 		ISourceRange selection= TextRangeUtil.getSelection(cu, startLine, startColumn, endLine, endColumn);
 		helper2(cu, selection);
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests17.java
new file mode 100644
index 0000000..25da62a
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/InlineTempTests17.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class InlineTempTests17 extends InlineTempTests {
+
+	private static final Class clazz= InlineTempTests17.class;
+
+	public InlineTempTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return new Java17Setup(new NoSuperTestsSuite(clazz));
+	}
+
+	public static Test setUpTest(Test someTest) {
+		return new Java17Setup(someTest);
+	}
+
+	@Override
+	protected String getTestFileName(boolean canInline, boolean input){
+		String fileName= TEST_PATH_PREFIX + getRefactoringPath();
+		fileName += (canInline ? "canInline17/": "cannotInline17/");
+		return fileName + getSimpleTestFileName(canInline, input);
+	}
+
+	//--- tests
+
+	public void test0() throws Exception{
+		helper1(8, 19, 8, 23);
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
index 3387bbd..a46f735 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
@@ -123,19 +123,19 @@
 		}
 	}
 
-	private void helperPass(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
+	protected void helperPass(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
 		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, false, false, false);
 	}
 
-	private void helperWarn(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
+	protected void helperWarn(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
 		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, false, false);
 	}
 
-	private void helperErr(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
+	protected void helperErr(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
 		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, true, false);
 	}
 
-	private void helperFail(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
+	protected void helperFail(String[] topLevelName, String newName, String target, int startLine, int startColumn, int endLine, int endColumn) throws Exception {
 		helper(topLevelName, newName, target, startLine, startColumn, endLine, endColumn, true, true, true, true);
 	}
 
@@ -304,6 +304,5 @@
 	public void test31() throws Exception {
 		// test for bug 127665
 		helperPass(new String[] { "p.Test" }, "foo", "p.Test0", 13, 20, 13, 23);
-	}
-
+	}	
 }
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests17.java
new file mode 100644
index 0000000..a18a8dd
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests17.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class IntroduceIndirectionTests17 extends IntroduceIndirectionTests{
+	private static final Class clazz= IntroduceIndirectionTests17.class;
+
+	public IntroduceIndirectionTests17(String name) {
+		super(name);
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17Setup(test);
+	}
+
+	public static Test suite() {
+		return setUpTest(new NoSuperTestsSuite(clazz));
+	}
+
+// ---
+	
+	public void test17_32() throws Exception {
+		// test for bug 349405
+		helperPass(new String[] { "p.Foo" }, "foo", "p.Foo", 10, 17, 10, 20);
+	}
+	
+	public void test17_33() throws Exception {
+		// test for bug 349405
+		helperPass(new String[] { "p.Foo" }, "getX", "p.Foo", 14, 17, 14, 21);
+	}
+	
+	public void test17_34() throws Exception {
+		// test for bug 
+		helperFail(new String[] { "p.Foo" }, "m2", "p.Foo", 7, 18, 7, 18);
+	}
+
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests.java
index 779bf1a..02d13d9 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests.java
@@ -67,15 +67,15 @@
 		return result;
 	}
 
-	private void performOK() throws Exception {
+	protected void performOK() throws Exception {
 		perform(RefactoringStatus.OK, RefactoringStatus.OK);
 	}
 
-	private void performInvalidSelection() throws Exception {
+	protected void performInvalidSelection() throws Exception {
 		perform(RefactoringStatus.FATAL, RefactoringStatus.FATAL);
 	}
 
-	private void perform(int expectedActivationStatus, int expectedInputStatus) throws Exception {
+	protected void perform(int expectedActivationStatus, int expectedInputStatus) throws Exception {
 		String packageName= adaptPackage(getName());
 		IPackageFragment packageFragment= RefactoringTestSetup.getDefaultSourceFolder().createPackageFragment(packageName, true , null);
 		ICompilationUnit cu= createCU(packageFragment, getName());
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests17.java
new file mode 100644
index 0000000..8789926
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceParameterTests17.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+public class IntroduceParameterTests17 extends IntroduceParameterTests {
+
+	private static final Class clazz= IntroduceParameterTests17.class;
+
+	public IntroduceParameterTests17(String name) {
+		super(name);
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17Setup(test);
+	}
+
+	public static Test suite() {
+		return setUpTest(new NoSuperTestsSuite(clazz));
+	}
+
+// ---
+
+	public void testSimple17_Catch1() throws Exception {
+		performOK();
+	}
+
+	public void testSimple17_Catch2() throws Exception {
+		performOK();
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/Java17Setup.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/Java17Setup.java
new file mode 100644
index 0000000..e31de9c
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/Java17Setup.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+public class Java17Setup extends RefactoringTestSetup {
+
+	public Java17Setup(Test test) {
+		super(test);
+	}
+
+	/*
+	 * @see org.eclipse.jdt.ui.tests.refactoring.RefactoringTestSetup#addRTJar(org.eclipse.jdt.core.IJavaProject)
+	 */
+	protected IPackageFragmentRoot addRTJar(IJavaProject project) throws CoreException {
+		return JavaProjectHelper.addRTJar17(project);
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/NoSuperTestsSuite.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/NoSuperTestsSuite.java
new file mode 100644
index 0000000..013c862
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/NoSuperTestsSuite.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Test suite that only includes tests from the given test class, but not
+ * tests from super classes.
+ * 
+ * @since 3.7
+ */
+public class NoSuperTestsSuite extends TestSuite {
+	/**
+	 * This implementation creates unnecessary test objects for tests from super classes
+	 * (in {@link junit.framework.TestSuite#addTestMethod}).
+	 * Alternative would have been to copy most of the implementation of TestSuite.
+	 */
+	
+	private static final Class<? extends Test> WARNING_TEST_CLASS= warning(null).getClass();
+
+	public NoSuperTestsSuite(Class<? extends Test> theClass) {
+		super(theClass);
+	}
+	
+	/**
+	 * Adds the given test to this suite, but only if the test was declared in
+	 * the test object's class (and not in a superclass).
+	 */
+	@Override
+	public void addTest(Test test) {
+		if (test instanceof TestCase) {
+			TestCase testCase= (TestCase) test;
+			Class<? extends TestCase> testClass= testCase.getClass();
+			try {
+				testClass.getDeclaredMethod(testCase.getName());
+			} catch (NoSuchMethodException e) {
+				if (testClass != WARNING_TEST_CLASS)
+					return;
+			}
+			super.addTest(test);
+		}
+	}
+	
+	@Override
+	public void addTestSuite(Class<? extends TestCase> testClass) {
+		super.addTest(new NoSuperTestsSuite(testClass));
+	}
+}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTestSetup17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTestSetup17.java
new file mode 100644
index 0000000..db92643
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTestSetup17.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import java.util.Hashtable;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.testplugin.TestOptions;
+
+import org.eclipse.ltk.core.refactoring.RefactoringCore;
+
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.util.CoreUtility;
+
+
+public class SurroundWithTestSetup17 extends TestSetup {
+
+	private IJavaProject fJavaProject;
+	private IPackageFragmentRoot fRoot;
+	private static final String CONTAINER= "src";
+
+	private IPackageFragment fTryCatchPackage;
+
+	public SurroundWithTestSetup17(Test test) {
+		super(test);
+	}
+
+	public IPackageFragmentRoot getRoot() {
+		return fRoot;
+	}
+
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		Hashtable options= TestOptions.getDefaultOptions();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.TAB);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, "0");
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
+		JavaCore.setOptions(options);
+		TestOptions.initializeCodeGenerationOptions();
+		JavaPlugin.getDefault().getCodeTemplateStore().load();
+
+		fJavaProject= JavaProjectHelper.createJavaProject("TestProject17", "bin");
+		JavaProjectHelper.addRTJar17(fJavaProject);
+		fRoot= JavaProjectHelper.addSourceContainer(fJavaProject, CONTAINER);
+
+		RefactoringCore.getUndoManager().flush();
+		CoreUtility.setAutoBuilding(false);
+
+		fTryCatchPackage= getRoot().createPackageFragment("trycatch17_in", true, null);
+		StubUtility.setCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, "", null);
+	}
+
+	protected void tearDown() throws Exception {
+		super.tearDown();
+		JavaProjectHelper.delete(fJavaProject);
+	}
+
+	public IPackageFragment getTryCatchPackage() {
+		return fTryCatchPackage;
+	}
+}
+
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests.java
index afb3f42..139f67e 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -51,13 +51,17 @@
 
 	protected void performTest(IPackageFragment packageFragment, String name, String outputFolder, int mode) throws Exception {
 		ICompilationUnit unit= createCU(packageFragment, name);
-		SurroundWithTryCatchRefactoring refactoring= SurroundWithTryCatchRefactoring.create(unit, getTextSelection());
+		SurroundWithTryCatchRefactoring refactoring= createRefactoring(unit);
 		String out= null;
 		if (mode == COMPARE_WITH_OUTPUT)
 			out= getProofedContent(outputFolder, name);
 		performTest(unit, refactoring, mode, out, true);
 	}
 
+	protected SurroundWithTryCatchRefactoring createRefactoring(ICompilationUnit unit) {
+		return SurroundWithTryCatchRefactoring.create(unit, getTextSelection());
+	}
+
 	protected void tryCatchInvalidTest() throws Exception {
 		performTest(fgTestSetup.getTryCatchPackage(), getName(), "trycatch_out", INVALID_SELECTION);
 	}
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests17.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests17.java
new file mode 100644
index 0000000..5ec9ec0
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/SurroundWithTests17.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.refactoring;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+
+import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryCatchRefactoring;
+
+public class SurroundWithTests17 extends SurroundWithTests {
+
+	private static SurroundWithTestSetup17 fgTestSetup;
+
+	public SurroundWithTests17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		fgTestSetup= new SurroundWithTestSetup17(new NoSuperTestsSuite(SurroundWithTests17.class));
+		return fgTestSetup;
+	}
+
+	public static Test setUpTest(Test someTest) {
+		fgTestSetup= new SurroundWithTestSetup17(someTest);
+		return fgTestSetup;
+	}
+
+	protected IPackageFragmentRoot getRoot() {
+		return fgTestSetup.getRoot();
+	}
+
+	@Override
+	protected SurroundWithTryCatchRefactoring createRefactoring(ICompilationUnit unit) {
+		return SurroundWithTryCatchRefactoring.create(unit, getTextSelection(), true);
+	}
+
+	protected void tryCatchInvalidTest() throws Exception {
+		performTest(fgTestSetup.getTryCatchPackage(), getName(), "trycatch17_out", INVALID_SELECTION);
+	}
+
+	protected void tryCatchTest() throws Exception {
+		performTest(fgTestSetup.getTryCatchPackage(), getName(), "trycatch17_out", COMPARE_WITH_OUTPUT);
+	}
+
+	public void testSimple1() throws Exception {
+		tryCatchTest();
+	}
+
+	public void testSimple2() throws Exception {
+		tryCatchTest();
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF
index ba7e095..993db8c 100644
--- a/org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.ui.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %Plugin.name
 Bundle-SymbolicName: org.eclipse.jdt.ui.tests; singleton:=true
-Bundle-Version: 3.7.0.qualifier
+Bundle-Version: 3.7.1.qualifier
 Bundle-ClassPath: javauitests.jar
 Bundle-Activator: org.eclipse.jdt.testplugin.JavaTestPlugin
 Bundle-ActivationPolicy: lazy
@@ -48,7 +48,7 @@
  org.eclipse.jdt.junit,
  org.eclipse.jdt.junit.runtime,
  org.eclipse.jdt.launching,
- org.eclipse.jdt.ui;bundle-version="[3.7.0,4.0.0)",
+ org.eclipse.jdt.ui;bundle-version="[3.7.1,4.0.0)",
  org.eclipse.jface.text,
  org.eclipse.ltk.core.refactoring,
  org.eclipse.search,
diff --git a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
index a94e699..ee029c3 100644
--- a/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
+++ b/org.eclipse.jdt.ui.tests/test plugin/org/eclipse/jdt/testplugin/JavaProjectHelper.java
@@ -83,6 +83,7 @@
 
 	public static final IPath RT_STUBS_15= new Path("testresources/rtstubs15.jar");
 	public static final IPath RT_STUBS_16= new Path("testresources/rtstubs16.jar");
+	public static final IPath RT_STUBS_17= new Path("testresources/rtstubs17.jar");
 	public static final IPath JUNIT_SRC_381= new Path("testresources/junit381-noUI-src.zip");
 	public static final String JUNIT_SRC_ENCODING= "ISO-8859-1";
 
@@ -183,6 +184,26 @@
 	}
 
 	/**
+	 * Sets the compiler options to 1.7 for the given project.
+	 * @param project the java project
+	 */
+	public static void set17CompilerOptions(IJavaProject project) {
+		Map options= project.getOptions(false);
+		JavaProjectHelper.set17CompilerOptions(options);
+		project.setOptions(options);
+	}
+	
+	/**
+	 * Sets the compiler options to 1.6 for the given project.
+	 * @param project the java project
+	 */
+	public static void set16CompilerOptions(IJavaProject project) {
+		Map options= project.getOptions(false);
+		JavaProjectHelper.set16CompilerOptions(options);
+		project.setOptions(options);
+	}
+	
+	/**
 	 * Sets the compiler options to 1.5 for the given project.
 	 * @param project the java project
 	 */
@@ -203,15 +224,19 @@
 	}
 
 	/**
+	 * Sets the compiler options to 1.7
+	 * @param options The compiler options to configure
+	 */
+	public static void set17CompilerOptions(Map options) {
+		JavaCore.setComplianceOptions(JavaCore.VERSION_1_7, options);
+	}
+	
+	/**
 	 * Sets the compiler options to 1.6
 	 * @param options The compiler options to configure
 	 */
 	public static void set16CompilerOptions(Map options) {
-		options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_6);
-		options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
-		options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
-		options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_6);
-		options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_6);
+		JavaCore.setComplianceOptions(JavaCore.VERSION_1_6, options);
 	}
 
 	/**
@@ -219,11 +244,7 @@
 	 * @param options The compiler options to configure
 	 */
 	public static void set15CompilerOptions(Map options) {
-		options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
-		options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
-		options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.ERROR);
-		options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
-		options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
+		JavaCore.setComplianceOptions(JavaCore.VERSION_1_5, options);
 	}
 
 	/**
@@ -231,11 +252,7 @@
 	 * @param options The compiler options to configure
 	 */
 	public static void set14CompilerOptions(Map options) {
-		options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4);
-		options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
-		options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.WARNING);
-		options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
-		options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2);
+		JavaCore.setComplianceOptions(JavaCore.VERSION_1_4, options);
 	}
 
 	/**
@@ -243,11 +260,7 @@
 	 * @param options The compiler options to configure
 	 */
 	public static void set13CompilerOptions(Map options) {
-		options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_3);
-		options.put(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.WARNING);
-		options.put(JavaCore.COMPILER_PB_ENUM_IDENTIFIER, JavaCore.WARNING);
-		options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3);
-		options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2);
+		JavaCore.setComplianceOptions(JavaCore.VERSION_1_3, options);
 	}
 
 	/**
@@ -603,11 +616,13 @@
 
 	public static IPackageFragmentRoot addRTJar16(IJavaProject jproject) throws CoreException {
 		IPath[] rtJarPath= findRtJar(RT_STUBS_16);
+		set16CompilerOptions(jproject);
+		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
+	}
 
-		Map options= jproject.getOptions(false);
-		JavaProjectHelper.set16CompilerOptions(options);
-		jproject.setOptions(options);
-
+	public static IPackageFragmentRoot addRTJar17(IJavaProject jproject) throws CoreException {
+		IPath[] rtJarPath= findRtJar(RT_STUBS_17);
+		set17CompilerOptions(jproject);
 		return addLibrary(jproject, rtJarPath[0], rtJarPath[1], rtJarPath[2]);
 	}
 
diff --git a/org.eclipse.jdt.ui.tests/testresources/rtstubs17.jar b/org.eclipse.jdt.ui.tests/testresources/rtstubs17.jar
new file mode 100644
index 0000000..9c5c3ac
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/testresources/rtstubs17.jar
Binary files differ
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTests.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTests.java
index bec23e0..0b70edc 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTests.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/CoreTests.java
@@ -45,6 +45,7 @@
 		suite.addTest(HierarchicalASTVisitorTest.suite());
 		suite.addTest(ImportOrganizeTest.suite());
 		suite.addTest(JavaElementLabelsTest.suite());
+		suite.addTest(JavaElementLabelsTest17.suite());
 		suite.addTest(JavaElementPropertyTesterTest.suite());
 		suite.addTest(JavaModelUtilTest.suite());
 		suite.addTest(MethodOverrideTest.suite());
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/Java17ProjectTestSetup.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/Java17ProjectTestSetup.java
new file mode 100644
index 0000000..bfdcd6e
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/Java17ProjectTestSetup.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.core;
+
+import junit.framework.Test;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+
+public class Java17ProjectTestSetup extends ProjectTestSetup {
+
+	public static final String PROJECT_NAME17= "TestSetupProject17";
+
+	public static IJavaProject getProject() {
+		IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(PROJECT_NAME17);
+		return JavaCore.create(project);
+	}
+
+	public static IClasspathEntry[] getDefaultClasspath() throws CoreException {
+		IPath[] rtJarPath= JavaProjectHelper.findRtJar(JavaProjectHelper.RT_STUBS_17);
+		return new IClasspathEntry[] { JavaCore.newLibraryEntry(rtJarPath[0], rtJarPath[1], rtJarPath[2], true) };
+	}
+
+	public Java17ProjectTestSetup(Test test) {
+		super(test);
+	}
+
+	protected boolean projectExists() {
+		return getProject().exists();
+	}
+
+	protected IJavaProject createAndInitializeProject() throws CoreException {
+		IJavaProject javaProject= JavaProjectHelper.createJavaProject(PROJECT_NAME17, "bin");
+		javaProject.setRawClasspath(getDefaultClasspath(), null);
+		JavaProjectHelper.set17CompilerOptions(javaProject);
+		return javaProject;
+	}
+
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest.java
index b50ca5e..f03e08a 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest.java
@@ -15,6 +15,8 @@
 
 import org.eclipse.jdt.testplugin.JavaProjectHelper;
 
+import org.eclipse.core.runtime.CoreException;
+
 import org.eclipse.jface.preference.IPreferenceStore;
 
 import org.eclipse.jdt.core.ICompilationUnit;
@@ -25,6 +27,7 @@
 import org.eclipse.jdt.core.IPackageFragmentRoot;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
 
 import org.eclipse.jdt.ui.JavaElementLabels;
 import org.eclipse.jdt.ui.PreferenceConstants;
@@ -60,6 +63,11 @@
 		JavaProjectHelper.clear(fJProject1, ProjectTestSetup.getDefaultClasspath());
 	}
 
+	private static void assertExpectedLabel(IJavaElement element, String expectedLabel, long flags) {
+		String lab= JavaElementLabels.getTextLabel(element, flags);
+		assertEqualString(lab, expectedLabel);
+	}
+
 	public void testTypeLabelOuter() throws Exception {
 
 		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
@@ -489,9 +497,119 @@
 		}
 	}
 
-	private void assertExpectedLabel(IJavaElement element, String expectedLabel, long flags) {
-		String lab= JavaElementLabels.getTextLabel(element, flags);
-		assertEqualString(lab, expectedLabel);
+	public void testMethodLabelVarargsDeclaration() throws Exception {
+		
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		
+		IPackageFragment pack1= sourceFolder.createPackageFragment("org.test", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package org.test;\n");
+		buf.append("public class Varargs {\n");
+		buf.append("    public void foo(int i, String... varargs) {\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String content= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("Varargs.java", content, false, null);
+
+		IJavaElement elem= cu.getElementAt(content.indexOf("foo"));
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT);
+		assertEqualString(lab, "foo(int, String...)");
+
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES);
+		assertEqualString(lab, "foo(i, varargs)");
+
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "foo(int, String...)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "foo(int i, String... varargs)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "foo(int, String...)");
 	}
 
+	public void testMethodLabelVarargsReference0() throws Exception {
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		
+		IPackageFragment pack1= sourceFolder.createPackageFragment("org.test", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package org.test;\n");
+		buf.append("import java.util.Arrays;\n");
+		buf.append("public class Varargs {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Arrays.asList();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String content= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("Varargs.java", content, false, null);
+		
+		IJavaElement elem= cu.codeSelect(content.indexOf("asList"), 0)[0];
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT);
+		assertEqualString(lab, "asList(T...) <T>");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES);
+		assertEqualString(lab, "asList(arg0)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "asList(T...)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "asList(T... arg0)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "asList(Object...) <Object>");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "asList(Object...)");
+	}
+
+	public void testMethodLabelVarargsReference1() throws Exception {
+		assertMethodLabelVarargsReference("1");
+	}
+	
+	public void testMethodLabelVarargsReference2() throws Exception {
+		assertMethodLabelVarargsReference("1, 2");
+	}
+	
+	public void testMethodLabelVarargsReference3() throws Exception {
+		assertMethodLabelVarargsReference("1, 2, new Integer(3)");
+	}
+	
+	private void assertMethodLabelVarargsReference(String args) throws CoreException, JavaModelException {
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+
+		IPackageFragment pack1= sourceFolder.createPackageFragment("org.test", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package org.test;\n");
+		buf.append("import java.util.Arrays;\n");
+		buf.append("public class Varargs {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Arrays.asList(" + args + ");\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String content= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("Varargs.java", content, false, null);
+
+		IJavaElement elem= cu.codeSelect(content.indexOf("asList"), 0)[0];
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT);
+		assertEqualString(lab, "asList(T...) <T>");
+
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES);
+		assertEqualString(lab, "asList(arg0)");
+
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "asList(T...)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "asList(T... arg0)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "asList(Integer...) <Integer>");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "asList(Integer...)");
+	}
 }
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest17.java
new file mode 100644
index 0000000..cfb8d25
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/JavaElementLabelsTest17.java
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.core;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+
+import org.eclipse.jdt.ui.JavaElementLabels;
+import org.eclipse.jdt.ui.PreferenceConstants;
+
+
+public class JavaElementLabelsTest17 extends CoreTests {
+
+	private static final Class THIS= JavaElementLabelsTest17.class;
+
+	private IJavaProject fJProject1;
+
+	public JavaElementLabelsTest17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+	protected void setUp() throws Exception {
+		fJProject1= Java17ProjectTestSetup.getProject();
+
+		IPreferenceStore store= PreferenceConstants.getPreferenceStore();
+		store.setValue(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES, false);
+	}
+
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+
+	public void testMethodLabelPolymorphicSignatureDeclaration() throws Exception {
+		IType methodHandle= fJProject1.findType("java.lang.invoke.MethodHandle");
+		IMethod invokeExact= methodHandle.getMethod("invokeExact", new String[] {
+				Signature.createArraySignature(Signature.createTypeSignature("java.lang.Object", true), 1)
+		});
+		
+		String lab= JavaElementLabels.getTextLabel(invokeExact, JavaElementLabels.ALL_DEFAULT);
+		assertEqualString(lab, "invokeExact(Object...)");
+	
+		lab= JavaElementLabels.getTextLabel(invokeExact, JavaElementLabels.M_PARAMETER_NAMES);
+		assertEqualString(lab, "invokeExact(arg0)");
+	
+		lab= JavaElementLabels.getTextLabel(invokeExact, JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "invokeExact(Object...)");
+		
+		lab= JavaElementLabels.getTextLabel(invokeExact, JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "invokeExact(Object... arg0)");
+		
+		lab= JavaElementLabels.getTextLabel(invokeExact, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invokeExact(Object...)");
+	}
+
+	private IJavaElement createInvokeReference(String invocation) throws CoreException, JavaModelException {
+		IPackageFragmentRoot sourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+		
+		IPackageFragment pack1= sourceFolder.createPackageFragment("org.test", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package org.test;\n");
+		buf.append("import java.lang.invoke.MethodHandle;\n");
+		buf.append("public class Test {\n");
+		buf.append("    void foo(MethodHandle mh) throws Throwable {\n");
+		buf.append("        " + invocation + ";\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String content= buf.toString();
+		ICompilationUnit cu= pack1.createCompilationUnit("Test.java", content, false, null);
+		
+		IJavaElement elem= cu.codeSelect(content.indexOf("invoke("), 0)[0];
+		return elem;
+	}
+
+	private static void assertInvokeUnresolved(IJavaElement elem) {
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT);
+		assertEqualString(lab, "invoke(Object...)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES);
+		assertEqualString(lab, "invoke(arg0)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES);
+		assertEqualString(lab, "invoke(Object...)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PRE_RETURNTYPE);
+		assertEqualString(lab, "Object invoke(Object... arg0)");
+	}
+
+	public void testMethodLabelPolymorphicSignatureReference0() throws Exception {
+		IJavaElement elem= createInvokeReference("mh.invoke()");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke()");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke()");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke()");
+	}
+
+	public void testMethodLabelPolymorphicSignatureReference0Ret() throws Exception {
+		IJavaElement elem= createInvokeReference("String s= (String) mh.invoke()");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke()");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke()");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke()");
+	}
+	
+	public void testMethodLabelPolymorphicSignatureReference1() throws Exception {
+		IJavaElement elem= createInvokeReference("mh.invoke(1)");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(int)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(int)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke(int arg00)");
+	}
+	
+	public void testMethodLabelPolymorphicSignatureReference1Array() throws Exception {
+		IJavaElement elem= createInvokeReference("mh.invoke(new Object[42])");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(Object[])");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(Object[])");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke(Object[] arg00)");
+	}
+	
+	public void testMethodLabelPolymorphicSignatureReference2() throws Exception {
+		IJavaElement elem= createInvokeReference("mh.invoke('a', new Integer[0][])");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(char, Integer[][])");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(char, Integer[][])");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke(char arg00, Integer[][] arg01)");
+	}
+	
+	public void testMethodLabelPolymorphicSignatureReference3Ret() throws Exception {
+		IJavaElement elem= createInvokeReference("long l= (long) mh.invoke('a', new java.util.ArrayList<String>(), null)");
+		
+		assertInvokeUnresolved(elem);
+		
+		String lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(char, ArrayList, Void)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "invoke(char, ArrayList, Void)");
+		
+		lab= JavaElementLabels.getTextLabel(elem, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES | JavaElementLabels.M_PRE_RETURNTYPE | JavaElementLabels.USE_RESOLVED);
+		assertEqualString(lab, "Object invoke(char arg00, ArrayList arg01, Void arg02)");
+	}
+	
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ProjectTestSetup.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ProjectTestSetup.java
index 258c67c..d6a29f6 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ProjectTestSetup.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/core/ProjectTestSetup.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -62,23 +62,30 @@
 	protected void setUp() throws Exception {
 		super.setUp();
 
-		IJavaProject project= getProject();
-		if (project.exists()) { // allow nesting of ProjectTestSetups
+		if (projectExists()) { // allow nesting of ProjectTestSetups
 			return;
 		}
 
 		fAutobuilding = CoreUtility.setAutoBuilding(false);
 
-		fJProject= JavaProjectHelper.createJavaProject(PROJECT_NAME, "bin");
-		fJProject.setRawClasspath(getDefaultClasspath(), null);
-
-		TestOptions.initializeProjectOptions(fJProject);
+		fJProject= createAndInitializeProject();
 
 		JavaCore.setOptions(TestOptions.getDefaultOptions());
 		TestOptions.initializeCodeGenerationOptions();
 		JavaPlugin.getDefault().getCodeTemplateStore().load();
 	}
 
+	protected boolean projectExists() {
+		return getProject().exists();
+	}
+
+	protected IJavaProject createAndInitializeProject() throws CoreException {
+		IJavaProject javaProject= JavaProjectHelper.createJavaProject(PROJECT_NAME, "bin");
+		javaProject.setRawClasspath(getDefaultClasspath(), null);
+		TestOptions.initializeProjectOptions(javaProject);
+		return javaProject;
+	}
+
 	protected void tearDown() throws Exception {
 		if (fJProject != null) {
 			JavaProjectHelper.delete(fJProject);
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java
index 3b90792..a387d44 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest.java
@@ -2636,6 +2636,43 @@
 		assertExpectedExistInProposals(proposals, new String[] { expected1 });
 	}
 
+	public void testReplaceReturnConditionWithIf4() throws Exception {
+		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=112443
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    List<String> foo(List<String> list) {\n");
+		buf.append("        return list != null ? list : Collections.emptyList();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("?");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    List<String> foo(List<String> list) {\n");
+		buf.append("        if (list != null)\n");
+		buf.append("            return list;\n");
+		buf.append("        else\n");
+		buf.append("            return Collections.emptyList();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
 	public void testReplaceAssignConditionWithIf1() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest17.java
new file mode 100644
index 0000000..5558da8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AdvancedQuickAssistTest17.java
@@ -0,0 +1,255 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import java.util.Hashtable;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.testplugin.TestOptions;
+
+import org.eclipse.core.runtime.Preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
+
+public class AdvancedQuickAssistTest17 extends QuickFixTest {
+
+	private static final Class THIS= AdvancedQuickAssistTest17.class;
+
+	private IJavaProject fJProject1;
+
+	private IPackageFragmentRoot fSourceFolder;
+
+	public AdvancedQuickAssistTest17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+
+	protected void setUp() throws Exception {
+		Hashtable options= TestOptions.getDefaultOptions();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
+
+		JavaCore.setOptions(options);
+
+		IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
+		store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false);
+		store.setValue(PreferenceConstants.CODEGEN_KEYWORD_THIS, false);
+
+		StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "//TODO\n${body_statement}", null);
+
+		Preferences corePrefs= JavaPlugin.getJavaCorePluginPreferences();
+		corePrefs.setValue(JavaCore.CODEASSIST_FIELD_PREFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_FIELD_SUFFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, "");
+
+		fJProject1= Java17ProjectTestSetup.getProject();
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+	}
+
+
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+	public void testConvertSwitchToIf() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo(String s) {\n");
+		buf.append("        switch (s) {\n");
+		buf.append("        case \"abc\":\n");
+		buf.append("            System.out.println();\n");
+		buf.append("            break;\n");
+		buf.append("        case \"xyz\":\n");
+		buf.append("            System.out.println();\n");
+		buf.append("            break;\n");
+		buf.append("        default:\n");
+		buf.append("            System.out.println();\n");
+		buf.append("            break;\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("switch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo(String s) {\n");
+		buf.append("        if (\"abc\".equals(s)) {\n");
+		buf.append("            System.out.println();\n");
+		buf.append("        } else if (\"xyz\".equals(s)) {\n");
+		buf.append("            System.out.println();\n");
+		buf.append("        } else {\n");
+		buf.append("            System.out.println();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testReplaceReturnConditionWithIf4() throws Exception {
+		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=112443
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    List<String> foo(int a) {\n");
+		buf.append("        return a > 0 ? new ArrayList<>() : new ArrayList<>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("?");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    List<String> foo(int a) {\n");
+		buf.append("        if (a > 0)\n");
+		buf.append("            return new ArrayList<>();\n");
+		buf.append("        else\n");
+		buf.append("            return new ArrayList<>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+	
+	public void testReplaceReturnIfWithCondition3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public List<String> foo(int a) {\n");
+		buf.append("        if (a > 0) {\n");
+		buf.append("            return new ArrayList<>();\n");
+		buf.append("        } else {\n");
+		buf.append("            return new ArrayList<>();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("if");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public List<String> foo(int a) {\n");
+		buf.append("        return a > 0 ? new ArrayList<String>() : new ArrayList<String>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] {expected1});
+	}
+	
+	public void testReplaceReturnIfWithCondition4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    public Map<String, java.io.IOException> foo(int a) {\n");
+		buf.append("        if (a > 0) {\n");
+		buf.append("            return Collections.emptyMap();\n");
+		buf.append("        } else {\n");
+		buf.append("            return Collections.singletonMap(\"none\", null);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+		
+		int offset= buf.toString().indexOf("if");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+		
+		assertCorrectLabels(proposals);
+		
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.util.Collections;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    public Map<String, java.io.IOException> foo(int a) {\n");
+		buf.append("        return a > 0 ? Collections.<String, IOException>emptyMap() : Collections.<String, IOException>singletonMap(\"none\", null);\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		
+		String expected1= buf.toString();
+		
+		assertExpectedExistInProposals(proposals, new String[] {expected1});
+	}
+	
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest17.java
new file mode 100644
index 0000000..385caac
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest17.java
@@ -0,0 +1,964 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import java.util.Hashtable;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.testplugin.TestOptions;
+
+import org.eclipse.core.runtime.Preferences;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.text.correction.AssistContext;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal;
+
+public class AssistQuickFixTest17 extends QuickFixTest {
+
+	private static final String REMOVE_CATCH_CLAUSE= "Remove catch clause";
+	private static final String REPLACE_CATCH_CLAUSE_WITH_THROWS= "Replace catch clause with throws";
+	private static final String REMOVE_SURROUNDING_TRY_BLOCK= "Remove surrounding 'try' block";
+	private static final String CONVERT_TO_A_SINGLE_MULTI_CATCH_BLOCK= "Combine catch blocks";
+	private static final String CONVERT_TO_SEPARATE_CATCH_BLOCKS= "Use separate catch blocks";
+
+	private static final Class THIS= AssistQuickFixTest17.class;
+
+	private IJavaProject fJProject1;
+
+	private IPackageFragmentRoot fSourceFolder;
+
+	public AssistQuickFixTest17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+	protected void setUp() throws Exception {
+		Hashtable options= TestOptions.getDefaultOptions();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
+
+		JavaCore.setOptions(options);
+
+		IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
+		store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false);
+		store.setValue(PreferenceConstants.CODEGEN_KEYWORD_THIS, false);
+
+		StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "//TODO\n${body_statement}", null);
+
+		Preferences corePrefs= JavaPlugin.getJavaCorePluginPreferences();
+		corePrefs.setValue(JavaCore.CODEASSIST_FIELD_PREFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_STATIC_FIELD_PREFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_FIELD_SUFFIXES, "");
+		corePrefs.setValue(JavaCore.CODEASSIST_STATIC_FIELD_SUFFIXES, "");
+
+		fJProject1= Java17ProjectTestSetup.getProject();
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+	}
+
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+	public void testConvertToMultiCatch1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testConvertToMultiCatch2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+
+	}
+
+	public void testConvertToMultiCatch3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (RuntimeException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("        // a comment at the end\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException | RuntimeException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("        // a comment at the end\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testConvertToMultiCatch4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("            \n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertProposalDoesNotExist(proposals, CONVERT_TO_A_SINGLE_MULTI_CATCH_BLOCK);
+	}
+
+	public void testConvertToMultiCatch5() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertProposalDoesNotExist(proposals, CONVERT_TO_A_SINGLE_MULTI_CATCH_BLOCK);
+	}
+
+	public void testConvertToMultiCatch6() throws Exception {
+		//Quick assist should not be offered in 1.5 mode
+		JavaProjectHelper.set15CompilerOptions(fJProject1);
+		try {
+			IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+			StringBuffer buf= new StringBuffer();
+			buf.append("package test1;\n");
+			buf.append("public class E {\n");
+			buf.append("    void foo() {\n");
+			buf.append("        try {\n");
+			buf.append("            System.out.println(\"foo\");\n");
+			buf.append("        } catch (IllegalArgumentException e) {\n");
+			buf.append("            e.printStackTrace();\n");
+			buf.append("        } catch (NullPointerException e) {\n");
+			buf.append("            e.printStackTrace();\n");
+			buf.append("        }\n");
+			buf.append("    }\n");
+			buf.append("}\n");
+			ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+			int offset= buf.toString().indexOf("catch");
+			AssistContext context= getCorrectionContext(cu, offset, 0);
+			assertNoErrors(context);
+			List proposals= collectAssists(context, false);
+
+			assertProposalDoesNotExist(proposals, CONVERT_TO_A_SINGLE_MULTI_CATCH_BLOCK);
+		} finally {
+			JavaProjectHelper.set17CompilerOptions(fJProject1);
+		}
+	}
+
+	public void testUnrollMultiCatch1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testUnrollMultiCatch2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (RuntimeException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (RuntimeException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testUnrollMultiCatch3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException | ClassCastException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch (NullPointerException");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (ClassCastException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testUnrollMultiCatch4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException | ClassCastException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (ArrayIndexOutOfBoundsException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch (NullPointerException");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (ClassCastException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (ArrayIndexOutOfBoundsException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testUnrollMultiCatch5() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		assertNoErrors(context);
+		List proposals= collectAssists(context, false);
+
+		assertProposalDoesNotExist(proposals, CONVERT_TO_SEPARATE_CATCH_BLOCKS);
+	}
+
+	public void testReplaceMultiCatchClauseWithThrows1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            goo();\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("catch");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 4);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws IllegalArgumentException, NullPointerException {\n");
+		buf.append("        goo();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        goo();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2 });
+	}
+
+	public void testReplaceMultiCatchClauseWithThrows2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            System.out.println(\"foo\");\n");
+		buf.append("        } catch (Outer<String>.Inner | NullPointerException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Outer<E> {\n");
+		buf.append("    class Inner extends IllegalArgumentException { }\n"); // yes, that's a compile error
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("Inner");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 2);
+		assertProposalDoesNotExist(proposals, REMOVE_CATCH_CLAUSE);
+		assertProposalDoesNotExist(proposals, REPLACE_CATCH_CLAUSE_WITH_THROWS);
+	}
+
+	public void testReplaceMultiCatchClauseWithThrows3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            goo();\n");
+		buf.append("        } catch (IllegalArgumentException | NullPointerException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("IllegalArgumentException");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 4);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            goo();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws IllegalArgumentException {\n");
+		buf.append("        try {\n");
+		buf.append("            goo();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            goo();\n");
+		buf.append("        } catch (NullPointerException e) {\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2, expected3 });
+	}
+	
+	public void testReplaceMultiCatchClauseWithThrows4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		int offset= buf.toString().indexOf("IllegalArgumentException");
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 4);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | InvocationTargetException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws IllegalArgumentException {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | InvocationTargetException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | InvocationTargetException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testPickoutTypeFromMulticatch1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		String string= "IllegalArgumentException | InvocationTargetException";
+		int offset= buf.toString().indexOf(string);
+		int length= string.length();
+		AssistContext context= getCorrectionContext(cu, offset, length);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 5);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        String.class.getConstructor().newInstance();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {\n");
+		buf.append("        String.class.getConstructor().newInstance();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (IllegalArgumentException | InvocationTargetException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+		
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (IllegalAccessException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (InvocationTargetException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (NoSuchMethodException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected4= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2, expected3, expected4 });
+	}
+
+	public void testPickoutTypeFromMulticatch2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | java.lang.NoSuchMethodException | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		String string= "MethodException";
+		int offset= buf.toString().indexOf(string);
+		AssistContext context= getCorrectionContext(cu, offset, 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 4);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws java.lang.NoSuchMethodException {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.lang.reflect.InvocationTargetException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            String.class.getConstructor().newInstance();\n");
+		buf.append("        } catch (InstantiationException | IllegalAccessException\n");
+		buf.append("                | IllegalArgumentException | InvocationTargetException\n");
+		buf.append("                | SecurityException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        } catch (java.lang.NoSuchMethodException e) {\n");
+		buf.append("            e.printStackTrace();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testSplitDeclaration1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws Exception {\n");
+		buf.append("        try (FileReader reader = new FileReader(\"file\")) {\n");
+		buf.append("            int ch;\n");
+		buf.append("            while ((ch = reader.read()) != -1) {\n");
+		buf.append("                System.out.println(ch);\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		String str= "reader";
+		AssistContext context= getCorrectionContext(cu, buf.toString().indexOf(str), 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		assertProposalDoesNotExist(proposals, "Split variable declaration");
+	}
+
+	public void testUnwrapTryStatement() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileReader;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws Exception {\n");
+		buf.append("        try (FileReader reader1 = new FileReader(\"file\")) {\n");
+		buf.append("            int ch;\n");
+		buf.append("            while ((ch = reader1.read()) != -1) {\n");
+		buf.append("                System.out.println(ch);\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		String str= "try";
+		AssistContext context= getCorrectionContext(cu, buf.toString().indexOf(str) + str.length(), 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 1);
+		assertProposalDoesNotExist(proposals, REMOVE_SURROUNDING_TRY_BLOCK);
+	}
+
+	public void testInferDiamondArguments() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        Map<String, ? extends Number> m = new HashMap<>(12);\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		String str= "<>";
+		AssistContext context= getCorrectionContext(cu, buf.toString().indexOf(str), 0);
+		List proposals= collectAssists(context, false);
+
+		assertNumberOfProposals(proposals, 1);
+		assertCorrectLabels(proposals);
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal) proposals.get(0);
+		String preview= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        Map<String, ? extends Number> m = new HashMap<String, Number>(12);\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		assertEqualString(preview, buf.toString());
+	}
+
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
index 7e116f6..2391d17 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest.java
@@ -1064,6 +1064,153 @@
 		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
 	}
 
+	public void testUncaughtException4() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public E goo(int i) throws InterruptedIOException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    public E bar() throws FileNotFoundException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    /**\n");
+		buf.append("     * Not much to say here.\n");
+		buf.append("     */\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        goo(1).bar();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 2);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public E goo(int i) throws InterruptedIOException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    public E bar() throws FileNotFoundException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    /**\n");
+		buf.append("     * Not much to say here.\n");
+		buf.append("     * @throws InterruptedIOException \n");
+		buf.append("     * @throws FileNotFoundException \n");
+		buf.append("     */\n");
+		buf.append("    public void foo() throws FileNotFoundException, InterruptedIOException {\n");
+		buf.append("        goo(1).bar();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public E goo(int i) throws InterruptedIOException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    public E bar() throws FileNotFoundException {\n");
+		buf.append("        return new E();\n");
+		buf.append("    }\n");
+		buf.append("    /**\n");
+		buf.append("     * Not much to say here.\n");
+		buf.append("     */\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            goo(1).bar();\n");
+		buf.append("        } catch (FileNotFoundException e) {\n");
+		buf.append("        } catch (InterruptedIOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+	}
+
+	public void testUncaughtException5() throws Exception {
+		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=31554
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new IOException();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("            throw new IOException();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws IOException {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new IOException();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("            throw new IOException();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new IOException();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("            try {\n");
+		buf.append("                throw new IOException();\n");
+		buf.append("            } catch (IOException e1) {\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+	}
+
 	public void testUncaughtExceptionImportConflict() throws Exception {
 		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
 		StringBuffer buf= new StringBuffer();
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest17.java
new file mode 100644
index 0000000..f483131
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/LocalCorrectionsQuickFixTest17.java
@@ -0,0 +1,1010 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.testplugin.TestOptions;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.CUCorrectionProposal;
+
+public class LocalCorrectionsQuickFixTest17 extends QuickFixTest {
+
+	private static final Class THIS= LocalCorrectionsQuickFixTest17.class;
+
+	private IJavaProject fJProject1;
+
+	private IPackageFragmentRoot fSourceFolder;
+
+
+	public LocalCorrectionsQuickFixTest17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+
+	protected void setUp() throws Exception {
+		Hashtable options= TestOptions.getDefaultOptions();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
+		options.put(DefaultCodeFormatterConstants.FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE, String.valueOf(99));
+		options.put(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER, JavaCore.ERROR);
+		options.put(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION, JavaCore.IGNORE);
+		options.put(JavaCore.COMPILER_PB_MISSING_HASHCODE_METHOD, JavaCore.WARNING);
+		options.put(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS, JavaCore.WARNING);
+
+		JavaCore.setOptions(options);
+
+		IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
+		store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false);
+
+		StubUtility.setCodeTemplate(CodeTemplateContextType.CATCHBLOCK_ID, "", null);
+		StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORSTUB_ID, "", null);
+		StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "", null);
+
+		fJProject1= Java17ProjectTestSetup.getProject();
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+	}
+
+
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+	public void testUncaughtExceptionUnionType() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo(int a) {\n");
+		buf.append("        try {\n");
+		buf.append("            if (a < 10)\n");
+		buf.append("                throw new FileNotFoundException();\n");
+		buf.append("            else if (a < 20)\n");
+		buf.append("                throw new InterruptedIOException();\n");
+		buf.append("            else\n");
+		buf.append("                throw new IOException();\n");
+		buf.append("        } catch (FileNotFoundException | InterruptedIOException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } \n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 4);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo(int a) throws IOException {\n");
+		buf.append("        try {\n");
+		buf.append("            if (a < 10)\n");
+		buf.append("                throw new FileNotFoundException();\n");
+		buf.append("            else if (a < 20)\n");
+		buf.append("                throw new InterruptedIOException();\n");
+		buf.append("            else\n");
+		buf.append("                throw new IOException();\n");
+		buf.append("        } catch (FileNotFoundException | InterruptedIOException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } \n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo(int a) {\n");
+		buf.append("        try {\n");
+		buf.append("            if (a < 10)\n");
+		buf.append("                throw new FileNotFoundException();\n");
+		buf.append("            else if (a < 20)\n");
+		buf.append("                throw new InterruptedIOException();\n");
+		buf.append("            else\n");
+		buf.append("                throw new IOException();\n");
+		buf.append("        } catch (FileNotFoundException | InterruptedIOException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("        } \n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("import java.io.InterruptedIOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo(int a) {\n");
+		buf.append("        try {\n");
+		buf.append("            if (a < 10)\n");
+		buf.append("                throw new FileNotFoundException();\n");
+		buf.append("            else if (a < 20)\n");
+		buf.append("                throw new InterruptedIOException();\n");
+		buf.append("            else\n");
+		buf.append("                throw new IOException();\n");
+		buf.append("        } catch (FileNotFoundException | InterruptedIOException | IOException ex) {\n");
+		buf.append("            ex.printStackTrace();\n");
+		buf.append("        } \n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertExpectedExistInProposals(proposals, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testUncaughtExceptionTryWithResources1() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 3, 0); //quick fix on 1st problem
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws FileNotFoundException, IOException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (FileNotFoundException e) {\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(2);
+		String preview3= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (FileNotFoundException | IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testUncaughtExceptionTryWithResources2() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 3, 1); //quick fix on 2nd problem
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws FileNotFoundException, IOException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (FileNotFoundException e) {\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(2);
+		String preview3= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (FileNotFoundException | IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testUncaughtExceptionTryWithResources3() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 3, 2); //quick fix on 3rd problem
+		assertNumberOfProposals(proposals, 5);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws IllegalArgumentException, MyException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (IllegalArgumentException e) {\n");
+		buf.append("        } catch (MyException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(2);
+		String preview3= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar(1);\n");
+		buf.append("        } catch (IllegalArgumentException | MyException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(3);
+		String preview4= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            try {\n");
+		buf.append("                bar(1);\n");
+		buf.append("            } catch (IllegalArgumentException e) {\n");
+		buf.append("            } catch (MyException e) {\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected4= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(4);
+		String preview5= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar(int n) throws IllegalArgumentException, MyException {\n");
+		buf.append("        if (n == 1)\n");
+		buf.append("            throw new IllegalArgumentException();\n");
+		buf.append("        else\n");
+		buf.append("            throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            try {\n");
+		buf.append("                bar(1);\n");
+		buf.append("            } catch (IllegalArgumentException | MyException e) {\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected5= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3, preview4, preview5 }, new String[] { expected1, expected2, expected3, expected4, expected5 });
+	}
+
+	public void testUncaughtExceptionTryWithResources4() throws Exception {
+		//https://bugs.eclipse.org/bugs/show_bug.cgi?id=351464
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar() throws MyException {\n");
+		buf.append("        throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws IOException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar() throws MyException {\n");
+		buf.append("        throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws IOException, MyException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar();\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar() throws MyException {\n");
+		buf.append("        throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws IOException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            bar();\n");
+		buf.append("        } catch (MyException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(2);
+		String preview3= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileInputStream;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void bar() throws MyException {\n");
+		buf.append("        throw new MyException();\n");
+		buf.append("    }\n");
+		buf.append("    void foo(String name, boolean b) throws IOException {\n");
+		buf.append("        try (FileInputStream fis = new FileInputStream(name)) {\n");
+		buf.append("            try {\n");
+		buf.append("                bar();\n");
+		buf.append("            } catch (MyException e) {\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected3= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2, preview3 }, new String[] { expected1, expected2, expected3 });
+	}
+
+	public void testUnneededCaughtException1() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (FileNotFoundException | IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws FileNotFoundException {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+	}
+
+	public void testUnneededCaughtException2() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (java.io.FileNotFoundException | java.io.IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (java.io.IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileNotFoundException;\n");
+		buf.append("import java.io.IOException;\n");
+		buf.append("public class E {\n");
+		buf.append("    public void foo() throws java.io.FileNotFoundException {\n");
+		buf.append("        try {\n");
+		buf.append("            throw new FileNotFoundException();\n");
+		buf.append("        } catch (java.io.IOException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+	}
+
+	public void testUnneededCatchBlockTryWithResources() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileReader;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws Exception {\n");
+		buf.append("        try (FileReader reader1 = new FileReader(\"file\")) {\n");
+		buf.append("            int ch;\n");
+		buf.append("            while ((ch = reader1.read()) != -1) {\n");
+		buf.append("                System.out.println(ch);\n");
+		buf.append("            }\n");
+		buf.append("        } catch (MyException e) {\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 2);
+		assertCorrectLabels(proposals);
+
+
+		CUCorrectionProposal proposal= (CUCorrectionProposal)proposals.get(0);
+		String preview1= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileReader;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws Exception {\n");
+		buf.append("        try (FileReader reader1 = new FileReader(\"file\")) {\n");
+		buf.append("            int ch;\n");
+		buf.append("            while ((ch = reader1.read()) != -1) {\n");
+		buf.append("                System.out.println(ch);\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected1= buf.toString();
+
+		proposal= (CUCorrectionProposal)proposals.get(1);
+		String preview2= getPreviewContent(proposal);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.io.FileReader;\n");
+		buf.append("class MyException extends Exception {\n");
+		buf.append("    static final long serialVersionUID = 1L;\n");
+		buf.append("}\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() throws Exception {\n");
+		buf.append("        try (FileReader reader1 = new FileReader(\"file\")) {\n");
+		buf.append("            int ch;\n");
+		buf.append("            while ((ch = reader1.read()) != -1) {\n");
+		buf.append("                System.out.println(ch);\n");
+		buf.append("            }\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		String expected2= buf.toString();
+
+		assertEqualStringsIgnoreOrder(new String[] { preview1, preview2 }, new String[] { expected1, expected2 });
+	}
+
+	public void testRemoveRedundantTypeArguments1() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<String> a = new ArrayList<java.lang.String>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<String> a = new ArrayList<>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testRemoveRedundantTypeArguments2() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Map<String,String> a = new HashMap<String,String>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Map<String,String> a = new HashMap<>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testRemoveRedundantTypeArguments3() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<Map<String, String>> a = new ArrayList<Map<String, String>>();;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.ArrayList;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<Map<String, String>> a = new ArrayList<>();;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+	public void testRemoveRedundantTypeArguments4() throws Exception {
+
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Map<Map<String, String>, Map<String, String>> a = new HashMap<Map<String, String>, Map<String, String>>();;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		assertNumberOfProposals(proposals, 3);
+		assertCorrectLabels(proposals);
+
+		buf= new StringBuffer();
+		buf.append("package test1;\n");
+		buf.append("import java.util.HashMap;\n");
+		buf.append("import java.util.Map;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Map<Map<String, String>, Map<String, String>> a = new HashMap<>();;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+
+		String expected1= buf.toString();
+		assertExpectedExistInProposals(proposals, new String[] { expected1 });
+	}
+
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest17.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest17.java
new file mode 100644
index 0000000..737b8bd
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/ModifierCorrectionsQuickFixTest17.java
@@ -0,0 +1,546 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.tests.quickfix;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.jdt.testplugin.JavaProjectHelper;
+import org.eclipse.jdt.testplugin.TestOptions;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType;
+
+import org.eclipse.jdt.ui.PreferenceConstants;
+import org.eclipse.jdt.ui.tests.core.Java17ProjectTestSetup;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+public class ModifierCorrectionsQuickFixTest17 extends QuickFixTest {
+
+	private static final String ADD_SAFE_VARARGS= "Add @SafeVarargs";
+	private static final Class THIS= ModifierCorrectionsQuickFixTest17.class;
+
+	private IJavaProject fJProject1;
+
+	private IPackageFragmentRoot fSourceFolder;
+
+	public ModifierCorrectionsQuickFixTest17(String name) {
+		super(name);
+	}
+
+	public static Test suite() {
+		return setUpTest(new TestSuite(THIS));
+	}
+
+	public static Test setUpTest(Test test) {
+		return new Java17ProjectTestSetup(test);
+	}
+
+	protected void setUp() throws Exception {
+		Hashtable options= TestOptions.getDefaultOptions();
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
+		options.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_LOCAL_VARIABLE, JavaCore.DO_NOT_INSERT);
+
+
+		JavaCore.setOptions(options);
+
+		IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
+		store.setValue(PreferenceConstants.CODEGEN_ADD_COMMENTS, false);
+
+		fJProject1= Java17ProjectTestSetup.getProject();
+
+		StubUtility.setCodeTemplate(CodeTemplateContextType.METHODSTUB_ID, "", null);
+		StubUtility.setCodeTemplate(CodeTemplateContextType.CONSTRUCTORSTUB_ID, "", null);
+
+		fSourceFolder= JavaProjectHelper.addSourceContainer(fJProject1, "src");
+	}
+
+
+	protected void tearDown() throws Exception {
+		JavaProjectHelper.clear(fJProject1, Java17ProjectTestSetup.getDefaultClasspath());
+	}
+
+	public void testAddSafeVarargs1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public static <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 3);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargs2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public final <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 3);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public final <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargs3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public static <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 3);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public static <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargs4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("public class E {\n");
+		buf.append("    public <T> E(T ... a) {\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 3);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public <T> E(T ... a) {\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargs5() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public <T> List<T> asList(T ... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+
+		assertProposalDoesNotExist(proposals, ADD_SAFE_VARARGS);
+	}
+
+	public void testAddSafeVarargsToDeclaration1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 2);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargsToDeclaration2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 2);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargsToDeclaration3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("class Y {\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		pack1.createCompilationUnit("Y.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 1);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("class Y {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargsToDeclaration4() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        new Y(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("    public <T> Y(T ... a) {\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot, 2);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        new Y(Y.asList(\"Hello\", \" World\"));\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		buf.append("class Y {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public <T> Y(T ... a) {\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testAddSafeVarargsToDeclaration5() throws Exception {
+		JavaProjectHelper.set15CompilerOptions(fJProject1);
+		try {
+			IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+			StringBuffer buf= new StringBuffer();
+			buf.append("package p;\n");
+			buf.append("import java.util.List;\n");
+			buf.append("public class E {\n");
+			buf.append("    void foo() {\n");
+			buf.append("        Y.asList(Y.asList(\"Hello\", \" World\"));\n");
+			buf.append("    }\n");
+			buf.append("}\n");
+			buf.append("class Y {\n");
+			buf.append("    public static <T> List<T> asList(T... a) {\n");
+			buf.append("        return null;\n");
+			buf.append("    }\n");
+			buf.append("}\n");
+			ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+			CompilationUnit astRoot= getASTRoot(cu);
+			ArrayList proposals= collectCorrections(cu, astRoot);
+			assertNumberOfProposals(proposals, 1);
+
+			assertProposalDoesNotExist(proposals, "Add @SafeVarargs to 'asList(..)'");
+		} finally {
+			JavaProjectHelper.set17CompilerOptions(fJProject1);
+		}
+	}
+
+	public void testRemoveSafeVarargs1() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public static <T> List<T> asList() {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 1);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public static <T> List<T> asList() {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testRemoveSafeVarargs2() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    public <T> List<T> asList2(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 1);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    public <T> List<T> asList2(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+	public void testRemoveSafeVarargs3() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("p", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @SafeVarargs\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public <T> List<T> asList2(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("E.java", buf.toString(), false, null);
+
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 1);
+
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("import java.util.List;\n");
+		buf.append("public class E {\n");
+		buf.append("    @Deprecated\n");
+		buf.append("    public <T> List<T> asList2(T... a) {\n");
+		buf.append("        return null;\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
+		assertExpectedExistInProposals(proposals, expected);
+	}
+
+}
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java
index 6ab1b42..a4c6b39 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/QuickFixTest.java
@@ -78,17 +78,21 @@
 		suite.addTest(UnresolvedMethodsQuickFixTest.suite());
 		suite.addTest(ReturnTypeQuickFixTest.suite());
 		suite.addTest(LocalCorrectionsQuickFixTest.suite());
+		suite.addTest(LocalCorrectionsQuickFixTest17.suite());
 		suite.addTest(TypeMismatchQuickFixTests.suite());
 		suite.addTest(ReorgQuickFixTest.suite());
 		suite.addTest(ModifierCorrectionsQuickFixTest.suite());
+		suite.addTest(ModifierCorrectionsQuickFixTest17.suite());
 		suite.addTest(GetterSetterQuickFixTest.suite());
 		suite.addTest(AssistQuickFixTest.suite());
+		suite.addTest(AssistQuickFixTest17.suite());
 		suite.addTest(ChangeNonStaticToStaticTest.suite());
 		suite.addTest(MarkerResolutionTest.suite());
 		suite.addTest(JavadocQuickFixTest.suite());
 		suite.addTest(ConvertForLoopQuickFixTest.suite());
 		suite.addTest(ConvertIterableLoopQuickFixTest.suite());
 		suite.addTest(AdvancedQuickAssistTest.suite());
+		suite.addTest(AdvancedQuickAssistTest17.suite());
 		suite.addTest(CleanUpTestCase.suite());
 		suite.addTest(QuickFixEnablementTest.suite());
 		suite.addTest(SurroundWithTemplateTest.suite());
@@ -209,12 +213,19 @@
 		return collectCorrections(cu, astRoot, nProblems, null);
 	}
 
+	protected static final ArrayList collectCorrections(ICompilationUnit cu, CompilationUnit astRoot, int nProblems, int problem) throws CoreException {
+		return collectCorrections(cu, astRoot, nProblems, problem, null);
+	}
 
 	protected static final ArrayList collectCorrections(ICompilationUnit cu, CompilationUnit astRoot, int nProblems, AssistContext context) throws CoreException {
+		return collectCorrections(cu, astRoot, nProblems, 0, context);
+	}
+
+	protected static final ArrayList collectCorrections(ICompilationUnit cu, CompilationUnit astRoot, int nProblems, int problem, AssistContext context) throws CoreException {
 		IProblem[] problems= astRoot.getProblems();
 		assertNumberOfProblems(nProblems, problems);
-		
-		return collectCorrections(cu, problems[0], context);
+
+		return collectCorrections(cu, problems[problem], context);
 	}
 
 	protected static void assertNumberOfProblems(int nProblems, IProblem[] problems) {
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeParameterMismatchTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeParameterMismatchTest.java
index 88dbc38..c253ce7 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeParameterMismatchTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/TypeParameterMismatchTest.java
@@ -138,8 +138,38 @@
 		expected[0]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
-		}
+	}
 
+	public void testInferDiamondArguments() throws Exception {
+		IPackageFragment pack1= fSourceFolder.createPackageFragment("", false, null);
+		StringBuffer buf= new StringBuffer();
+		buf.append("import java.util.*;\n");
+		buf.append("public class A {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<String> a= new ArrayList<>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		ICompilationUnit cu= pack1.createCompilationUnit("A.java", buf.toString(), false, null);
+		
+		CompilationUnit astRoot= getASTRoot(cu);
+		ArrayList proposals= collectCorrections(cu, astRoot);
+		
+		assertCorrectLabels(proposals);
+		assertNumberOfProposals(proposals, 2);
+		
+		String[] expected= new String[1];
+		buf= new StringBuffer();
+		buf.append("import java.util.*;\n");
+		buf.append("public class A {\n");
+		buf.append("    void foo() {\n");
+		buf.append("        List<String> a= new ArrayList<String>();\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+		
+		assertExpectedExistInProposals(proposals, expected);
+	}
+	
 
 
 }
diff --git a/org.eclipse.jdt.ui/.settings/.api_filters b/org.eclipse.jdt.ui/.settings/.api_filters
index 50aeb84..3efebda 100644
--- a/org.eclipse.jdt.ui/.settings/.api_filters
+++ b/org.eclipse.jdt.ui/.settings/.api_filters
@@ -1,5 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <component id="org.eclipse.jdt.ui" version="2">
+    <resource path="META-INF/MANIFEST.MF">
+        <filter id="924844039">
+            <message_arguments>
+                <message_argument value="3.7.1"/>
+                <message_argument value="3.7.0"/>
+            </message_arguments>
+        </filter>
+    </resource>
     <resource path="core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ReplaceInvocationsRefactoring.java" type="org.eclipse.jdt.internal.corext.refactoring.code.ReplaceInvocationsRefactoring">
         <filter id="571519004">
             <message_arguments>
@@ -135,5 +143,27 @@
                 <message_argument value="IJavaEditorActionDefinitionIds"/>
             </message_arguments>
         </filter>
+        <filter id="1210056707">
+            <message_arguments>
+                <message_argument value="3.7.1"/>
+                <message_argument value="SURROUND_WITH_TRY_MULTI_CATCH"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="ui/org/eclipse/jdt/ui/actions/JdtActionConstants.java" type="org.eclipse.jdt.ui.actions.JdtActionConstants">
+        <filter id="1142947843">
+            <message_arguments>
+                <message_argument value="3.7.1"/>
+                <message_argument value="SURROUND_WITH_TRY_MULTI_CATCH"/>
+            </message_arguments>
+        </filter>
+    </resource>
+    <resource path="ui/org/eclipse/jdt/ui/actions/SurroundWithTryMultiCatchAction.java" type="org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatchAction">
+        <filter id="1109393411">
+            <message_arguments>
+                <message_argument value="3.7.1"/>
+                <message_argument value="org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatchAction"/>
+            </message_arguments>
+        </filter>
     </resource>
 </component>
diff --git a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
index 5bc39b6..676c6e5 100644
--- a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.jdt.ui; singleton:=true
-Bundle-Version: 3.7.0.qualifier
+Bundle-Version: 3.7.1.qualifier
 Bundle-Activator: org.eclipse.jdt.internal.ui.JavaPlugin
 Bundle-ActivationPolicy: lazy
 Bundle-Vendor: %providerName
@@ -115,11 +115,11 @@
  org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.core.resources;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.2.200,4.0.0)",
- org.eclipse.jdt.core;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.7.1,4.0.0)",
  org.eclipse.search;bundle-version="[3.7.0,4.0.0)",
  org.eclipse.debug.core;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.debug.ui;bundle-version="[3.5.0,4.0.0)",
- org.eclipse.jdt.launching;bundle-version="[3.6.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.6.1,4.0.0)",
  org.eclipse.compare;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.team.ui;bundle-version="[3.4.100,4.0.0)",
  org.eclipse.team.core;bundle-version="[3.4.100,4.0.0)",
diff --git a/org.eclipse.jdt.ui/about.html b/org.eclipse.jdt.ui/about.html
index b3906a9..91218e5 100644
--- a/org.eclipse.jdt.ui/about.html
+++ b/org.eclipse.jdt.ui/about.html
@@ -8,7 +8,7 @@
 <body lang="EN-US">
 <h2>About This Content</h2>
  
-<p>April 20, 2007</p>	
+<p>July 28, 2011</p>	
 <h3>License</h3>
 
 <p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise 
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java
index 5b6dbb9..2fc9017 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTFlattener.java
@@ -103,6 +103,7 @@
 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
 import org.eclipse.jdt.core.dom.TypeLiteral;
 import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
@@ -521,7 +522,7 @@
 		this.fBuffer.append(";");//$NON-NLS-1$
 		return false;
 	}
-
+	
 	/*
 	 * @see ASTVisitor#visit(DoStatement)
 	 */
@@ -1437,6 +1438,19 @@
 	@Override
 	public boolean visit(TryStatement node) {
 		this.fBuffer.append("try ");//$NON-NLS-1$
+		if (node.getAST().apiLevel() >= AST.JLS4) {
+			if (!node.resources().isEmpty()) {
+				this.fBuffer.append("(");//$NON-NLS-1$
+				for (Iterator<VariableDeclarationExpression> it= node.resources().iterator(); it.hasNext();) {
+					VariableDeclarationExpression var= it.next();
+					var.accept(this);
+					if (it.hasNext()) {
+						this.fBuffer.append(",");//$NON-NLS-1$
+					}
+				}
+				this.fBuffer.append(") ");//$NON-NLS-1$
+			}
+		}
 		node.getBody().accept(this);
 		this.fBuffer.append(" ");//$NON-NLS-1$
 		for (Iterator<CatchClause> it= node.catchClauses().iterator(); it.hasNext();) {
@@ -1559,6 +1573,21 @@
 	}
 
 	/*
+	 * @see ASTVisitor#visit(UnionType)
+	 */
+	@Override
+	public boolean visit(UnionType node) {
+		for (Iterator<Type> it= node.types().iterator(); it.hasNext();) {
+			Type t= it.next();
+			t.accept(this);
+			if (it.hasNext()) {
+				this.fBuffer.append("|");//$NON-NLS-1$
+			}
+		}
+		return false;
+	}
+	
+	/*
 	 * @see ASTVisitor#visit(VariableDeclarationExpression)
 	 */
 	@Override
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java
index b47e7eb..eb1fc0d 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/ASTNodeFactory.java
@@ -28,10 +28,14 @@
 import org.eclipse.jdt.core.dom.Name;
 import org.eclipse.jdt.core.dom.NodeFinder;
 import org.eclipse.jdt.core.dom.PrimitiveType;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
 import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
 
 public class ASTNodeFactory {
 
@@ -118,9 +122,47 @@
 	 * @return a new type node created with the given AST.
 	 */
 	public static Type newType(AST ast, VariableDeclaration declaration) {
-		Type type= ASTNodes.getType(declaration);
-		int extraDim= declaration.getExtraDimensions();
+		return newType(ast, declaration, null, null);
+	}
 
+	/**
+	 * Returns the new type node corresponding to the type of the given declaration
+	 * including the extra dimensions. If the type is a {@link UnionType}, use the LUB type.
+	 * If the <code>importRewrite</code> is <code>null</code>, the type may be fully-qualified. 
+	 * 
+	 * @param ast The AST to create the resulting type with.
+	 * @param declaration The variable declaration to get the type from
+	 * @param importRewrite the import rewrite to use, or <code>null</code>
+	 * @param context the import rewrite context, or <code>null</code>
+	 * @return a new type node created with the given AST.
+	 * 
+	 * @since 3.7.1
+	 */
+	public static Type newType(AST ast, VariableDeclaration declaration, ImportRewrite importRewrite, ImportRewriteContext context) {
+		Type type= ASTNodes.getType(declaration);
+
+		if (declaration instanceof SingleVariableDeclaration) {
+			Type type2= ((SingleVariableDeclaration) declaration).getType();
+			if (type2 instanceof UnionType) {
+				ITypeBinding typeBinding= type2.resolveBinding();
+				if (typeBinding != null) {
+					if (importRewrite != null) {
+						type= importRewrite.addImport(typeBinding, ast, context);
+						return type;
+					} else {
+						String qualifiedName= typeBinding.getQualifiedName();
+						if (qualifiedName.length() > 0) {
+							type= ast.newSimpleType(ast.newName(qualifiedName));
+							return type;
+						}
+					}
+				}
+				// XXX: fallback for intersection types or unresolved types: take first type of union
+				type= (Type) ((UnionType) type2).types().get(0);
+				return type;
+			}
+		}
+		int extraDim= declaration.getExtraDimensions();
 		type= (Type) ASTNode.copySubtree(ast, type);
 		for (int i= 0; i < extraDim; i++) {
 			type= ast.newArrayType(type);
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/GenericVisitor.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/GenericVisitor.java
index 8b900f5..3c9ca14 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/GenericVisitor.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/GenericVisitor.java
@@ -90,6 +90,7 @@
 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
 import org.eclipse.jdt.core.dom.TypeLiteral;
 import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
@@ -367,6 +368,10 @@
 		return visitNode(node);
 	}
 	@Override
+	public boolean visit(UnionType node) {
+		return visitNode(node);
+	}
+	@Override
 	public boolean visit(SingleVariableDeclaration node) {
 		return visitNode(node);
 	}
@@ -764,6 +769,10 @@
 		endVisitNode(node);
 	}
 	@Override
+	public void endVisit(UnionType node) {
+		endVisitNode(node);
+	}
+	@Override
 	public void endVisit(SingleVariableDeclaration node) {
 		endVisitNode(node);
 	}
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java
index 4d75ad9..48f0c35 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/HierarchicalASTVisitor.java
@@ -98,6 +98,7 @@
 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
 import org.eclipse.jdt.core.dom.TypeLiteral;
 import org.eclipse.jdt.core.dom.TypeParameter;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
@@ -1072,6 +1073,16 @@
 		endVisit((Type)node);
 	}
 
+	@Override
+	public boolean visit(UnionType node) {
+		return visit((Type)node);
+	}
+
+	@Override
+	public void endVisit(UnionType node) {
+		endVisit((Type)node);
+	}
+
 //---- End Type Hierarchy ----------------------------------------
 
 	@Override
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java
index afe32bc..0217274 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/JavaModelUtil.java
@@ -64,10 +64,19 @@
 public final class JavaModelUtil {
 	
 	/**
+	 * The latest available {@link JavaCore}{@code #VERSION_*} level.
+	 * @since 3.7
+	 */
+	public static final String VERSION_LATEST;
+	static {
+		VERSION_LATEST= JavaCore.VERSION_1_7; // make sure it is not inlined
+	}
+	
+	/**
 	 * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=309163
 	 * @since 3.7
 	 */
-	public static final boolean HIDE_VERSION_1_7= true;
+	public static final boolean HIDE_VERSION_1_7= Boolean.FALSE.booleanValue();
 
 	/**
 	 * Only use this suffix for creating new .java files.
@@ -684,14 +693,6 @@
 	}
 
 
-	/**
-	 * Sets all compliance settings in the given map to 5.0
-	 * @param map the map to update
-	 */
-	public static void set50ComplianceOptions(Map<String, String> map) {
-		setComplianceOptions(map, JavaCore.VERSION_1_5);
-	}
-
 	public static void setComplianceOptions(Map<String, String> map, String compliance) {
 		JavaCore.setComplianceOptions(compliance, map);
 	}
@@ -723,12 +724,16 @@
 	public static boolean is50OrHigher(String compliance) {
 		return !isVersionLessThan(compliance, JavaCore.VERSION_1_5);
 	}
+	
+	public static boolean is17OrHigher(String compliance) {
+		return !isVersionLessThan(compliance, JavaCore.VERSION_1_7);
+	}
 
 	/**
-	 * Checks if the given project or workspace has source compliance 5.0 or greater.
+	 * Checks if the given project or workspace has source compliance 1.5 or greater.
 	 *
 	 * @param project the project to test or <code>null</code> to test the workspace settings
-	 * @return <code>true</code> if the given project or workspace has source compliance 5.0 or greater.
+	 * @return <code>true</code> if the given project or workspace has source compliance 1.5 or greater.
 	 */
 	public static boolean is50OrHigher(IJavaProject project) {
 		String source= project != null ? project.getOption(JavaCore.COMPILER_SOURCE, true) : JavaCore.getOption(JavaCore.COMPILER_SOURCE);
@@ -736,12 +741,23 @@
 	}
 
 	/**
-	 * Checks if the JRE of the given project or workspace default JRE have source compliance 5.0 or
+	 * Checks if the given project or workspace has source compliance 1.7 or greater.
+	 *
+	 * @param project the project to test or <code>null</code> to test the workspace settings
+	 * @return <code>true</code> if the given project or workspace has source compliance 1.7 or greater.
+	 */
+	public static boolean is17OrHigher(IJavaProject project) {
+		String source= project != null ? project.getOption(JavaCore.COMPILER_SOURCE, true) : JavaCore.getOption(JavaCore.COMPILER_SOURCE);
+		return is17OrHigher(source);
+	}
+	
+	/**
+	 * Checks if the JRE of the given project or workspace default JRE have source compliance 1.5 or
 	 * greater.
 	 *
 	 * @param project the project to test or <code>null</code> to test the workspace JRE
 	 * @return <code>true</code> if the JRE of the given project or workspace default JRE have
-	 *         source compliance 5.0 or greater.
+	 *         source compliance 1.5 or greater.
 	 * @throws CoreException if unable to determine the project's VM install
 	 */
 	public static boolean is50OrHigherJRE(IJavaProject project) throws CoreException {
@@ -752,11 +768,11 @@
 			vmInstall= JavaRuntime.getVMInstall(project);
 		}
 		if (!(vmInstall instanceof IVMInstall2))
-			return true; // assume 5.0.
+			return true; // assume 1.5.
 
 		String compliance= getCompilerCompliance((IVMInstall2) vmInstall, null);
 		if (compliance == null)
-			return true; // assume 5.0
+			return true; // assume 1.5
 		return compliance.startsWith(JavaCore.VERSION_1_5)
 				|| compliance.startsWith(JavaCore.VERSION_1_6)
 				|| compliance.startsWith(JavaCore.VERSION_1_7);
@@ -889,4 +905,8 @@
 		return "package-info.java".equals(cu.getElementName()); //$NON-NLS-1$
 	}
 
+	public static boolean isPolymorphicSignature(IMethod method) {
+		return method.getAnnotation("java.lang.invoke.MethodHandle$PolymorphicSignature").exists(); //$NON-NLS-1$
+	}
+
 }
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
index 7051035..62f0832 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringAvailabilityTester.java
@@ -741,6 +741,8 @@
 			return false;
 		if (method.getDeclaringType().isAnnotation())
 			return false;
+		if (JavaModelUtil.isPolymorphicSignature(method))
+			return false;
 
 		return true;
 	}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java
index 173037b..2c6aef5 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringCoreMessages.java
@@ -149,6 +149,8 @@
 
 	public static String ChangeTypeRefactoring_enumsNotSupported;
 
+	public static String ChangeTypeRefactoring_uniontypeNotSupported;
+
 	public static String ChangeTypeRefactoring_insideLocalTypesNotSupported;
 
 	public static String ChangeTypeRefactoring_invalidSelection;
@@ -563,6 +565,8 @@
 
 	public static String ExtractMethodAnalyzer_parent_mismatch;
 
+	public static String ExtractMethodAnalyzer_resource_in_try_with_resources;
+
 	public static String ExtractMethodAnalyzer_single_expression_or_set;
 
 	public static String ExtractMethodAnalyzer_super_or_this;
@@ -685,6 +689,8 @@
 
 	public static String ExtractTempRefactoring_replace_occurrences;
 
+	public static String ExtractTempRefactoring_resource_in_try_with_resources;
+
 	public static String ExtractTempRefactoring_select_expression;
 
 	public static String FlowAnalyzer_execution_flow;
@@ -861,6 +867,8 @@
 
 	public static String InlineTempRefactoring_remove_edit_name;
 
+	public static String InlineTempRefactoring_resource_in_try_with_resources;
+
 	public static String InlineTempRefactoring_select_temp;
 
 	public static String InlineTemRefactoring_error_message_fieldsCannotBeInlined;
@@ -2317,6 +2325,8 @@
 
 	public static String SurroundWithTryCatchRefactoring_name;
 
+	public static String SurroundWithTryCatchRefactoring_notMultipleexceptions;
+
 	public static String TargetProvider_cannot_local_method_in_binary;
 
 	public static String TargetProvider_inaccurate_match;
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/TypeContextChecker.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/TypeContextChecker.java
index eb3d032..8c3858e 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/TypeContextChecker.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/TypeContextChecker.java
@@ -713,7 +713,7 @@
 		ASTParser p= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
 		p.setSource(cuBuff.toString().toCharArray());
 		Map<String, String> options= new HashMap<String, String>();
-		JavaModelUtil.set50ComplianceOptions(options);
+		JavaModelUtil.setComplianceOptions(options, JavaModelUtil.VERSION_LATEST);
 		p.setCompilerOptions(options);
 		CompilationUnit cu= (CompilationUnit) p.createAST(null);
 		ASTNode selected= NodeFinder.perform(cu, offset, superType.length());
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ConstantChecks.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ConstantChecks.java
index 8bb9a0d..c8335fd 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ConstantChecks.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ConstantChecks.java
@@ -68,7 +68,7 @@
 		}
 		@Override
 		public boolean visit(FieldAccess node) {
-			fResult= new LoadTimeConstantChecker((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(node.getExpression())).check();
+			fResult&= new LoadTimeConstantChecker((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(node.getExpression())).check();
 			return false;
 		}
 		@Override
@@ -76,7 +76,7 @@
 			if(node.getExpression() == null) {
 				visitName(node.getName());
 			} else {
-				fResult= new LoadTimeConstantChecker((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(node.getExpression())).check();
+				fResult&= new LoadTimeConstantChecker((IExpressionFragment) ASTFragmentFactory.createFragmentForFullSubtree(node.getExpression())).check();
 			}
 
 			return false;
@@ -91,7 +91,7 @@
 		}
 
 		private boolean visitName(Name name) {
-			fResult= checkName(name);
+			fResult&= checkName(name);
 			return false; //Do not descend further
 		}
 
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java
index b8032b3..51d8f63 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodAnalyzer.java
@@ -61,6 +61,7 @@
 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
 import org.eclipse.jdt.core.dom.SwitchCase;
 import org.eclipse.jdt.core.dom.ThisExpression;
+import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
@@ -247,7 +248,7 @@
 		switch (fReturnKind) {
 			case ACCESS_TO_LOCAL:
 				VariableDeclaration declaration= ASTNodes.findVariableDeclaration(fReturnValue, fEnclosingBodyDeclaration);
-				fReturnType= ASTNodeFactory.newType(ast, declaration);
+				fReturnType= ASTNodeFactory.newType(ast, declaration, rewriter, new ContextSensitiveImportRewriteContext(declaration, rewriter));
 				if (declaration.resolveBinding() != null) {
 					fReturnTypeBinding= declaration.resolveBinding().getType();
 				}
@@ -843,6 +844,11 @@
 
 	@Override
 	public void endVisit(VariableDeclarationExpression node) {
+		if (getSelection().getEndVisitSelectionMode(node) == Selection.SELECTED && getFirstSelectedNode() == node) {
+			if (node.getLocationInParent() == TryStatement.RESOURCES_PROPERTY) {
+				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_resource_in_try_with_resources, JavaStatusContext.create(fCUnit, getSelection()));
+			}
+		}
 		checkTypeInDeclaration(node.getType());
 		super.endVisit(node);
 	}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java
index c75a7e5..949683d 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractMethodRefactoring.java
@@ -818,7 +818,7 @@
 	}
 
 	private String getType(VariableDeclaration declaration, boolean isVarargs) {
-		String type= ASTNodes.asString(ASTNodeFactory.newType(declaration.getAST(), declaration));
+		String type= ASTNodes.asString(ASTNodeFactory.newType(declaration.getAST(), declaration, fImportRewriter, new ContextSensitiveImportRewriteContext(declaration, fImportRewriter)));
 		if (isVarargs)
 			return type + ParameterInfo.ELLIPSIS;
 		else
@@ -999,6 +999,8 @@
 		result.modifiers().addAll(ASTNodeFactory.newModifiers(fAST, modifiers));
 		result.setReturnType2((Type)ASTNode.copySubtree(fAST, fAnalyzer.getReturnType()));
 		result.setName(fAST.newSimpleName(fMethodName));
+		
+		ImportRewriteContext context= new ContextSensitiveImportRewriteContext(enclosingBodyDeclaration, fImportRewriter);
 
 		List<SingleVariableDeclaration> parameters= result.parameters();
 		for (int i= 0; i < fParameterInfos.size(); i++) {
@@ -1006,7 +1008,7 @@
 			VariableDeclaration infoDecl= getVariableDeclaration(info);
 			SingleVariableDeclaration parameter= fAST.newSingleVariableDeclaration();
 			parameter.modifiers().addAll(ASTNodeFactory.newModifiers(fAST, ASTNodes.getModifiers(infoDecl)));
-			parameter.setType(ASTNodeFactory.newType(fAST, infoDecl));
+			parameter.setType(ASTNodeFactory.newType(fAST, infoDecl, fImportRewriter, context));
 			parameter.setName(fAST.newSimpleName(info.getNewName()));
 			parameter.setVarargs(info.isNewVarargs());
 			parameters.add(parameter);
@@ -1014,7 +1016,6 @@
 
 		List<Name> exceptions= result.thrownExceptions();
 		ITypeBinding[] exceptionTypes= fAnalyzer.getExceptions(fThrowRuntimeExceptions);
-		ImportRewriteContext context= new ContextSensitiveImportRewriteContext(enclosingBodyDeclaration, fImportRewriter);
 		for (int i= 0; i < exceptionTypes.length; i++) {
 			ITypeBinding exceptionType= exceptionTypes[i];
 			exceptions.add(ASTNodeFactory.newName(fAST, fImportRewriter.addImport(exceptionType, context)));
@@ -1144,7 +1145,7 @@
 		fragment.setInitializer(intilizer);
 		VariableDeclarationStatement result= fAST.newVariableDeclarationStatement(fragment);
 		result.modifiers().addAll(ASTNode.copySubtrees(fAST, ASTNodes.getModifiers(original)));
-		result.setType(ASTNodeFactory.newType(fAST, original));
+		result.setType(ASTNodeFactory.newType(fAST, original, fImportRewriter, new ContextSensitiveImportRewriteContext(original, fImportRewriter)));
 		return result;
 	}
 
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java
index 2d915ad..3d84176 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/ExtractTempRefactoring.java
@@ -85,6 +85,7 @@
 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
 import org.eclipse.jdt.core.dom.SwitchCase;
 import org.eclipse.jdt.core.dom.SwitchStatement;
+import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
@@ -442,12 +443,13 @@
 					return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_assignment);
 				else
 					return null;
-
 			} else if (selectedExpression instanceof SimpleName) {
 				if ((((SimpleName) selectedExpression)).isDeclaration())
 					return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_names_in_declarations);
 				if (parent instanceof QualifiedName && selectedExpression.getLocationInParent() == QualifiedName.NAME_PROPERTY || parent instanceof FieldAccess && selectedExpression.getLocationInParent() == FieldAccess.NAME_PROPERTY)
 					return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_select_expression);
+			} else if (selectedExpression instanceof VariableDeclarationExpression && parent instanceof TryStatement) {
+				return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.ExtractTempRefactoring_resource_in_try_with_resources);
 			}
 		}
 
@@ -876,7 +878,7 @@
 		ASTRewrite rewrite= fCURewrite.getASTRewrite();
 		AST ast= rewrite.getAST();
 
-		if (expression instanceof ClassInstanceCreation) {
+		if (expression instanceof ClassInstanceCreation && (typeBinding == null || typeBinding.getTypeArguments().length == 0)) {
 			resultingType= (Type) rewrite.createCopyTarget(((ClassInstanceCreation) expression).getType());
 		} else if (expression instanceof CastExpression) {
 			resultingType= (Type) rewrite.createCopyTarget(((CastExpression) expression).getType());
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java
index 923f455..39a8e97 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineConstantRefactoring.java
@@ -77,7 +77,6 @@
 import org.eclipse.jdt.core.dom.QualifiedName;
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.SuperMethodInvocation;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
@@ -257,9 +256,7 @@
 
 			private void perform(Expression initializer) {
 				initializer.accept(this);
-				if (initializer instanceof MethodInvocation || initializer instanceof SuperMethodInvocation) {
-					addExplicitTypeArgumentsIfNecessary(initializer);
-				}
+				addExplicitTypeArgumentsIfNecessary(initializer);
 			}
 
 			private void addExplicitTypeArgumentsIfNecessary(Expression invocation) {
@@ -268,9 +265,8 @@
 					if (! (referenceContext instanceof VariableDeclarationFragment
 							|| referenceContext instanceof SingleVariableDeclaration
 							|| referenceContext instanceof Assignment)) {
-						IMethodBinding methodBinding= Invocations.resolveBinding(invocation);
-						ITypeBinding[] typeArguments= methodBinding.getTypeArguments();
-						ListRewrite typeArgsRewrite= fInitializerRewrite.getListRewrite(invocation, Invocations.getTypeArgumentsProperty(invocation));
+						ITypeBinding[] typeArguments= Invocations.getInferredTypeArguments(invocation);
+						ListRewrite typeArgsRewrite= Invocations.getInferredTypeArgumentsRewrite(fInitializerRewrite, invocation);
 						for (int i= 0; i < typeArguments.length; i++) {
 							Type typeArgument= fNewLocationCuRewrite.getImportRewrite().addImport(typeArguments[i], fNewLocationCuRewrite.getAST(), fNewLocationContext);
 							fNewLocationCuRewrite.getImportRemover().registerAddedImports(typeArgument);
@@ -278,10 +274,14 @@
 						}
 						
 						if (invocation instanceof MethodInvocation) {
-							Expression expression= ((MethodInvocation)invocation).getExpression();
+							MethodInvocation methodInvocation= (MethodInvocation) invocation;
+							Expression expression= methodInvocation.getExpression();
 							if (expression == null) {
-								expression= fNewLocationCuRewrite.getAST().newName(fNewLocationCuRewrite.getImportRewrite().addImport(methodBinding.getDeclaringClass().getTypeDeclaration(), fNewLocationContext));
-								fInitializerRewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, expression, null);
+								IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
+								if (methodBinding != null) {
+									expression= fNewLocationCuRewrite.getAST().newName(fNewLocationCuRewrite.getImportRewrite().addImport(methodBinding.getDeclaringClass().getTypeDeclaration(), fNewLocationContext));
+									fInitializerRewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, expression, null);
+								}
 							}
 						}
 					}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java
index 2d31d41..ebddd77 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/InlineTempRefactoring.java
@@ -64,7 +64,7 @@
 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
-import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
@@ -237,6 +237,10 @@
 			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InlineTempRefactoring_for_initializers);
 		}
 
+		if (parent instanceof VariableDeclarationExpression && parent.getLocationInParent() == TryStatement.RESOURCES_PROPERTY) {
+			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InlineTempRefactoring_resource_in_try_with_resources);
+		}
+
 		if (decl.getInitializer() == null) {
 			String message= Messages.format(RefactoringCoreMessages.InlineTempRefactoring_not_initialized, BasicElementLabels.getJavaElementName(decl.getName().getIdentifier()));
 			return RefactoringStatus.createFatalErrorStatus(message);
@@ -356,16 +360,14 @@
 		Expression initializer= varDecl.getInitializer();
 
 		ASTNode referenceContext= reference.getParent();
-		if (isInvocation(initializer)) {
-			if (Invocations.isResolvedTypeInferredFromExpectedType(initializer)) {
-				if (! (referenceContext instanceof VariableDeclarationFragment
-						|| referenceContext instanceof SingleVariableDeclaration
-						|| referenceContext instanceof Assignment)) {
-					IMethodBinding methodBinding= Invocations.resolveBinding(initializer);
-					if (methodBinding != null) {
-						String newSource= createParameterizedInvocation(initializer, methodBinding, rewrite);
-						return (Expression) rewrite.getASTRewrite().createStringPlaceholder(newSource, initializer.getNodeType());
-					}
+		if (Invocations.isResolvedTypeInferredFromExpectedType(initializer)) {
+			if (! (referenceContext instanceof VariableDeclarationFragment
+					|| referenceContext instanceof SingleVariableDeclaration
+					|| referenceContext instanceof Assignment)) {
+				ITypeBinding[] typeArguments= Invocations.getInferredTypeArguments(initializer);
+				if (typeArguments != null) {
+					String newSource= createParameterizedInvocation(initializer, typeArguments, rewrite);
+					return (Expression) rewrite.getASTRewrite().createStringPlaceholder(newSource, initializer.getNodeType());
 				}
 			}
 		}
@@ -396,20 +398,21 @@
 		return copy;
 	}
 
-	private String createParameterizedInvocation(Expression invocation, IMethodBinding methodBinding, CompilationUnitRewrite cuRewrite) throws JavaModelException {
+	private String createParameterizedInvocation(Expression invocation, ITypeBinding[] typeArguments, CompilationUnitRewrite cuRewrite) throws JavaModelException {
 		ASTRewrite rewrite= ASTRewrite.create(invocation.getAST());
-		ListRewrite typeArgsRewrite= rewrite.getListRewrite(invocation, Invocations.getTypeArgumentsProperty(invocation));
+		ListRewrite typeArgsRewrite= Invocations.getInferredTypeArgumentsRewrite(rewrite, invocation);
 		
-		ITypeBinding[] typeArguments= methodBinding.getTypeArguments();
 		for (int i= 0; i < typeArguments.length; i++) {
 			Type typeArgumentNode= cuRewrite.getImportRewrite().addImport(typeArguments[i], cuRewrite.getAST());
 			typeArgsRewrite.insertLast(typeArgumentNode, null);
 		}
 		
 		if (invocation instanceof MethodInvocation) {
-			Expression expression= ((MethodInvocation)invocation).getExpression();
+			MethodInvocation methodInvocation= (MethodInvocation) invocation;
+			Expression expression= methodInvocation.getExpression();
 			if (expression == null) {
-				if (Modifier.isStatic(methodBinding.getModifiers())) {
+				IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
+				if (methodBinding != null && Modifier.isStatic(methodBinding.getModifiers())) {
 					expression= cuRewrite.getAST().newName(cuRewrite.getImportRewrite().addImport(methodBinding.getDeclaringClass().getTypeDeclaration()));
 				} else {
 					expression= invocation.getAST().newThisExpression();
@@ -438,10 +441,6 @@
 		return fCu.getBuffer().getText(invocation.getStartPosition(), invocation.getLength());
 	}
 
-	private static boolean isInvocation(Expression node) {
-		return node instanceof MethodInvocation || node instanceof SuperMethodInvocation;
-	}
-
 	public SimpleName[] getReferences() {
 		if (fReferences != null)
 			return fReferences;
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
index a932e2d..8dabab0 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
@@ -1059,6 +1059,8 @@
 			return status;
 		}
 
+		currentTypeBinding= currentTypeBinding.getTypeDeclaration();
+
 		ITypeBinding typeOfCall= ASTNodes.getEnclosingType(originalInvocation);
 		if (!typeOfCall.equals(currentTypeBinding)) {
 			if (currentTypeBinding.isAnonymous()) {
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/Invocations.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/Invocations.java
index 1e9d698..1400f7b 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/Invocations.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/Invocations.java
@@ -22,9 +22,14 @@
 import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
 import org.eclipse.jdt.core.dom.Expression;
 import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
 import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.ParameterizedType;
 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
+import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
 
 public class Invocations {
 
@@ -140,39 +145,51 @@
 	}
 
 	public static boolean isResolvedTypeInferredFromExpectedType(Expression invocation) {
+		if (invocation == null)
+			return false;
+		
 		switch (invocation.getNodeType()) {
 			case ASTNode.METHOD_INVOCATION:
 				return ((MethodInvocation) invocation).isResolvedTypeInferredFromExpectedType();
 			case ASTNode.SUPER_METHOD_INVOCATION:
 				return ((SuperMethodInvocation) invocation).isResolvedTypeInferredFromExpectedType();
-				
-			case ASTNode.CONSTRUCTOR_INVOCATION:
-			case ASTNode.SUPER_CONSTRUCTOR_INVOCATION:
-				
 			case ASTNode.CLASS_INSTANCE_CREATION:
-			case ASTNode.ENUM_CONSTANT_DECLARATION:
+				return ((ClassInstanceCreation) invocation).isResolvedTypeInferredFromExpectedType();
+				
+			default:
 				return false;
+		}
+	}
+	
+	public static ListRewrite getInferredTypeArgumentsRewrite(ASTRewrite rewrite, Expression invocation) {
+		switch (invocation.getNodeType()) {
+			case ASTNode.METHOD_INVOCATION:
+				return rewrite.getListRewrite(invocation, MethodInvocation.TYPE_ARGUMENTS_PROPERTY);
+			case ASTNode.SUPER_METHOD_INVOCATION:
+				return rewrite.getListRewrite(invocation, SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY);
+			case ASTNode.CLASS_INSTANCE_CREATION:
+				Type type= ((ClassInstanceCreation) invocation).getType();
+				return rewrite.getListRewrite(type, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
+				
 			default:
 				throw new IllegalArgumentException(invocation.toString());
 		}
 	}
 
-	public static ChildListPropertyDescriptor getTypeArgumentsProperty(Expression invocation) {
+	public static ITypeBinding[] getInferredTypeArguments(Expression invocation) {
+		IMethodBinding methodBinding;
 		switch (invocation.getNodeType()) {
 			case ASTNode.METHOD_INVOCATION:
-				return MethodInvocation.TYPE_ARGUMENTS_PROPERTY;
+				methodBinding= ((MethodInvocation) invocation).resolveMethodBinding();
+				return methodBinding == null ? null : methodBinding.getTypeArguments();
 			case ASTNode.SUPER_METHOD_INVOCATION:
-				return SuperMethodInvocation.TYPE_ARGUMENTS_PROPERTY;
-				
-			case ASTNode.CONSTRUCTOR_INVOCATION:
-				return ConstructorInvocation.TYPE_ARGUMENTS_PROPERTY;
-			case ASTNode.SUPER_CONSTRUCTOR_INVOCATION:
-				return SuperConstructorInvocation.TYPE_ARGUMENTS_PROPERTY;
-				
+				methodBinding= ((SuperMethodInvocation) invocation).resolveMethodBinding();
+				return methodBinding == null ? null : methodBinding.getTypeArguments();
 			case ASTNode.CLASS_INSTANCE_CREATION:
-				return ClassInstanceCreation.TYPE_ARGUMENTS_PROPERTY;
+				Type type= ((ClassInstanceCreation) invocation).getType();
+				ITypeBinding typeBinding= type.resolveBinding();
+				return typeBinding == null ? null : typeBinding.getTypeArguments();
 				
-			case ASTNode.ENUM_CONSTANT_DECLARATION:
 			default:
 				throw new IllegalArgumentException(invocation.toString());
 		}
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties
index 055df80..990b8e1 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/refactoring.properties
@@ -128,6 +128,7 @@
 ExtractMethodAnalyzer_leftHandSideOfAssignment=Cannot extract the left-hand side of an assignment.
 ExtractMethodAnalyzer_single_expression_or_set=Can only extract a single expression or a set of statements.
 ExtractMethodAnalyzer_cannot_extract_null_type=Cannot extract null expression.
+ExtractMethodAnalyzer_resource_in_try_with_resources=Cannot extract a resource declared in a 'try-with-resources' statement.
 
 ExtractMethodRefactoring_name=Extract Method
 ExtractMethodRefactoring_add_method=Create new method ''{0}'' from selected statements
@@ -251,6 +252,7 @@
 InlineTempRefactoring_inline=Inline local variable
 InlineTempRefactoring_inline_edit_name=Replace variable reference with expression
 InlineTempRefactoring_remove_edit_name=Remove variable declaration
+InlineTempRefactoring_resource_in_try_with_resources=Cannot inline a resource declared in a 'try-with-resources' statement.
 InlineTempRefactoring_for_initializers=Cannot inline variables declared in the initializer list of a \'for\' statement.
 InlineTempRefactoring_original_pattern=Original element: ''{0}''
 
@@ -279,6 +281,7 @@
 ExtractTempRefactoring_change_name=Extract Local Variable
 ExtractTempRefactoring_refers_to_for_variable=Cannot extract expression, since it refers to a variable declared in the initializer of the enclosing \'for\' statement.
 ExtractTempRefactoring_replace_occurrences=Replace occurrences of expression with variable
+ExtractTempRefactoring_resource_in_try_with_resources=Cannot extract a resource declared in a 'try-with-resources' statement.
 ExtractTempRefactoring_destination_pattern=Destination method: ''{0}''
 ExtractTempRefactoring_for_initializer_updater=Cannot extract \'for\' initializer or updater.
 
@@ -693,6 +696,7 @@
 #######################################
 
 SurroundWithTryCatchRefactoring_name=Surround with try/catch Block
+SurroundWithTryCatchRefactoring_notMultipleexceptions=The selected code does not throw multiple uncaught exceptions. A simple catch block will be created.
 SurroundWithTryCatchAnalyzer_doesNotCover=Selection does not cover a set of statements. Extend selection to a valid range using the \'Expand Selection To\' actions from the \'Edit\' menu.
 SurroundWithTryCatchAnalyzer_doesNotContain=Selection does not contain statements from a method body or static initializer.
 SurroundWithTryCatchAnalyzer_onlyStatements=Only statements can be surrounded with try/catch blocks.
@@ -1286,6 +1290,7 @@
 ChangeTypeRefactoring_insideLocalTypesNotSupported=Generalize Declared Type is currently not supported inside local types.
 ChangeTypeRefactoring_typeParametersNotSupported=Generalize Declared Type is not supported on type parameters.
 ChangeTypeRefactoring_enumsNotSupported=Generalize Declared Type is not supported on enumerated types.
+ChangeTypeRefactoring_uniontypeNotSupported=Generalize Declared Type is not supported on union types.
 
 #--- Introduce Indirection
 IntroduceIndirectionRefactoring_introduce_indirection_name=Introduce Indirection
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java
index 1dfe371..28abf7d 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ChangeTypeRefactoring.java
@@ -58,6 +58,7 @@
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
@@ -687,6 +688,8 @@
 				return ((FieldDeclaration) node).getType();
 			case ASTNode.VARIABLE_DECLARATION_STATEMENT:
 				return ((VariableDeclarationStatement) node).getType();
+			case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
+				return ((VariableDeclarationExpression) node).getType();
 			case ASTNode.METHOD_DECLARATION:
 				return ((MethodDeclaration)node).getReturnType2();
 			case ASTNode.PARAMETERIZED_TYPE:
@@ -891,6 +894,9 @@
 			}
 		} else if (parent.getNodeType() == ASTNode.SINGLE_VARIABLE_DECLARATION) {
 			SingleVariableDeclaration singleVariableDeclaration= (SingleVariableDeclaration) parent;
+			if (singleVariableDeclaration.getType() instanceof UnionType) {
+				return RefactoringCoreMessages.ChangeTypeRefactoring_uniontypeNotSupported;
+			}
 			if ((grandParent.getNodeType() == ASTNode.METHOD_DECLARATION)) {
 				fMethodBinding= ((MethodDeclaration)grandParent).resolveBinding();
 				setOriginalType(simpleName.resolveTypeBinding());
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
index 2d3b61b..47942a1 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/ExceptionAnalyzer.java
@@ -29,6 +29,7 @@
 import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
 import org.eclipse.jdt.core.dom.SuperMethodInvocation;
 import org.eclipse.jdt.core.dom.ThrowStatement;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 
 import org.eclipse.jdt.internal.corext.dom.Bindings;
 import org.eclipse.jdt.internal.corext.dom.Selection;
@@ -129,6 +130,13 @@
 		return handleExceptions(node.resolveConstructorBinding());
 	}
 
+	@Override
+	public boolean visit(VariableDeclarationExpression node) {
+		if (!isSelected(node))
+			return false;
+		return super.visit(node);
+	}
+
 	private boolean handleExceptions(IMethodBinding binding) {
 		if (binding == null)
 			return true;
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
index 7dfa9e7..617690d 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/surround/SurroundWithTryCatchRefactoring.java
@@ -46,6 +46,7 @@
 import org.eclipse.jdt.core.dom.Statement;
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
@@ -71,7 +72,7 @@
 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
 
 /**
- * Surround a set of statements with a try/catch block.
+ * Surround a set of statements with a try/catch block or a try/multi-catch block.
  *
  * Special case:
  *
@@ -100,18 +101,29 @@
 
 	private LinkedProposalModel fLinkedProposalModel;
 
-	private SurroundWithTryCatchRefactoring(ICompilationUnit cu, Selection selection) {
+	private final boolean fIsMultiCatch;
+
+	private SurroundWithTryCatchRefactoring(ICompilationUnit cu, Selection selection, boolean isMultiCatch) {
 		fCUnit= cu;
 		fSelection= selection;
+		fIsMultiCatch= isMultiCatch;
 		fLeaveDirty= false;
 	}
 
 	public static SurroundWithTryCatchRefactoring create(ICompilationUnit cu, ITextSelection selection) {
-		return new SurroundWithTryCatchRefactoring(cu, Selection.createFromStartLength(selection.getOffset(), selection.getLength()));
+		return create(cu, selection, false);
 	}
 
 	public static SurroundWithTryCatchRefactoring create(ICompilationUnit cu, int offset, int length) {
-		return new SurroundWithTryCatchRefactoring(cu, Selection.createFromStartLength(offset, length));
+		return create(cu, offset, length, false);
+	}
+
+	public static SurroundWithTryCatchRefactoring create(ICompilationUnit cu, ITextSelection selection, boolean isMultiCatch) {
+		return new SurroundWithTryCatchRefactoring(cu, Selection.createFromStartLength(selection.getOffset(), selection.getLength()), isMultiCatch);
+	}
+
+	public static SurroundWithTryCatchRefactoring create(ICompilationUnit cu, int offset, int length, boolean isMultiCatch) {
+		return new SurroundWithTryCatchRefactoring(cu, Selection.createFromStartLength(offset, length), isMultiCatch);
 	}
 
 	public LinkedProposalModel getLinkedProposalModel() {
@@ -144,6 +156,10 @@
 		fAnalyzer= new SurroundWithTryCatchAnalyzer(fCUnit, fSelection);
 		fRootNode.accept(fAnalyzer);
 		result.merge(fAnalyzer.getStatus());
+		ITypeBinding[] exceptions= fAnalyzer.getExceptions();
+		if (fIsMultiCatch && (exceptions == null || exceptions.length <= 1)) {
+			result.merge(RefactoringStatus.createWarningStatus(RefactoringCoreMessages.SurroundWithTryCatchRefactoring_notMultipleexceptions));
+		}
 		return result;
 	}
 
@@ -219,24 +235,51 @@
 		TryStatement tryStatement= getAST().newTryStatement();
 		ITypeBinding[] exceptions= fAnalyzer.getExceptions();
 		ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);
-		for (int i= 0; i < exceptions.length; i++) {
-			ITypeBinding exception= exceptions[i];
-			String type= fImportRewrite.addImport(exception, context);
+
+		if (!fIsMultiCatch) {
+			for (int i= 0; i < exceptions.length; i++) {
+				ITypeBinding exception= exceptions[i];
+				String type= fImportRewrite.addImport(exception, context);
+				CatchClause catchClause= getAST().newCatchClause();
+				tryStatement.catchClauses().add(catchClause);
+				SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration();
+				String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
+
+				String name= fScope.createName(varName, false);
+				decl.setName(getAST().newSimpleName(name));
+				decl.setType(ASTNodeFactory.newType(getAST(), type));
+				catchClause.setException(decl);
+				Statement st= getCatchBody(type, name, lineDelimiter);
+				if (st != null) {
+					catchClause.getBody().statements().add(st);
+				}
+				fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(decl.getType()), i == 0);
+				fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false);
+			}
+		} else {
 			CatchClause catchClause= getAST().newCatchClause();
-			tryStatement.catchClauses().add(catchClause);
 			SingleVariableDeclaration decl= getAST().newSingleVariableDeclaration();
 			String varName= StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
-
 			String name= fScope.createName(varName, false);
 			decl.setName(getAST().newSimpleName(name));
-			decl.setType(ASTNodeFactory.newType(getAST(), type));
+
+			UnionType unionType= getAST().newUnionType();
+			List<Type> types= unionType.types();
+			for (int i= 0; i < exceptions.length; i++) {
+				ITypeBinding exception= exceptions[i];
+				Type type= fImportRewrite.addImport(exception, getAST(), context);
+				types.add(type);
+				fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(type), i == 0);
+			}
+
+			decl.setType(unionType);
 			catchClause.setException(decl);
-			Statement st= getCatchBody(type, name, lineDelimiter);
+			fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + 0, true).addPosition(fRewriter.track(decl.getName()), false);
+			Statement st= getCatchBody("Exception", name, lineDelimiter); //$NON-NLS-1$
 			if (st != null) {
 				catchClause.getBody().statements().add(st);
 			}
-			fLinkedProposalModel.getPositionGroup(GROUP_EXC_TYPE + i, true).addPosition(fRewriter.track(decl.getType()), i == 0);
-			fLinkedProposalModel.getPositionGroup(GROUP_EXC_NAME + i, true).addPosition(fRewriter.track(decl.getName()), false);
+			tryStatement.catchClauses().add(catchClause);
 		}
 		List<ASTNode> variableDeclarations= getSpecialVariableDeclarationStatements();
 		ListRewrite statements= fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java
index 601f8cf..bef5a84 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/typeconstraints/FullConstraintCreator.java
@@ -585,6 +585,9 @@
 
 	private ITypeConstraint[] getArgumentConstraints(List<Expression> arguments, IMethodBinding methodBinding) {
 		List<ITypeConstraint> result= new ArrayList<ITypeConstraint>(arguments.size());
+		
+		if (methodBinding == null)
+			return new ITypeConstraint[0];
 
 		if (methodBinding.isVarargs()) {
 			ITypeBinding[] parameterTypes= methodBinding.getParameterTypes();
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
index abfefac..3392963 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/util/AbstractExceptionAnalyzer.java
@@ -15,17 +15,24 @@
 import java.util.List;
 import java.util.Stack;
 
+import org.eclipse.jdt.core.dom.AST;
 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.CatchClause;
 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
 import org.eclipse.jdt.core.dom.EnumDeclaration;
+import org.eclipse.jdt.core.dom.IMethodBinding;
 import org.eclipse.jdt.core.dom.ITypeBinding;
 import org.eclipse.jdt.core.dom.MethodInvocation;
 import org.eclipse.jdt.core.dom.ThrowStatement;
 import org.eclipse.jdt.core.dom.TryStatement;
+import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+
+import org.eclipse.jdt.internal.corext.dom.Bindings;
 
 public abstract class AbstractExceptionAnalyzer extends ASTVisitor {
 
@@ -85,6 +92,13 @@
 		// visit try block
 		node.getBody().accept(this);
 
+		if (node.getAST().apiLevel() >= AST.JLS4) {
+			List<VariableDeclarationExpression> resources= node.resources();
+			for (Iterator<VariableDeclarationExpression> iterator= resources.iterator(); iterator.hasNext();) {
+				iterator.next().accept(this);
+			}
+		}
+
 		// Remove those exceptions that get catch by following catch blocks
 		List<CatchClause> catchClauses= node.catchClauses();
 		if (!catchClauses.isEmpty())
@@ -106,6 +120,22 @@
 		return false;
 	}
 
+	@Override
+	public boolean visit(VariableDeclarationExpression node) {
+		if (node.getAST().apiLevel() >= AST.JLS4 && node.getLocationInParent() == TryStatement.RESOURCES_PROPERTY) {
+			Type type= node.getType();
+			ITypeBinding resourceTypeBinding= type.resolveBinding();
+			if (resourceTypeBinding != null) {
+				IMethodBinding methodBinding= Bindings.findMethodInHierarchy(resourceTypeBinding, "close", new ITypeBinding[0]); //$NON-NLS-1$
+				if (methodBinding != null) {
+					addExceptions(methodBinding.getExceptionTypes());
+				}
+			}
+		}
+		return super.visit(node);
+	}
+
+
 	protected void addExceptions(ITypeBinding[] exceptions) {
 		if(exceptions == null)
 			return;
@@ -125,18 +155,28 @@
 
 	private void handleCatchArguments(List<CatchClause> catchClauses) {
 		for (Iterator<CatchClause> iter= catchClauses.iterator(); iter.hasNext(); ) {
-			CatchClause clause= iter.next();
-			ITypeBinding catchTypeBinding= clause.getException().getType().resolveBinding();
-			if (catchTypeBinding == null)	// No correct type resolve.
-				continue;
-			for (Iterator<ITypeBinding> exceptions= new ArrayList<ITypeBinding>(fCurrentExceptions).iterator(); exceptions.hasNext(); ) {
-				ITypeBinding throwTypeBinding= exceptions.next();
-				if (catches(catchTypeBinding, throwTypeBinding))
-					fCurrentExceptions.remove(throwTypeBinding);
+			Type type= iter.next().getException().getType();
+			if (type instanceof UnionType) {
+				List<Type> types= ((UnionType) type).types();
+				for (Iterator<Type> iterator= types.iterator(); iterator.hasNext();) {
+					removeCaughtExceptions(iterator.next().resolveBinding());
+				}
+			} else {
+				removeCaughtExceptions(type.resolveBinding());
 			}
 		}
 	}
 
+	private void removeCaughtExceptions(ITypeBinding catchTypeBinding) {
+		if (catchTypeBinding == null)
+			return;
+		for (Iterator<ITypeBinding> exceptions= new ArrayList<ITypeBinding>(fCurrentExceptions).iterator(); exceptions.hasNext();) {
+			ITypeBinding throwTypeBinding= exceptions.next();
+			if (catches(catchTypeBinding, throwTypeBinding))
+				fCurrentExceptions.remove(throwTypeBinding);
+		}
+	}
+
 	private boolean catches(ITypeBinding catchTypeBinding, ITypeBinding throwTypeBinding) {
 		while(throwTypeBinding != null) {
 			if (throwTypeBinding == catchTypeBinding)
diff --git a/org.eclipse.jdt.ui/plugin.properties b/org.eclipse.jdt.ui/plugin.properties
index e35fd5f..f37ce20 100644
--- a/org.eclipse.jdt.ui/plugin.properties
+++ b/org.eclipse.jdt.ui/plugin.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2010 IBM Corporation and others.
+# Copyright (c) 2000, 2011 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -103,7 +103,7 @@
 
 preferenceKeywords.codetemplates=Java comment code getter setter Javadoc codestyle override constructor file type field method override overriding catch body project specific
 preferenceKeywords.organizeimports=Java static imports order codestyle project specific packages
-preferenceKeywords.compliance=Java compliance level identifier assert enum debug compatibility jdk 1.1 1.2 1.3 1.4 1.5 5.0 1.6 6.0 CLDC J2SE5 classfile compiler project specific projectspecific
+preferenceKeywords.compliance=Java compliance level identifier assert enum debug compatibility jdk 1.1 1.2 1.3 1.4 1.5 5.0 1.6 6 1.7 7 CLDC J2SE5 classfile compiler project specific projectspecific
 preferenceKeywords.building=Java build path buildpath problem exclusion inclusion pattern folder outputfolder filtered resource output compiler 1.5 5.0 J2SE5 project specific projectspecific strictly compatible JRE execution environment
 preferenceKeywords.severities=Java errors warnings ignore compiler options nls externalize string severity severities jdk 5.0 1.5 J2SE5 deprecated static access member serializable serialVersionUID assignment effect finally empty char array catch shadowing package visible interface object method deprecated forbidden discouraged reference unused code unnecessary import imports private cast instanceof local variable parameter thrown exception final type bound generic vararg boxing unboxing autoboxing annotation @Override @Deprecated @SuppressWarnings enum constants switch project specific projectspecific raw null synchronized problem identical equals hashcode dead code missing
 preferenceKeywords.javadocproblems=Java tag problem missing deprecated non visible severity severities level comment compiler project specific projectspecific
@@ -698,6 +698,9 @@
 ActionDefinition.surroundWith.tryCatch.name= Surround with try/catch Block
 ActionDefinition.surroundWith.tryCatch.description= Surround the selected text with a try/catch block
 
+ActionDefinition.surroundWith.tryMultiCatch.name= Surround with try/multi-catch Block
+ActionDefinition.surroundWith.tryMultiCatch.description= Surround the selected text with a try/multi-catch block
+
 ActionDefinition.surroundWith.quickMenu.name= Surround With Quick Menu
 ActionDefinition.surroundWith.quickMenu.description= Shows the Surround With quick menu
 
diff --git a/org.eclipse.jdt.ui/plugin.xml b/org.eclipse.jdt.ui/plugin.xml
index 436c1a6..d9c4a9b 100644
--- a/org.eclipse.jdt.ui/plugin.xml
+++ b/org.eclipse.jdt.ui/plugin.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?eclipse version="3.0"?>
 <!-- ====================================================================== -->
-<!-- Copyright (c) 2000, 2010 IBM Corporation and others.                   -->
+<!-- Copyright (c) 2000, 2011 IBM Corporation and others.                   -->
 <!-- All rights reserved. This program and the accompanying materials       -->
 <!-- are made available under the terms of the Eclipse Public License v1.0  -->
 <!-- which accompanies this distribution, and is available at               -->
@@ -3515,6 +3515,12 @@
             id="org.eclipse.jdt.ui.edit.text.java.surround.with.try.catch">
       </command>
       <command
+            name="%ActionDefinition.surroundWith.tryMultiCatch.name"
+            description="%ActionDefinition.surroundWith.tryMultiCatch.description"
+            categoryId="org.eclipse.jdt.ui.category.source"
+            id="org.eclipse.jdt.ui.edit.text.java.surround.with.try.multicatch">
+      </command>
+      <command
             name="%ActionDefinition.cleanUp.name"
             description="%ActionDefinition.cleanUp.description"
             categoryId="org.eclipse.jdt.ui.category.source"
diff --git a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringMessages.java b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringMessages.java
index 92b106c..eb609e3 100644
--- a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringMessages.java
+++ b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/RefactoringMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -958,10 +958,16 @@
 
 	public static String SurroundWithTryCatchAction_dialog_title;
 
+	public static String SurroundWithTryMultiCatchAction_dialog_title;
+
 	public static String SurroundWithTryCatchAction_exception;
 
 	public static String SurroundWithTryCatchAction_label;
 
+	public static String SurroundWithTryMultiCatchAction_label;
+
+	public static String SurroundWithTryMultiCatchAction_not17;
+
 	public static String UseSupertypeAction_to_activate;
 
 	public static String UseSupertypeAction_use_Supertype;
diff --git a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/refactoringui.properties b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/refactoringui.properties
index 702ba77..6f06d5e 100644
--- a/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/refactoringui.properties
+++ b/org.eclipse.jdt.ui/ui refactoring/org/eclipse/jdt/internal/ui/refactoring/refactoringui.properties
@@ -1,5 +1,5 @@
 ###############################################################################
-# Copyright (c) 2000, 2010 IBM Corporation and others.
+# Copyright (c) 2000, 2011 IBM Corporation and others.
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Eclipse Public License v1.0
 # which accompanies this distribution, and is available at
@@ -30,7 +30,10 @@
 ExtractMethodAction_dialog_title=Extract Method
 
 SurroundWithTryCatchAction_label=Surround with tr&y/catch Block
+SurroundWithTryMultiCatchAction_label=Surround with t&ry/multi-catch Block
 SurroundWithTryCatchAction_dialog_title=Surround with try/catch
+SurroundWithTryMultiCatchAction_dialog_title=Surround with try/multi-catch
+SurroundWithTryMultiCatchAction_not17=Project ''{0}'' cannot be processed since its compiler source level is below 1.7.
 SurroundWithTryCatchAction_exception=An unexpected exception occurred. See the error log for more details.
 
 RefactoringGroup_modify_Parameters_label=&Change Method Signature...
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java
index 40d5f89..15b838f 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.java
@@ -371,6 +371,7 @@
 	public static String SurroundWithTemplateMenuAction_NoneApplicable;
 	public static String SurroundWithTemplateMenuAction_SurroundWithTemplateSubMenuName;
 	public static String SurroundWithTemplateMenuAction_SurroundWithTryCatchActionName;
+	public static String SurroundWithTemplateMenuAction_SurroundWithTryMultiCatchActionName;
 
 	public static String ToggleLinkingAction_label;
 	public static String ToggleLinkingAction_tooltip;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties
index 6851be4..5b96a9f 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/ActionMessages.properties
@@ -446,6 +446,7 @@
 
 SurroundWithTemplateMenuAction_SurroundWithTemplateSubMenuName=Surround &With
 SurroundWithTemplateMenuAction_SurroundWithTryCatchActionName=Tr&y/catch Block
+SurroundWithTemplateMenuAction_SurroundWithTryMultiCatchActionName=T&ry/multi-catch Block
 SurroundWithTemplateMenuAction_ConfigureTemplatesActionName=&Configure Templates...
 SurroundWithTemplateMenuAction_NoneApplicable=(no template applicable)
 IntroduceParameterObjectAction_action_text=Introduce &Parameter Object...
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithActionGroup.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithActionGroup.java
index 6d84107..cac2f12 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithActionGroup.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithActionGroup.java
@@ -25,6 +25,7 @@
 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
 import org.eclipse.jdt.ui.actions.JdtActionConstants;
 import org.eclipse.jdt.ui.actions.SurroundWithTryCatchAction;
+import org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatchAction;
 
 import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
 
@@ -32,17 +33,20 @@
 
 	private CompilationUnitEditor fEditor;
 	private SurroundWithTryCatchAction fSurroundWithTryCatchAction;
+	private SurroundWithTryMultiCatchAction fSurroundWithTryMultiCatchAction;
 	private final String fGroup;
 
 	public SurroundWithActionGroup(CompilationUnitEditor editor, String group) {
 		fEditor= editor;
 		fGroup= group;
 		fSurroundWithTryCatchAction= createSurroundWithTryCatchAction(fEditor);
+		fSurroundWithTryMultiCatchAction= createSurroundWithTryMultiCatchAction(fEditor);
 	}
 
 	@Override
 	public void fillActionBars(IActionBars actionBar) {
 		actionBar.setGlobalActionHandler(JdtActionConstants.SURROUND_WITH_TRY_CATCH, fSurroundWithTryCatchAction);
+		actionBar.setGlobalActionHandler(JdtActionConstants.SURROUND_WITH_TRY_MULTI_CATCH, fSurroundWithTryMultiCatchAction);
 	}
 
 	/**
@@ -72,7 +76,7 @@
 		subMenu.addMenuListener(new IMenuListener() {
 			public void menuAboutToShow(IMenuManager manager) {
 				manager.removeAll();
-				SurroundWithTemplateMenuAction.fillMenu(manager, fEditor, fSurroundWithTryCatchAction);
+				SurroundWithTemplateMenuAction.fillMenu(manager, fEditor, fSurroundWithTryCatchAction, fSurroundWithTryMultiCatchAction);
 			}
 		});
 	}
@@ -84,4 +88,12 @@
 		editor.setAction("SurroundWithTryCatch", result); //$NON-NLS-1$
 		return result;
 	}
+
+	private static SurroundWithTryMultiCatchAction createSurroundWithTryMultiCatchAction(CompilationUnitEditor editor) {
+		SurroundWithTryMultiCatchAction result= new SurroundWithTryMultiCatchAction(editor);
+		result.setText(ActionMessages.SurroundWithTemplateMenuAction_SurroundWithTryMultiCatchActionName);
+		result.setActionDefinitionId(IJavaEditorActionDefinitionIds.SURROUND_WITH_TRY_MULTI_CATCH);
+		editor.setAction("SurroundWithTryMultiCatch", result); //$NON-NLS-1$
+		return result;
+	}
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithTemplateMenuAction.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithTemplateMenuAction.java
index fd250a2..62afd14 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithTemplateMenuAction.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/actions/SurroundWithTemplateMenuAction.java
@@ -58,6 +58,7 @@
 import org.eclipse.jdt.ui.JavaUI;
 import org.eclipse.jdt.ui.actions.IJavaEditorActionDefinitionIds;
 import org.eclipse.jdt.ui.actions.SurroundWithTryCatchAction;
+import org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatchAction;
 import org.eclipse.jdt.ui.text.IJavaPartitions;
 import org.eclipse.jdt.ui.text.java.IInvocationContext;
 import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal;
@@ -164,18 +165,22 @@
 		return fMenu;
 	}
 
-	public static void fillMenu(IMenuManager menu, CompilationUnitEditor editor, SurroundWithTryCatchAction surroundWithTryCatchAction) {
+	public static void fillMenu(IMenuManager menu, CompilationUnitEditor editor, SurroundWithTryCatchAction surroundWithTryCatchAction, SurroundWithTryMultiCatchAction surroundWithTryMultiCatchAction) {
 		IAction[] actions= getTemplateActions(editor);
 
 		surroundWithTryCatchAction.update(editor.getSelectionProvider().getSelection());
-		boolean addSurroundWithAction= surroundWithTryCatchAction.isEnabled() && !isInJavadoc(editor);
+		boolean addSurroundWithTryCatchAction= surroundWithTryCatchAction.isEnabled() && !isInJavadoc(editor);
+		boolean addSurroundWithTryMultiCatchAction= surroundWithTryMultiCatchAction.isEnabled() && !isInJavadoc(editor);
 
-		if ((actions == null || actions.length == 0) && !addSurroundWithAction) {
+		if ((actions == null || actions.length == 0) && (!addSurroundWithTryCatchAction && !addSurroundWithTryMultiCatchAction)) {
 			menu.add(NONE_APPLICABLE_ACTION);
 		} else {
-			if (addSurroundWithAction)
+			if (addSurroundWithTryCatchAction)
 				menu.add(surroundWithTryCatchAction);
 
+			if (addSurroundWithTryMultiCatchAction)
+				menu.add(surroundWithTryMultiCatchAction);
+
 			menu.add(new Separator(TEMPLATE_GROUP));
 			for (int i= 0; actions != null && i < actions.length; i++)
 				menu.add(actions[i]);
@@ -229,7 +234,8 @@
 			@Override
 			protected void fillMenu(IMenuManager menu) {
 				SurroundWithTryCatchAction surroundWithTryCatch= createSurroundWithTryCatchAction(editor);
-				SurroundWithTemplateMenuAction.fillMenu(menu, editor, surroundWithTryCatch);
+				SurroundWithTryMultiCatchAction surroundWithTryMultiCatch= createSurroundWithTryMultiCatchAction(editor);
+				SurroundWithTemplateMenuAction.fillMenu(menu, editor, surroundWithTryCatch, surroundWithTryMultiCatch);
 			}
 		}.createMenu();
 	}
@@ -265,9 +271,13 @@
 
 		boolean addSurroundWith= !isInJavadoc(editor);
 		if (addSurroundWith) {
-			SurroundWithTryCatchAction surroundAction= createSurroundWithTryCatchAction(editor);
-			ActionContributionItem surroundItem= new ActionContributionItem(surroundAction);
-			surroundItem.fill(menu, -1);
+			SurroundWithTryCatchAction surroundWithTryCatch= createSurroundWithTryCatchAction(editor);
+			SurroundWithTryMultiCatchAction surroundWithTryMultiCatch= createSurroundWithTryMultiCatchAction(editor);
+
+			ActionContributionItem surroundWithTryCatchItem= new ActionContributionItem(surroundWithTryCatch);
+			ActionContributionItem surroundWithTryMultiCatchItem= new ActionContributionItem(surroundWithTryMultiCatch);
+			surroundWithTryCatchItem.fill(menu, -1);
+			surroundWithTryMultiCatchItem.fill(menu, -1);
 		}
 
 
@@ -303,6 +313,14 @@
 		return result;
 	}
 
+	private static SurroundWithTryMultiCatchAction createSurroundWithTryMultiCatchAction(CompilationUnitEditor editor) {
+		SurroundWithTryMultiCatchAction result= new SurroundWithTryMultiCatchAction(editor);
+		result.setText(ActionMessages.SurroundWithTemplateMenuAction_SurroundWithTryMultiCatchActionName);
+		result.setActionDefinitionId(IJavaEditorActionDefinitionIds.SURROUND_WITH_TRY_MULTI_CATCH);
+		editor.setAction("SurroundWithTryMultiCatch", result); //$NON-NLS-1$
+		return result;
+	}
+
 	protected void initMenu() {
 		fMenu.addMenuListener(new MenuAdapter() {
 			@Override
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ASTProvider.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ASTProvider.java
index 8ce57b0..a405ae2 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ASTProvider.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/ASTProvider.java
@@ -202,7 +202,7 @@
 		}
 	}
 
-	public static final int SHARED_AST_LEVEL= AST.JLS3;
+	public static final int SHARED_AST_LEVEL= AST.JLS4;
 	public static final boolean SHARED_AST_STATEMENT_RECOVERY= true;
 	public static final boolean SHARED_BINDING_RECOVERY= true;
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java
index 4396dcb..260d01a 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java
@@ -155,6 +155,7 @@
 	public static String JavaElementImplementationHyperlink_hyperlinkText_qualified;
 	public static String JavaElementImplementationHyperlink_search_method_implementors;
 	public static String JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified;
+	public static String JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified_signature;
 	public static String JavaElementDeclaredTypeHyperlink_hyperlinkText;
 	public static String JavaElementDeclaredTypeHyperlink_error_msg;
 	public static String JavaElementReturnTypeHyperlink_hyperlinkText_qualified;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.properties
index b200798..503e829 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.properties
@@ -140,6 +140,7 @@
 JavaElementImplementationHyperlink_hyperlinkText_qualified=Open Implementation for ''{0}''
 JavaElementImplementationHyperlink_search_method_implementors=Searching for implementors of ''{0}''...
 JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified=Open Declared Type for ''{0}''
+JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified_signature=Open Declared Type ''{0}''
 JavaElementDeclaredTypeHyperlink_hyperlinkText=Open Declared Type
 JavaElementDeclaredTypeHyperlink_error_msg= Cannot open the declared type as it is either primitive or cannot be resolved.
 JavaElementReturnTypeHyperlink_hyperlinkText_qualified=Open Return Type for ''{0}''
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementDeclaredTypeHyperlink.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementDeclaredTypeHyperlink.java
index 3d7df13..f258c82 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementDeclaredTypeHyperlink.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementDeclaredTypeHyperlink.java
@@ -46,6 +46,7 @@
 	private final IRegion fRegion;
 	private final SelectionDispatchAction fOpenAction;
 	private final IJavaElement fElement;
+	private final String fTypeSig;
 	private final boolean fQualify;
 	
 	/**
@@ -58,6 +59,20 @@
 	 *            element.
 	 */
 	public JavaElementDeclaredTypeHyperlink(IRegion region, SelectionDispatchAction openAction, IJavaElement element, boolean qualify) {
+		this(region, openAction, element, null, qualify);
+	}
+
+	/**
+	 * Creates a new Java element declared type hyperlink for variables.
+	 * 
+	 * @param region the region of the link
+	 * @param openAction the action to use to open the Java elements
+	 * @param element the Java element to open
+	 * @param typeSig the signature of the type to open
+	 * @param qualify <code>true</code> if the hyperlink text should show a qualified name for
+	 *            element.
+	 */
+	public JavaElementDeclaredTypeHyperlink(IRegion region, SelectionDispatchAction openAction, IJavaElement element, String typeSig, boolean qualify) {
 		Assert.isNotNull(openAction);
 		Assert.isNotNull(region);
 		Assert.isNotNull(element);
@@ -65,6 +80,7 @@
 		fRegion= region;
 		fOpenAction= openAction;
 		fElement= element;
+		fTypeSig= typeSig;
 		fQualify= qualify;
 	}
 
@@ -87,8 +103,13 @@
 	 */
 	public String getHyperlinkText() {
 		if (fQualify) {
-			String elementLabel= JavaElementLabels.getElementLabel(fElement, JavaElementLabels.ALL_FULLY_QUALIFIED);
-			return Messages.format(JavaEditorMessages.JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified, new Object[] { elementLabel });
+			if (fTypeSig == null) {
+				String elementLabel= JavaElementLabels.getElementLabel(fElement, JavaElementLabels.ALL_FULLY_QUALIFIED);
+				return Messages.format(JavaEditorMessages.JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified, new Object[] { elementLabel });
+			} else {
+				String type= Signature.toString(fTypeSig);
+				return Messages.format(JavaEditorMessages.JavaElementDeclaredTypeHyperlink_hyperlinkText_qualified_signature, new Object[] { type });
+			}
 		} else {
 			return JavaEditorMessages.JavaElementDeclaredTypeHyperlink_hyperlinkText;
 		}
@@ -98,12 +119,14 @@
 	 * @see org.eclipse.jface.text.hyperlink.IHyperlink#open()
 	 */
 	public void open() {
-		String typeSignature;
-		try {
-			typeSignature= JavaElementHyperlinkDeclaredTypeDetector.getTypeSignature(fElement);
-		} catch (JavaModelException e) {
-			JavaPlugin.log(e);
-			return;
+		String typeSignature= fTypeSig;
+		if (typeSignature == null) {
+			try {
+				typeSignature= JavaElementHyperlinkDeclaredTypeDetector.getTypeSignature(fElement);
+			} catch (JavaModelException e) {
+				JavaPlugin.log(e);
+				return;
+			}
 		}
 		int kind= Signature.getTypeSignatureKind(typeSignature);
 		if (kind == Signature.ARRAY_TYPE_SIGNATURE) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDeclaredTypeDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDeclaredTypeDetector.java
index 97d49cb..cb9efa7 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDeclaredTypeDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDeclaredTypeDetector.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.ui.javaeditor;
 
+import java.util.List;
+
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
 
@@ -17,6 +19,7 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.ILocalVariable;
 import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
 
 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
 
@@ -37,16 +40,25 @@
 	 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaElementHyperlinkDetector#createHyperlink(org.eclipse.jface.text.IRegion, org.eclipse.jdt.ui.actions.SelectionDispatchAction, org.eclipse.jdt.core.IJavaElement, boolean, org.eclipse.jdt.internal.ui.javaeditor.JavaEditor)
 	 */
 	@Override
-	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
+	protected void addHyperlinks(List<IHyperlink> hyperlinksCollector, IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
 		try {
-			if ((element.getElementType() == IJavaElement.FIELD || element.getElementType() == IJavaElement.LOCAL_VARIABLE) && !JavaModelUtil.isPrimitive(getTypeSignature(element))
-					&& SelectionConverter.canOperateOn(editor)) {
-				return new JavaElementDeclaredTypeHyperlink(wordRegion, openAction, element, qualify);
+			if (element.getElementType() == IJavaElement.FIELD || element.getElementType() == IJavaElement.LOCAL_VARIABLE) {
+				String typeSignature= getTypeSignature(element);
+				if (!JavaModelUtil.isPrimitive(typeSignature) && SelectionConverter.canOperateOn(editor)) {
+					if (Signature.getTypeSignatureKind(typeSignature) == Signature.INTERSECTION_TYPE_SIGNATURE) {
+						String[] bounds= Signature.getIntersectionTypeBounds(typeSignature);
+						qualify|= bounds.length >= 2;
+						for (int i= 0; i < bounds.length; i++) {
+							hyperlinksCollector.add(new JavaElementDeclaredTypeHyperlink(wordRegion, openAction, element, bounds[i], qualify));
+						}
+					} else {
+						hyperlinksCollector.add(new JavaElementDeclaredTypeHyperlink(wordRegion, openAction, element, qualify));
+					}
+				}
 			}
 		} catch (JavaModelException e) {
 			JavaPlugin.log(e);
 		}
-		return null;
 	}
 
 	/**
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDetector.java
index 7a4f319..7149585 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkDetector.java
@@ -36,6 +36,8 @@
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
 
+import org.eclipse.jdt.internal.corext.util.CollectionsUtil;
+
 import org.eclipse.jdt.ui.SharedASTProvider;
 import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
 
@@ -86,22 +88,14 @@
 			if (elements.length == 0)
 				return null;
 			
-			IHyperlink[] links= new IHyperlink[elements.length];
-			int j= 0;
+			ArrayList<IHyperlink> links= new ArrayList<IHyperlink>(elements.length);
 			for (int i= 0; i < elements.length; i++) {
-				IHyperlink link= createHyperlink(wordRegion, (SelectionDispatchAction)openAction, elements[i], elements.length > 1, (JavaEditor)textEditor);
-				if (link != null) {
-					links[j++]= link;
-				}
+				addHyperlinks(links, wordRegion, (SelectionDispatchAction)openAction, elements[i], elements.length > 1, (JavaEditor)textEditor);
 			}
-			if (j == 0) {
+			if (links.size() == 0)
 				return null;
-			} else if (j < elements.length) {
-				IHyperlink[] result= new IHyperlink[j];
-				System.arraycopy(links, 0, result, 0, j);
-				return result;
-			}
-			return links;
+			
+			return CollectionsUtil.toArray(links, IHyperlink.class);
 
 		} catch (JavaModelException e) {
 			return null;
@@ -126,20 +120,20 @@
 	}
 
 	/**
-	 * Creates a java element hyperlink.
+	 * Creates and adds Java element hyperlinks.
 	 * 
+	 * @param hyperlinksCollector the list to which hyperlinks should be added
 	 * @param wordRegion the region of the link
-	 * @param openAction the action to use to open the java elements
-	 * @param element the java element to open
+	 * @param openAction the action to use to open the Java elements
+	 * @param element the Java element to open
 	 * @param qualify <code>true</code> if the hyperlink text should show a qualified name for
 	 *            element
-	 * @param editor the active java editor
-	 * @return a Java element hyperlink or <code>null</code> if no hyperlink can be created for the
-	 *         given arguments
+	 * @param editor the active Java editor
+	 * 
 	 * @since 3.5
 	 */
-	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
-		return new JavaElementHyperlink(wordRegion, openAction, element, qualify);
+	protected void addHyperlinks(List<IHyperlink> hyperlinksCollector, IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
+		hyperlinksCollector.add(new JavaElementHyperlink(wordRegion, openAction, element, qualify));
 	}
 
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkImplementationDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkImplementationDetector.java
index e60b6d5..2c8ac99 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkImplementationDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkImplementationDetector.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.ui.javaeditor;
 
+import java.util.List;
+
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
 
@@ -33,10 +35,9 @@
 	 * @since 3.5
 	 */
 	@Override
-	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
+	protected void addHyperlinks(List<IHyperlink> hyperlinksCollector, IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
 		if (element.getElementType() == IJavaElement.METHOD && SelectionConverter.canOperateOn(editor)) {
-			return new JavaElementImplementationHyperlink(wordRegion, openAction, (IMethod)element, qualify, editor);
+			hyperlinksCollector.add(new JavaElementImplementationHyperlink(wordRegion, openAction, (IMethod)element, qualify, editor));
 		}
-		return null;
 	}
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkReturnTypeDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkReturnTypeDetector.java
index 524686d..5d2aae9 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkReturnTypeDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkReturnTypeDetector.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.ui.javaeditor;
 
+import java.util.List;
+
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
 
@@ -36,14 +38,13 @@
 	 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaElementHyperlinkDetector#createHyperlink(org.eclipse.jface.text.IRegion, org.eclipse.jdt.ui.actions.SelectionDispatchAction, org.eclipse.jdt.core.IJavaElement, boolean, org.eclipse.jdt.internal.ui.javaeditor.JavaEditor)
 	 */
 	@Override
-	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
+	protected void addHyperlinks(List<IHyperlink> hyperlinksCollector, IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
 		try {
 			if (element.getElementType() == IJavaElement.METHOD && !JavaModelUtil.isPrimitive(((IMethod)element).getReturnType()) && SelectionConverter.canOperateOn(editor)) {
-				return new JavaElementReturnTypeHyperlink(wordRegion, openAction, (IMethod)element, qualify);
+				hyperlinksCollector.add(new JavaElementReturnTypeHyperlink(wordRegion, openAction, (IMethod)element, qualify));
 			}
 		} catch (JavaModelException e) {
 			JavaPlugin.log(e);
 		}
-		return null;
 	}
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkSuperImplementationDetector.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkSuperImplementationDetector.java
index 5fc2b14..9906d74 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkSuperImplementationDetector.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaElementHyperlinkSuperImplementationDetector.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.ui.javaeditor;
 
+import java.util.List;
+
 import org.eclipse.jface.text.IRegion;
 import org.eclipse.jface.text.hyperlink.IHyperlink;
 
@@ -35,11 +37,10 @@
 	 * @since 3.7
 	 */
 	@Override
-	protected IHyperlink createHyperlink(IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
+	protected void addHyperlinks(List<IHyperlink> hyperlinksCollector, IRegion wordRegion, SelectionDispatchAction openAction, IJavaElement element, boolean qualify, JavaEditor editor) {
 		if (element.getElementType() == IJavaElement.METHOD && SelectionConverter.canOperateOn(editor) && isOverriddenMethod((IMethod)element)) {
-			return new JavaElementSuperImplementationHyperlink(wordRegion, openAction, (IMethod)element, qualify);
+			hyperlinksCollector.add(new JavaElementSuperImplementationHyperlink(wordRegion, openAction, (IMethod)element, qualify));
 		}
-		return null;
 	}
 
 	/**
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
index e8108dd..eb1e377 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java
@@ -264,6 +264,7 @@
 	public static String ProblemSeveritiesConfigurationBlock_ignore_documented_unused_parameters;
 	public static String ProblemSeveritiesConfigurationBlock_pb_redundant_null_check;
 	public static String ProblemSeveritiesConfigurationBlock_pb_redundant_super_interface_label;
+	public static String ProblemSeveritiesConfigurationBlock_pb_redundant_type_arguments_label;
 	public static String ProblemSeveritiesConfigurationBlock_include_assert_in_null_analysis;
 	public static String ProblemSeveritiesConfigurationBlock_treat_optional_as_fatal;
 	public static String SourceAttachmentPropertyPage_error_title;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
index b99ddec..b726bc0 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties
@@ -429,6 +429,7 @@
 ProblemSeveritiesConfigurationBlock_pb_parameter_assignment=Parameter assignment:
 ProblemSeveritiesConfigurationBlock_pb_redundant_null_check=Redundant null check:
 ProblemSeveritiesConfigurationBlock_pb_redundant_super_interface_label=Redundant super interface:
+ProblemSeveritiesConfigurationBlock_pb_redundant_type_arguments_label=Redundant type arguments
 ProblemSeveritiesConfigurationBlock_pb_non_externalized_strings_label=Non-externalized strings (missing/unused $NON-NLS$ tag):
 ProblemSeveritiesConfigurationBlock_pb_dead_code=Dead code (e.g. 'if (false)'):
 ProblemSeveritiesConfigurationBlock_pb_deprecation_label=Deprecated API:
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/ProblemSeveritiesConfigurationBlock.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/ProblemSeveritiesConfigurationBlock.java
index 02a513b..ac0707c 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/ProblemSeveritiesConfigurationBlock.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/ProblemSeveritiesConfigurationBlock.java
@@ -103,6 +103,7 @@
 	private static final Key PREF_15_PB_TYPE_PARAMETER_HIDING= getJDTCoreKey(JavaCore.COMPILER_PB_TYPE_PARAMETER_HIDING);
 	private static final Key PREF_15_PB_INCOMPLETE_ENUM_SWITCH= getJDTCoreKey(JavaCore.COMPILER_PB_INCOMPLETE_ENUM_SWITCH);
 	private static final Key PREF_15_PB_RAW_TYPE_REFERENCE= getJDTCoreKey(JavaCore.COMPILER_PB_RAW_TYPE_REFERENCE);
+	private static final Key PREF_17_PB_REDUNDANT_TYPE_ARGUMENTS= getJDTCoreKey(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS);
 	private static final Key PREF_15_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS= getJDTCoreKey(JavaCore.COMPILER_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS);
 
 	private static final Key PREF_PB_SUPPRESS_WARNINGS= getJDTCoreKey(JavaCore.COMPILER_PB_SUPPRESS_WARNINGS);
@@ -161,7 +162,7 @@
 				PREF_15_PB_AUTOBOXING_PROBLEM, PREF_15_PB_MISSING_OVERRIDE_ANNOTATION, PREF_16_PB_MISSING_OVERRIDE_ANNOTATION_FOR_INTERFACE_METHOD_IMPLEMENTATION,
 				PREF_15_PB_ANNOTATION_SUPER_INTERFACE,
 				PREF_15_PB_TYPE_PARAMETER_HIDING, PREF_15_PB_INCOMPLETE_ENUM_SWITCH, PREF_PB_MISSING_DEPRECATED_ANNOTATION,
-				PREF_15_PB_RAW_TYPE_REFERENCE, PREF_15_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS,
+				PREF_15_PB_RAW_TYPE_REFERENCE, PREF_15_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS, PREF_17_PB_REDUNDANT_TYPE_ARGUMENTS,
 				PREF_PB_FATAL_OPTIONAL_ERROR,
 				PREF_PB_FORBIDDEN_REFERENCE, PREF_PB_DISCOURRAGED_REFERENCE,
 				PREF_PB_SUPPRESS_WARNINGS, PREF_PB_SUPPRESS_OPTIONAL_ERRORS,
@@ -457,6 +458,9 @@
 		label= PreferencesMessages.ProblemSeveritiesConfigurationBlock_pb_final_param_bound_label;
 		fFilteredPrefTree.addComboBox(inner, label, PREF_15_PB_FINAL_PARAM_BOUND, errorWarningIgnore, errorWarningIgnoreLabels, defaultIndent, section);
 
+		label= PreferencesMessages.ProblemSeveritiesConfigurationBlock_pb_redundant_type_arguments_label;
+		fFilteredPrefTree.addComboBox(inner, label, PREF_17_PB_REDUNDANT_TYPE_ARGUMENTS, errorWarningIgnore, errorWarningIgnoreLabels, defaultIndent, section);
+
 		label= PreferencesMessages.ProblemSeveritiesConfigurationBlock_pb_unavoidable_generic_type_problems;
 		fFilteredPrefTree.addCheckBox(inner, label, PREF_15_PB_UNAVOIDABLE_GENERIC_TYPE_PROBLEMS, disabledEnabled, defaultIndent, section);
 		
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.java
index 97380c8..ca0d05a 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     istvan@benedek-home.de - 103706 [formatter] indent empty lines
@@ -82,7 +82,8 @@
 	public static String WhiteSpaceTabPage_switch_before_default_colon;
 	public static String WhiteSpaceTabPage_do;
 	public static String WhiteSpaceTabPage_synchronized;
-	public static String WhiteSpaceTabPage_try;
+	public static String WhiteSpaceTabPage_catch;
+	public static String WhiteSpaceTabPage_tryWithResources;
 	public static String WhiteSpaceTabPage_if;
 	public static String WhiteSpaceTabPage_assert;
 	public static String WhiteSpaceTabPage_for;
@@ -167,6 +168,7 @@
 	public static String WhiteSpaceOptions_postfix_operator;
 	public static String WhiteSpaceOptions_opening_paren;
 	public static String WhiteSpaceOptions_catch;
+	public static String WhiteSpaceOptions_try;
 	public static String WhiteSpaceOptions_for;
 	public static String WhiteSpaceOptions_if;
 	public static String WhiteSpaceOptions_switch;
@@ -262,6 +264,7 @@
 	public static String WhiteSpaceOptions_after_ellipsis;
 	public static String WhiteSpaceOptions_return_with_parenthesized_expression;
 	public static String WhiteSpaceOptions_throw_with_parenthesized_expression;
+	public static String LineWrappingTabPage_catch;
 	public static String LineWrappingTabPage_compact_if_else;
 	public static String LineWrappingTabPage_declaration;
 	public static String LineWrappingTabPage_extends_clause;
@@ -272,6 +275,7 @@
 	public static String LineWrappingTabPage_arguments;
 	public static String LineWrappingTabPage_qualified_invocations;
 	public static String LineWrappingTabPage_throws_clause;
+	public static String LineWrappingTabPage_try;
 	public static String LineWrappingTabPage_object_allocation;
 	public static String LineWrappingTabPage_qualified_object_allocation;
 	public static String LineWrappingTabPage_array_init;
@@ -311,6 +315,7 @@
 	public static String LineWrappingTabPage_enum_superinterfaces;
 	public static String LineWrappingTabPage_assignment_alignment;
 	public static String LineWrappingTabPage_binary_expression_wrap_operator;
+	public static String LineWrappingTabPage_multicatch_wrap_operator;
 	public static String LineWrappingTabPage_annotations;
 	public static String LineWrappingTabPage_annotations_arguments;
 	public static String LineWrappingTabPage_wrap_outer_expressions_when_nested;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.properties
index 29c9688..3c2ed08 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/FormatterMessages.properties
@@ -70,7 +70,8 @@
 
 WhiteSpaceTabPage_synchronized='synchronized'
 
-WhiteSpaceTabPage_try='catch'
+WhiteSpaceTabPage_catch='catch'
+WhiteSpaceTabPage_tryWithResources='try-with-resources'
 
 WhiteSpaceTabPage_if='if else'
 WhiteSpaceTabPage_assert='assert'
@@ -181,6 +182,7 @@
 
 WhiteSpaceOptions_opening_paren=Opening parenthesis
 WhiteSpaceOptions_catch='catch'
+WhiteSpaceOptions_try='try-with-resources'
 WhiteSpaceOptions_for='for'
 WhiteSpaceOptions_if='if'
 WhiteSpaceOptions_switch='switch'
@@ -297,6 +299,7 @@
 WhiteSpaceTabPage_insert_space=&Insert space:
 
 
+LineWrappingTabPage_catch='multi-catch'
 LineWrappingTabPage_compact_if_else=Compact 'if else'
 LineWrappingTabPage_declaration=Declaration
 LineWrappingTabPage_extends_clause='extends' clause
@@ -307,6 +310,7 @@
 LineWrappingTabPage_arguments=Arguments
 LineWrappingTabPage_qualified_invocations=Qualified invocations
 LineWrappingTabPage_throws_clause='throws' clause
+LineWrappingTabPage_try='try-with-resources'
 LineWrappingTabPage_object_allocation=Object allocation arguments
 LineWrappingTabPage_qualified_object_allocation=Qualified object allocation arguments
 LineWrappingTabPage_array_init=Array initializers
@@ -350,6 +354,7 @@
 LineWrappingTabPage_wrap_outer_expressions_when_nested=Prefer wrapping &outer expressions (keep nested expression on one line)
 
 LineWrappingTabPage_binary_expression_wrap_operator=Wrap &before operator
+LineWrappingTabPage_multicatch_wrap_operator=Wrap &before '|' operator
 
 BlankLinesTabPage_preview_header=Blank Lines
 BlankLinesTabPage_compilation_unit_group_title=Blank lines in compilation unit
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/JavaPreview.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/JavaPreview.java
index e93f00a..1f7d59b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/JavaPreview.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/JavaPreview.java
@@ -10,7 +10,9 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.ui.preferences.formatter;
 
+import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
@@ -37,9 +39,10 @@
 import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
 
-import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
 
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+
 import org.eclipse.jdt.ui.PreferenceConstants;
 import org.eclipse.jdt.ui.text.IJavaPartitions;
 import org.eclipse.jdt.ui.text.JavaTextTools;
@@ -110,10 +113,11 @@
 		tools.setupJavaDocumentPartitioner( fPreviewDocument, IJavaPartitions.JAVA_PARTITIONING);
 
 		PreferenceStore prioritizedSettings= new PreferenceStore();
-		prioritizedSettings.setValue(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5);
-		prioritizedSettings.setValue(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5);
-		prioritizedSettings.setValue(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5);
-		prioritizedSettings.setValue(JavaCore.COMPILER_PB_ASSERT_IDENTIFIER, JavaCore.ERROR);
+		HashMap<String, String> complianceOptions= new HashMap<String, String>();
+		JavaModelUtil.setComplianceOptions(complianceOptions, JavaModelUtil.VERSION_LATEST);
+		for (Entry<String, String> complianceOption : complianceOptions.entrySet()) {
+			prioritizedSettings.setValue(complianceOption.getKey(), complianceOption.getValue());
+		}
 
 		IPreferenceStore[] chain= { prioritizedSettings, JavaPlugin.getDefault().getCombinedPreferenceStore() };
 		fPreferenceStore= new ChainedPreferenceStore(chain);
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/LineWrappingTabPage.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/LineWrappingTabPage.java
index ae3e09e..0117edd 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/LineWrappingTabPage.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/LineWrappingTabPage.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -99,6 +99,11 @@
 		public Preference[] getSpecificPreferences() {
 			return preferences.toArray(new Preference[preferences.size()]);
 		}
+
+		public void setEnabled(boolean state) {
+			for (Preference preference : preferences)
+				preference.setEnabled(state);
+		}
 	}
 
 
@@ -397,6 +402,29 @@
 	    FormatterMessages.LineWrappingTabPage_compact_if_else
 	);
 
+	private final Category fTryCategory= new Category(
+			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_RESOURCES_IN_TRY,
+			"class Example {" + //$NON-NLS-1$
+			"void foo() {" + //$NON-NLS-1$
+			"try (FileReader reader1 = new FileReader(\"file1\"); " + //$NON-NLS-1$
+			"  FileReader reader2 = new FileReader(\"file2\")) {" + //$NON-NLS-1$
+			"}" + //$NON-NLS-1$
+			"}}", //$NON-NLS-1$
+			FormatterMessages.LineWrappingTabPage_try
+			);
+
+	private final Category fCatchCategory= new Category(
+			DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_UNION_TYPE_IN_MULTICATCH,
+			"class Example {" + //$NON-NLS-1$
+			"void foo() {" + //$NON-NLS-1$
+			"try {" + //$NON-NLS-1$
+			"} catch (IllegalArgumentException | NullPointerException | ClassCastException e) {" + //$NON-NLS-1$
+			"  e.printStackTrace();" + //$NON-NLS-1$
+			"}" + //$NON-NLS-1$
+			"}}", //$NON-NLS-1$
+			FormatterMessages.LineWrappingTabPage_catch
+			);
+
 
 	private final Category fTypeDeclarationSuperclassCategory= new Category(
 	    DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION,
@@ -663,6 +691,8 @@
 
 		final Category statements= new Category(FormatterMessages.LineWrappingTabPage_statements);
 		statements.children.add(fCompactIfCategory);
+		statements.children.add(fTryCategory);
+		statements.children.add(fCatchCategory);
 
 		final List<Category> root= new ArrayList<Category>();
 		root.add(annotations);
@@ -742,6 +772,17 @@
 		layoutData.grabExcessHorizontalSpace= false;
 		fBinaryExpressionCategory.addPreference(expressionWrapPositionPreference);
 		
+		// button "Wrap before '|' operator" in multi-catch
+		Preference expressionWrapMulticatchPositionPreference= createCheckboxPref(fOptionsGroup, 1, FormatterMessages.LineWrappingTabPage_multicatch_wrap_operator, DefaultCodeFormatterConstants.FORMATTER_WRAP_BEFORE_OR_OPERATOR_MULTICATCH, FALSE_TRUE);
+		control= expressionWrapMulticatchPositionPreference.getControl();
+		control.setVisible(false);
+		layoutData= (GridData)control.getLayoutData();
+		layoutData.exclude= true;
+		layoutData.horizontalAlignment= SWT.BEGINNING;
+		layoutData.horizontalSpan= numColumns - 1;
+		layoutData.grabExcessHorizontalSpace= false;
+		fCatchCategory.addPreference(expressionWrapMulticatchPositionPreference);
+		
 		// label "Select indentation style:"
 		fIndentStylePolicy= createLabel(numColumns, fOptionsGroup, FormatterMessages.LineWrappingTabPage_indentation_policy_label_text);
 
@@ -912,7 +953,11 @@
     protected void updateControlEnablement(boolean inhomogenous, int wrappingStyle) {
 	    boolean doSplit= wrappingStyle != DefaultCodeFormatterConstants.WRAP_NO_SPLIT;
 	    fIndentStylePolicy.setEnabled(true);
-	    fIndentStyleCombo.setEnabled(inhomogenous || doSplit);
-	    fForceSplit.setEnabled(inhomogenous || doSplit);
+
+		boolean isEnabled= inhomogenous || doSplit;
+		fIndentStyleCombo.setEnabled(isEnabled);
+		fForceSplit.setEnabled(isEnabled);
+		fBinaryExpressionCategory.setEnabled(isEnabled);
+		fCatchCategory.setEnabled(isEnabled);
 	}
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileManager.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileManager.java
index cd7462b..0ecad5b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileManager.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileManager.java
@@ -810,7 +810,7 @@
 	}
 
 	private static void setLatestCompliance(Map<String, String> map) {
-		JavaModelUtil.set50ComplianceOptions(map);
+		JavaModelUtil.setComplianceOptions(map, JavaModelUtil.VERSION_LATEST);
 	}
 
     public abstract Profile getDefaultProfile();
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersioner.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersioner.java
index d6f8223..fa73418 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersioner.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/ProfileVersioner.java
@@ -121,7 +121,7 @@
 	 * @param map The map to update
 	 */
 	public static void setLatestCompliance(Map<String, String> map) {
-		JavaModelUtil.set50ComplianceOptions(map);
+		JavaModelUtil.setComplianceOptions(map, JavaModelUtil.VERSION_LATEST);
 	}
 
 	private static void version1to2(final Map<String, String> oldSettings) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
index cb3dc0c..73ce3e9 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/formatter/WhiteSpaceOptions.java
@@ -4,13 +4,13 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-
 package org.eclipse.jdt.internal.ui.preferences.formatter;
 
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
@@ -174,6 +174,10 @@
     CodeFormatter.K_STATEMENTS,
     "try { number= Integer.parseInt(value); } catch (NumberFormatException e) {}"); //$NON-NLS-1$
 
+	private final PreviewSnippet TRY_PREVIEW= new PreviewSnippet(
+	CodeFormatter.K_STATEMENTS, 
+	"try (FileReader reader1 = new FileReader(\"file1\"); FileReader reader2 = new FileReader(\"file2\")) {}"); //$NON-NLS-1$
+
     private final PreviewSnippet IF_PREVIEW= new PreviewSnippet(
     CodeFormatter.K_STATEMENTS,
     "if (condition) { return foo; } else {return bar;}"); //$NON-NLS-1$
@@ -321,7 +325,8 @@
 
 	/**
 	 * Create the tree, in this order: syntax element - position - abstract element
-	 * @param workingValues
+	 * 
+	 * @param workingValues the current values
 	 * @return returns roots (type <code>Node</code>)
 	 */
 	public List<InnerNode> createTreeBySyntaxElem(Map<String, String> workingValues) {
@@ -399,11 +404,11 @@
 	}
 
     /**
-     * Create the tree, in this order: position - syntax element - abstract
-     * element
-     * @param workingValues
-     * @return returns roots (type <code>Node</code>)
-     */
+	 * Create the tree, in this order: position - syntax element - abstract element
+	 * 
+	 * @param workingValues the current values
+	 * @return returns roots (type <code>Node</code>)
+	 */
     public List<Node> createAltTree(Map<String, String> workingValues) {
 
         final ArrayList<Node> roots= new ArrayList<Node>();
@@ -543,7 +548,8 @@
         createSwitchStatementTree(workingValues, statements);
         createDoWhileTree(workingValues, statements);
         createSynchronizedTree(workingValues, statements);
-        createTryStatementTree(workingValues, statements);
+		createTryStatementTree(workingValues, statements);
+		createCatchTree(workingValues, statements);
         createAssertTree(workingValues, statements);
         createReturnTree(workingValues, statements);
         createThrowTree(workingValues, statements);
@@ -592,6 +598,7 @@
 
     private void createBeforeSemicolonTree(Map<String, String> workingValues, final InnerNode parent) {
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_for, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_FOR, FOR_PREVIEW);
+		createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_try, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES, TRY_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_statements, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON, SEMICOLON_PREVIEW);
     }
 
@@ -700,6 +707,7 @@
 
     private void createBeforeClosingParenTree(Map<String, String> workingValues, final InnerNode parent) {
 
+		createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_try, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY, TRY_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_catch, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH, CATCH_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_for, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR, FOR_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_if, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF, IF_PREVIEW);
@@ -723,6 +731,7 @@
 
     private void createBeforeOpenParenTree(Map<String, String> workingValues, final InnerNode parent) {
 
+		createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_try, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY, TRY_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_catch, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH, CATCH_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_for, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR, FOR_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_if, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF, IF_PREVIEW);
@@ -770,6 +779,7 @@
 
     private void createAfterSemicolonTree(Map<String, String> workingValues, final InnerNode parent) {
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_for, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_FOR, FOR_PREVIEW);
+		createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_try, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES, TRY_PREVIEW);
     }
 
     private void createAfterColonTree(Map<String, String> workingValues, final InnerNode parent) {
@@ -859,6 +869,7 @@
     }
 
     private void createAfterOpenParenTree(Map<String, String> workingValues, final InnerNode parent) {
+		createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_try, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY, TRY_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_catch, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH, CATCH_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_for, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR, FOR_PREVIEW);
         createOption(parent, workingValues, FormatterMessages.WhiteSpaceOptions_if, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF, IF_PREVIEW);
@@ -1074,14 +1085,26 @@
         return root;
     }
 
-    private InnerNode createTryStatementTree(Map<String, String> workingValues, InnerNode parent) {
-        final InnerNode root= new InnerNode(parent, workingValues, FormatterMessages.WhiteSpaceTabPage_try);
+	private InnerNode createCatchTree(Map<String, String> workingValues, InnerNode parent) {
+		final InnerNode root= new InnerNode(parent, workingValues, FormatterMessages.WhiteSpaceTabPage_catch);
 
         createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_before_opening_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH, CATCH_PREVIEW);
         createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_after_opening_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH, CATCH_PREVIEW);
         createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_before_closing_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH, CATCH_PREVIEW);
         return root;
     }
+
+	private InnerNode createTryStatementTree(Map<String, String> workingValues, InnerNode parent) {
+		final InnerNode root= new InnerNode(parent, workingValues, FormatterMessages.WhiteSpaceTabPage_tryWithResources);
+
+		createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_before_opening_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_TRY, TRY_PREVIEW);
+		createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_after_opening_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_TRY, TRY_PREVIEW);
+		createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_before_semicolon, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_SEMICOLON_IN_TRY_RESOURCES, TRY_PREVIEW);
+		createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_after_semicolon, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_SEMICOLON_IN_TRY_RESOURCES, TRY_PREVIEW);
+		createOption(root, workingValues, FormatterMessages.WhiteSpaceTabPage_before_closing_paren, DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_TRY, TRY_PREVIEW);
+		return root;
+	}
+
     private InnerNode createIfStatementTree(Map<String, String> workingValues, InnerNode parent) {
         final InnerNode root= new InnerNode(parent, workingValues, FormatterMessages.WhiteSpaceTabPage_if);
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java
index c6fdfb8..4ab37a6 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/ExceptionOccurrencesFinder.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -14,10 +14,12 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.ASTMatcher;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.Block;
 import org.eclipse.jdt.core.dom.CastExpression;
 import org.eclipse.jdt.core.dom.CatchClause;
 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
@@ -25,7 +27,6 @@
 import org.eclipse.jdt.core.dom.ConstructorInvocation;
 import org.eclipse.jdt.core.dom.IMethodBinding;
 import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
 import org.eclipse.jdt.core.dom.Javadoc;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.MethodInvocation;
@@ -39,6 +40,9 @@
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 
 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
 import org.eclipse.jdt.internal.corext.dom.Bindings;
@@ -57,6 +61,7 @@
 
 	private ITypeBinding fException;
 	private ASTNode fStart;
+	private TryStatement fTryStatement;
 	private List<OccurrenceLocation> fResult;
 	private String fDescription;
 
@@ -81,15 +86,15 @@
 			fStart= decl.getBody();
 		} else if (parent instanceof Type) {
 			parent= parent.getParent();
+			if (parent instanceof UnionType) {
+				parent= parent.getParent();
+			}
 			if (parent instanceof SingleVariableDeclaration && parent.getParent() instanceof CatchClause) {
 				CatchClause catchClause= (CatchClause)parent.getParent();
-				TryStatement tryStatement= (TryStatement)catchClause.getParent();
-				if (tryStatement != null) {
-					IVariableBinding var= catchClause.getException().resolveBinding();
-					if (var != null && var.getType() != null) {
-						fException= var.getType();
-						fStart= tryStatement.getBody();
-					}
+				fTryStatement= (TryStatement)catchClause.getParent();
+				if (fTryStatement != null) {
+					fException= fSelectedName.resolveTypeBinding();
+					fStart= fTryStatement.getBody();
 				}
 			}
 		}
@@ -122,11 +127,56 @@
 
 	private void performSearch() {
 		fStart.accept(this);
+		if (fTryStatement != null) {
+			visitResourceDeclarations(fTryStatement);
+			handleImplicitResourceClosure(fTryStatement);
+		}
 		if (fSelectedName != null) {
 			fResult.add(new OccurrenceLocation(fSelectedName.getStartPosition(), fSelectedName.getLength(), F_EXCEPTION_DECLARATION, fDescription));
 		}
 	}
 
+	private void visitResourceDeclarations(TryStatement tryStatement) {
+		if (tryStatement.getAST().apiLevel() >= AST.JLS4) {
+			List<VariableDeclarationExpression> resources= tryStatement.resources();
+			for (Iterator<VariableDeclarationExpression> iterator= resources.iterator(); iterator.hasNext();) {
+				iterator.next().accept(this);
+			}
+		}
+	}
+
+	private void handleImplicitResourceClosure(TryStatement tryStatement) {
+		//check if the exception is thrown as a result of resource#close()
+		if (tryStatement.getAST().apiLevel() >= AST.JLS4) {
+			List<VariableDeclarationExpression> resources= tryStatement.resources();
+			boolean exitMarked= false;
+			for (VariableDeclarationExpression variable : resources) {
+				Type type= variable.getType();
+				IMethodBinding methodBinding= Bindings.findMethodInHierarchy(type.resolveBinding(), "close", new ITypeBinding[0]); //$NON-NLS-1$
+				if (methodBinding != null) {
+					ITypeBinding[] exceptionTypes= methodBinding.getExceptionTypes();
+					for (int j= 0; j < exceptionTypes.length; j++) {
+						if (matches(exceptionTypes[j])) { // a close() throws the caught exception
+							// mark name of resource
+							for (VariableDeclarationFragment fragment : (List<VariableDeclarationFragment>) variable.fragments()) {
+								SimpleName name= fragment.getName();
+								fResult.add(new OccurrenceLocation(name.getStartPosition(), name.getLength(), 0, fDescription));
+							}
+							if (!exitMarked) {
+								// mark exit position
+								exitMarked= true;
+								Block body= tryStatement.getBody();
+								int offset= body.getStartPosition() + body.getLength() - 1; // closing bracket of try block
+								fResult.add(new OccurrenceLocation(offset, 1, 0, Messages.format(SearchMessages.ExceptionOccurrencesFinder_occurrence_implicit_close_description,
+										BasicElementLabels.getJavaElementName(fException.getName()))));
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
 	public OccurrenceLocation[] getOccurrences() {
 		performSearch();
 		if (fResult.isEmpty())
@@ -232,6 +282,12 @@
 	}
 
 	@Override
+	public boolean visit(TryStatement node) {
+		handleImplicitResourceClosure(node);
+		return super.visit(node);
+	}
+
+	@Override
 	public boolean visit(TypeDeclarationStatement node) {
 		// don't dive into local type declarations.
 		return false;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java
index 80b245c..f11ef43 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/MethodExitsFinder.java
@@ -14,6 +14,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.ASTNode;
 import org.eclipse.jdt.core.dom.ASTVisitor;
 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
@@ -26,7 +27,6 @@
 import org.eclipse.jdt.core.dom.EnumDeclaration;
 import org.eclipse.jdt.core.dom.IMethodBinding;
 import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.IVariableBinding;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.MethodInvocation;
 import org.eclipse.jdt.core.dom.Name;
@@ -40,6 +40,9 @@
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 
 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
 import org.eclipse.jdt.internal.corext.dom.Bindings;
@@ -188,19 +191,59 @@
 		int currentSize= fCatchedExceptions.size();
 		List<CatchClause> catchClauses= node.catchClauses();
 		for (Iterator<CatchClause> iter= catchClauses.iterator(); iter.hasNext();) {
-			IVariableBinding variable= iter.next().getException().resolveBinding();
-			if (variable != null && variable.getType() != null) {
-				fCatchedExceptions.add(variable.getType());
+			Type type= iter.next().getException().getType();
+			if (type instanceof UnionType) {
+				List<Type> types= ((UnionType) type).types();
+				for (Iterator<Type> iterator= types.iterator(); iterator.hasNext();) {
+					addCatchedException(iterator.next());
+				}
+			} else {
+				addCatchedException(type);
 			}
 		}
 		node.getBody().accept(this);
+
+		if (node.getAST().apiLevel() >= AST.JLS4) {
+			List<VariableDeclarationExpression> resources= node.resources();
+			for (Iterator<VariableDeclarationExpression> iterator= resources.iterator(); iterator.hasNext();) {
+				iterator.next().accept(this);
+			}
+
+			//check if the method could exit as a result of resource#close()
+			boolean exitMarked= false;
+			for (VariableDeclarationExpression variable : resources) {
+				Type type= variable.getType();
+				IMethodBinding methodBinding= Bindings.findMethodInHierarchy(type.resolveBinding(), "close", new ITypeBinding[0]); //$NON-NLS-1$
+				if (methodBinding != null) {
+					ITypeBinding[] exceptionTypes= methodBinding.getExceptionTypes();
+					for (int j= 0; j < exceptionTypes.length; j++) {
+						if (isExitPoint(exceptionTypes[j])) { // a close() throws an uncaught exception
+							// mark name of resource
+							for (VariableDeclarationFragment fragment : (List<VariableDeclarationFragment>) variable.fragments()) {
+								SimpleName name= fragment.getName();
+								fResult.add(new OccurrenceLocation(name.getStartPosition(), name.getLength(), 0, fExitDescription));
+							}
+							if (!exitMarked) {
+								// mark exit position
+								exitMarked= true;
+								Block body= node.getBody();
+								int offset= body.getStartPosition() + body.getLength() - 1; // closing bracket of try block
+								fResult.add(new OccurrenceLocation(offset, 1, 0, Messages.format(SearchMessages.MethodExitsFinder_occurrence_exit_impclict_close_description,
+										BasicElementLabels.getJavaElementName(fMethodDeclaration.getName().toString()))));
+							}
+						}
+					}
+				}
+			}
+		}
+
 		int toRemove= fCatchedExceptions.size() - currentSize;
-		for(int i= toRemove; i > 0; i--) {
+		for (int i= toRemove; i > 0; i--) {
 			fCatchedExceptions.remove(currentSize);
 		}
 
 		// visit catch and finally
-		for (Iterator<CatchClause> iter= catchClauses.iterator(); iter.hasNext(); ) {
+		for (Iterator<CatchClause> iter= catchClauses.iterator(); iter.hasNext();) {
 			iter.next().accept(this);
 		}
 		if (node.getFinally() != null)
@@ -210,6 +253,13 @@
 		return false;
 	}
 
+	private void addCatchedException(Type type) {
+		ITypeBinding typeBinding= type.resolveBinding();
+		if (typeBinding != null) {
+			fCatchedExceptions.add(typeBinding);
+		}
+	}
+
 	@Override
 	public boolean visit(ThrowStatement node) {
 		ITypeBinding exception= node.getExpression().resolveTypeBinding();
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java
index 40a8269..729469f 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -144,6 +144,7 @@
 	public static String ExceptionOccurrencesFinder_label_singular;
 	public static String ExceptionOccurrencesFinder_label_plural;
 	public static String ExceptionOccurrencesFinder_occurrence_description;
+	public static String ExceptionOccurrencesFinder_occurrence_implicit_close_description;
 	public static String ImplementOccurrencesFinder_invalidTarget;
 	public static String ImplementOccurrencesFinder_searchfor;
 	public static String ImplementOccurrencesFinder_label_singular;
@@ -250,6 +251,7 @@
 	public static String MethodExitsFinder_label_singular;
 	public static String MethodExitsFinder_no_return_type_selected;
 	public static String MethodExitsFinder_occurrence_exit_description;
+	public static String MethodExitsFinder_occurrence_exit_impclict_close_description;
 	public static String MethodExitsFinder_occurrence_return_description;
 	public static String BreakContinueTargetFinder_break_label_plural;
 	public static String BreakContinueTargetFinder_break_label_singular;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties
index 56ddf28..fe593ca 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/search/SearchMessages.properties
@@ -154,6 +154,7 @@
 # The first argument will be replaced by the element name, the second by the count and the last by the file name
 ExceptionOccurrencesFinder_label_plural=''{0}'' - {1} exception occurrences in ''{2}''
 ExceptionOccurrencesFinder_occurrence_description=Occurrences throwing ''{0}''
+ExceptionOccurrencesFinder_occurrence_implicit_close_description=''{0}'' is thrown from implicit close() methods of highlighted resources.
 
 ImplementOccurrencesFinder_invalidTarget= Cannot search for current selection. Please select a type behind 'implements' or 'extends'.
 ImplementOccurrencesFinder_searchfor= Search for Implement Occurrences
@@ -369,8 +370,9 @@
 MethodExitsFinder_label_plural=''{0}(...)'' - {1} method exit occurrence in ''{2}''
 MethodExitsFinder_label_singular=''{0}(...)'' - 1 method exit occurrence in ''{1}''
 MethodExitsFinder_no_return_type_selected=No return type selected
-MethodExitsFinder_occurrence_exit_description=Exit point of ''{0}()
-MethodExitsFinder_occurrence_return_description=Return type of ''{0}()
+MethodExitsFinder_occurrence_exit_description=Exit point of ''{0}()''
+MethodExitsFinder_occurrence_exit_impclict_close_description=Exit point of ''{0}()'': Exception is thrown from implicit close() methods of highlighted resources.
+MethodExitsFinder_occurrence_return_description=Return type of ''{0}()''
 
 BreakContinueTargetFinder_break_label_plural=''{0}'' - {1} break target occurrences in ''{2}''
 BreakContinueTargetFinder_break_label_singular=''{0}'' - 1 break target occurrence in ''{1}''
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/JavaIndenter.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/JavaIndenter.java
index 1938e18..0aa4fa7 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/JavaIndenter.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/JavaIndenter.java
@@ -1008,12 +1008,18 @@
 				// the end of the previous statement / block previous.end
 				// search to the end of the statement / block before the previous; the token just after that is previous.start
 				pos= fPosition;
-				if (isForStatement()) {
+				if (isSemicolonPartOfForStatement()) {
 					fIndent= fPrefs.prefContinuationIndent;
 					return fPosition;
 				} else {
 					fPosition= pos;
-					return skipToStatementStart(danglingElse, false);
+					if (isTryWithResources()) {
+						fIndent= fPrefs.prefContinuationIndent;
+						return fPosition;
+					} else {
+						fPosition= pos;
+						return skipToStatementStart(danglingElse, false);
+					}
 				}
 			// scope introduction: special treat who special is
 			case Symbols.TokenLPAREN:
@@ -1156,7 +1162,7 @@
 	 * @return returns <code>true</code> if current position is part of for statement
 	 * @since 3.7
 	 */
-	private boolean isForStatement() {
+	private boolean isSemicolonPartOfForStatement() {
 		int semiColonCount= 1;
 		while (true) {
 			nextToken();
@@ -1170,6 +1176,28 @@
 					if (semiColonCount > 2)
 						return false;
 					break;
+				case Symbols.TokenCOLON:
+					return false;
+				case Symbols.TokenEOF:
+					return false;
+			}
+		}
+	}
+
+	/**
+	 * Checks if the semicolon at the current position is part of a try with resources statement.
+	 * 
+	 * @return returns <code>true</code> if current position is part of try with resources statement
+	 * @since 3.7
+	 */
+	private boolean isTryWithResources() {
+		while (true) {
+			nextToken();
+			switch (fToken) {
+				case Symbols.TokenTRY:
+					return true;
+				case Symbols.TokenLBRACE:
+					return false;
 				case Symbols.TokenEOF:
 					return false;
 			}
@@ -1449,7 +1477,7 @@
 
 				case Symbols.TokenSEMICOLON:
 					int savedPosition= fPosition;
-					if (isForStatement())
+					if (isSemicolonPartOfForStatement())
 						fIndent= fPrefs.prefContinuationIndent;
 					else
 						fPosition= savedPosition;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java
index 53ac25d..abc5fd4 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/AdvancedQuickAssistProcessor.java
@@ -26,6 +26,7 @@
 import org.eclipse.core.runtime.CoreException;
 
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.NamingConventions;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.ASTNode;
@@ -38,6 +39,7 @@
 import org.eclipse.jdt.core.dom.CastExpression;
 import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
 import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.ConditionalExpression;
 import org.eclipse.jdt.core.dom.ConstructorInvocation;
 import org.eclipse.jdt.core.dom.ContinueStatement;
@@ -47,6 +49,7 @@
 import org.eclipse.jdt.core.dom.ExpressionStatement;
 import org.eclipse.jdt.core.dom.ForStatement;
 import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
 import org.eclipse.jdt.core.dom.ITypeBinding;
 import org.eclipse.jdt.core.dom.IVariableBinding;
 import org.eclipse.jdt.core.dom.IfStatement;
@@ -55,6 +58,7 @@
 import org.eclipse.jdt.core.dom.InstanceofExpression;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Modifier;
 import org.eclipse.jdt.core.dom.Name;
 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
 import org.eclipse.jdt.core.dom.PrefixExpression;
@@ -88,6 +92,7 @@
 import org.eclipse.jdt.internal.corext.fix.CleanUpConstants;
 import org.eclipse.jdt.internal.corext.fix.ExpressionsFix;
 import org.eclipse.jdt.internal.corext.fix.IProposableFix;
+import org.eclipse.jdt.internal.corext.refactoring.code.Invocations;
 import org.eclipse.jdt.internal.corext.refactoring.code.OperatorPrecedence;
 import org.eclipse.jdt.internal.corext.refactoring.util.TightSourceRangeComputer;
 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
@@ -156,6 +161,10 @@
 		if (coveringNode != null) {
 			ArrayList<ASTNode> coveredNodes= getFullyCoveredNodes(context, coveringNode);
 			ArrayList<ICommandAccess> resultingCollections= new ArrayList<ICommandAccess>();
+
+			//quick assists that show up also if there is an error/warning
+			getReplaceConditionalWithIfElseProposals(context, coveringNode, resultingCollections);
+
 			if (QuickAssistProcessor.noErrorsAtLocation(locations)) {
 				getInverseIfProposals(context, coveringNode, resultingCollections);
 				getIfReturnIntoIfElseAtEndOfVoidMethodProposals(context, coveringNode, resultingCollections);
@@ -175,7 +184,6 @@
 				getCastAndAssignIfStatementProposals(context, coveringNode, resultingCollections);
 				getPickOutStringProposals(context, coveringNode, resultingCollections);
 				getReplaceIfElseWithConditionalProposals(context, coveringNode, resultingCollections);
-				getReplaceConditionalWithIfElseProposals(context, coveringNode, resultingCollections);
 				getInverseLocalVariableProposals(context, coveringNode, resultingCollections);
 				getPushNegationDownProposals(context, coveringNode, resultingCollections);
 				getPullNegationUpProposals(context, coveredNodes, resultingCollections);
@@ -708,7 +716,7 @@
 		return true;
 	}
 
-	private static ArrayList<ASTNode> getFullyCoveredNodes(IInvocationContext context, ASTNode coveringNode) {
+	static ArrayList<ASTNode> getFullyCoveredNodes(IInvocationContext context, ASTNode coveringNode) {
 		final ArrayList<ASTNode> coveredNodes= new ArrayList<ASTNode>();
 		final int selectionBegin= context.getSelectionOffset();
 		final int selectionEnd= selectionBegin + context.getSelectionLength();
@@ -1668,7 +1676,8 @@
 		Expression elseCopy= (Expression) rewrite.createCopyTarget(elseExpression);
 
 
-		if (!JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) {
+		IJavaProject project= context.getCompilationUnit().getJavaProject();
+		if (!JavaModelUtil.is50OrHigher(project)) {
 			ITypeBinding thenBinding= thenExpression.resolveTypeBinding();
 			ITypeBinding elseBinding= elseExpression.resolveTypeBinding();
 			if (thenBinding != null && elseBinding != null && exprBinding != null && !elseBinding.isAssignmentCompatible(thenBinding)) {
@@ -1679,6 +1688,9 @@
 				castException.setExpression(elseCopy);
 				elseCopy= castException;
 			}
+		} else if (JavaModelUtil.is17OrHigher(project)) {
+			addExplicitTypeArgumentsIfNecessary(rewrite, proposal, thenExpression);
+			addExplicitTypeArgumentsIfNecessary(rewrite, proposal, elseExpression);
 		}
 		conditionalExpression.setThenExpression(thenCopy);
 		conditionalExpression.setElseExpression(elseCopy);
@@ -1703,6 +1715,42 @@
 		return true;
 	}
 
+	private static void addExplicitTypeArgumentsIfNecessary(ASTRewrite rewrite, ASTRewriteCorrectionProposal proposal, Expression invocation) {
+		if (Invocations.isResolvedTypeInferredFromExpectedType(invocation)) {
+			ITypeBinding[] typeArguments= Invocations.getInferredTypeArguments(invocation);
+			if (typeArguments == null)
+				return;
+			
+			ImportRewrite importRewrite= proposal.getImportRewrite();
+			if (importRewrite == null) {
+				importRewrite= proposal.createImportRewrite((CompilationUnit) invocation.getRoot());
+			}
+			ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(invocation, importRewrite);
+			
+			AST ast= invocation.getAST();
+			ListRewrite typeArgsRewrite= Invocations.getInferredTypeArgumentsRewrite(rewrite, invocation);
+			
+			for (int i= 0; i < typeArguments.length; i++) {
+				Type typeArgumentNode= importRewrite.addImport(typeArguments[i], ast, importRewriteContext);
+				typeArgsRewrite.insertLast(typeArgumentNode, null);
+			}
+			
+			if (invocation instanceof MethodInvocation) {
+				MethodInvocation methodInvocation= (MethodInvocation) invocation;
+				Expression expression= methodInvocation.getExpression();
+				if (expression == null) {
+					IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
+					if (methodBinding != null && Modifier.isStatic(methodBinding.getModifiers())) {
+						expression= ast.newName(importRewrite.addImport(methodBinding.getDeclaringClass().getTypeDeclaration(), importRewriteContext));
+					} else {
+						expression= ast.newThisExpression();
+					}
+					rewrite.set(invocation, MethodInvocation.EXPRESSION_PROPERTY, expression, null);
+				}
+			}
+		}
+	}
+	
 	private static ReturnStatement createReturnExpression(ASTRewrite rewrite, Expression expression) {
 		AST ast= rewrite.getAST();
 		ReturnStatement thenReturn= ast.newReturnStatement();
@@ -2166,12 +2214,15 @@
 		final ImportRewrite importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
 		//
 		SwitchStatement switchStatement= (SwitchStatement) covering;
+		ITypeBinding expressionType= switchStatement.getExpression().resolveTypeBinding();
+		boolean isStringsInSwitch= expressionType != null && "java.lang.String".equals(expressionType.getQualifiedName()); //$NON-NLS-1$
+		String label= isStringsInSwitch ? CorrectionMessages.AdvancedQuickAssistProcessor_convertSwitchToIfRemovingNullCheck : CorrectionMessages.AdvancedQuickAssistProcessor_convertSwitchToIf;
 		IfStatement firstIfStatement= null;
 		IfStatement currentIfStatement= null;
 		Block currentBlock= null;
 		boolean hasStopAsLastExecutableStatement= false;
 		Block defaultBlock= null;
-		InfixExpression currentCondition= null;
+		Expression currentCondition= null;
 		boolean defaultFound= false;
 
 		ArrayList<Block> allBlocks= new ArrayList<Block>();
@@ -2200,7 +2251,7 @@
 					return false;
 				}
 				// prepare condition
-				InfixExpression switchCaseCondition= createSwitchCaseCondition(ast, rewrite, importRewrite, importRewriteContext, switchStatement, switchCase);
+				Expression switchCaseCondition= createSwitchCaseCondition(ast, rewrite, importRewrite, importRewriteContext, switchStatement, switchCase, isStringsInSwitch);
 				if (currentCondition == null) {
 					currentCondition= switchCaseCondition;
 				} else {
@@ -2265,8 +2316,6 @@
 		}
 		// replace 'switch' with single if-else-if statement
 		rewrite.replace(switchStatement, firstIfStatement, null);
-		// prepare label, specially for Daniel :-)
-		String label= CorrectionMessages.AdvancedQuickAssistProcessor_convertSwitchToIf;
 
 		// add correction proposal
 		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
@@ -2276,29 +2325,35 @@
 		return true;
 	}
 
-	private static InfixExpression createSwitchCaseCondition(AST ast, ASTRewrite rewrite, ImportRewrite importRewrite, ImportRewriteContext importRewriteContext, SwitchStatement switchStatement,
-			SwitchCase switchCase) {
-		InfixExpression condition= ast.newInfixExpression();
-		condition.setOperator(InfixExpression.Operator.EQUALS);
-		//
-		Expression leftExpression= getParenthesizedExpressionIfNeeded(ast, rewrite, switchStatement.getExpression(), condition, InfixExpression.LEFT_OPERAND_PROPERTY);
-		condition.setLeftOperand(leftExpression);
-		//
-		Expression rightExpression= null;
+	private static Expression createSwitchCaseCondition(AST ast, ASTRewrite rewrite, ImportRewrite importRewrite, ImportRewriteContext importRewriteContext, SwitchStatement switchStatement,
+			SwitchCase switchCase, boolean isStringsInSwitch) {
 		Expression expression= switchCase.getExpression();
-		if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() instanceof IVariableBinding) {
-			IVariableBinding binding= (IVariableBinding) ((SimpleName) expression).resolveBinding();
-			if (binding.isEnumConstant()) {
-				String qualifiedName= importRewrite.addImport(binding.getDeclaringClass(), importRewriteContext) + '.' + binding.getName();
-				rightExpression= ast.newName(qualifiedName);
+		if (isStringsInSwitch) {
+			MethodInvocation methodInvocation= ast.newMethodInvocation();
+			methodInvocation.setExpression((Expression) rewrite.createCopyTarget(expression));
+			methodInvocation.setName(ast.newSimpleName("equals")); //$NON-NLS-1$
+			methodInvocation.arguments().add(rewrite.createCopyTarget(switchStatement.getExpression()));
+			return methodInvocation;
+		} else {
+			InfixExpression condition= ast.newInfixExpression();
+			condition.setOperator(InfixExpression.Operator.EQUALS);
+			Expression leftExpression= getParenthesizedExpressionIfNeeded(ast, rewrite, switchStatement.getExpression(), condition, InfixExpression.LEFT_OPERAND_PROPERTY);
+			condition.setLeftOperand(leftExpression);
+
+			Expression rightExpression= null;
+			if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() instanceof IVariableBinding) {
+				IVariableBinding binding= (IVariableBinding) ((SimpleName) expression).resolveBinding();
+				if (binding.isEnumConstant()) {
+					String qualifiedName= importRewrite.addImport(binding.getDeclaringClass(), importRewriteContext) + '.' + binding.getName();
+					rightExpression= ast.newName(qualifiedName);
+				}
 			}
+			if (rightExpression == null) {
+				rightExpression= (Expression) rewrite.createCopyTarget(expression);
+			}
+			condition.setRightOperand(rightExpression);
+			return condition;
 		}
-		if (rightExpression == null) {
-			rightExpression= (Expression) rewrite.createCopyTarget(expression);
-		}
-		condition.setRightOperand(rightExpression);
-		//
-		return condition;
 	}
 
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
index 2b07de0..0763686 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.java
@@ -41,8 +41,12 @@
 	public static String QuickAssistProcessor_convert_anonym_to_nested;
 	public static String QuickAssistProcessor_convert_local_to_field_description;
 	public static String QuickAssistProcessor_convert_to_message_format;
+	public static String QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks;
+	public static String QuickAssistProcessor_convert_to_single_multicatch_block;
 	public static String QuickAssistProcessor_convert_to_string_buffer_description;
+	public static String QuickAssistProcessor_exceptiontothrows_description;
 	public static String QuickAssistProcessor_extract_to_constant_description;
+	public static String QuickAssistProcessor_infer_diamond_description;
 	public static String QuickAssistProcessor_inline_local_description;
 	public static String QuickAssistProcessor_name_extension_from_class;
 	public static String QuickAssistProcessor_name_extension_from_interface;
@@ -72,15 +76,19 @@
 	public static String ReorgCorrectionsSubProcessor_addcp_project_description;
 	public static String ReorgCorrectionsSubProcessor_addcp_archive_description;
 	public static String ReorgCorrectionsSubProcessor_addcp_classfolder_description;
-	public static String ReorgCorrectionsSubProcessor_50_project_compliance_description;
-	public static String ReorgCorrectionsSubProcessor_50_workspace_compliance_description;
+	public static String ReorgCorrectionsSubProcessor_change_project_compliance_description;
+	public static String ReorgCorrectionsSubProcessor_change_workspace_compliance_description;
 	public static String ReorgCorrectionsSubProcessor_addcp_variable_description;
 	public static String ReorgCorrectionsSubProcessor_addcp_library_description;
-	public static String LocalCorrectionsSubProcessor_surroundwith_description;
+	public static String LocalCorrectionsSubProcessor_surroundwith_trycatch_description;
+	public static String LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description;
 	public static String LocalCorrectionsSubProcessor_add_missing_cases_description;
 	public static String LocalCorrectionsSubProcessor_addthrows_description;
 	public static String ClasspathFixProcessorDescriptor_error_processing_processors;
 	public static String LocalCorrectionsSubProcessor_addadditionalcatch_description;
+	public static String LocalCorrectionsSubProcessor_addadditionalmulticatch_description;
+	public static String LocalCorrectionsSubProcessor_addexceptiontoexistingcatch_description;
+	public static String LocalCorrectionsSubProcessor_addexceptionstoexistingcatch_description;
 	public static String LocalCorrectionsSubProcessor_unnecessaryinstanceof_description;
 	public static String LocalCorrectionsSubProcessor_unnecessarythrow_description;
 	public static String LocalCorrectionsSubProcessor_classtointerface_description;
@@ -235,6 +243,7 @@
 	public static String AssignToVariableAssistProposal_assignparamtofield_description;
 	public static String QuickAssistProcessor_catchclausetothrows_description;
 	public static String QuickAssistProcessor_removecatchclause_description;
+	public static String QuickAssistProcessor_removeexception_description;
 	public static String QuickAssistProcessor_unwrap_ifstatement;
 	public static String QuickAssistProcessor_unwrap_whilestatement;
 	public static String QuickAssistProcessor_unwrap_forstatement;
@@ -290,6 +299,8 @@
 	public static String AdvancedQuickAssistProcessor_pushNegationDown;
 	public static String AdvancedQuickAssistProcessor_putConditionalExpressionInParentheses;
 	public static String AdvancedQuickAssistProcessor_convertSwitchToIf;
+	public static String AdvancedQuickAssistProcessor_convertSwitchToIfRemovingNullCheck;
+	public static String AdvancedQuickAssistProcessor_convertIfElseToSwitch;
 	public static String AdvancedQuickAssistProcessor_inverseIfContinue_description;
 	public static String AdvancedQuickAssistProcessor_inverseIfToContinue_description;
 	public static String AdvancedQuickAssistProcessor_exchangeInnerAndOuterIfConditions_description;
@@ -315,10 +326,10 @@
 	public static String LocalCorrectionsSubProcessor_generate_hashCode_equals_description;
 	public static String AssignToVariableAssistProposal_assigntoexistingfield_description;
 	public static String ReorgCorrectionsSubProcessor_50_compliance_operation;
-	public static String ReorgCorrectionsSubProcessor_no_50jre_title;
-	public static String ReorgCorrectionsSubProcessor_no_50jre_message;
-	public static String ReorgCorrectionsSubProcessor_50_compliance_changeworkspace_description;
-	public static String ReorgCorrectionsSubProcessor_50_compliance_changeproject_description;
+	public static String ReorgCorrectionsSubProcessor_no_required_jre_title;
+	public static String ReorgCorrectionsSubProcessor_no_required_jre_message;
+	public static String ReorgCorrectionsSubProcessor_required_compliance_changeworkspace_description;
+	public static String ReorgCorrectionsSubProcessor_required_compliance_changeproject_description;
 	public static String GetterSetterCorrectionSubProcessor_creategetterunsingencapsulatefield_description;
 	public static String GetterSetterCorrectionSubProcessor_encapsulate_field_error_message;
 	public static String GetterSetterCorrectionSubProcessor_additional_info;
@@ -334,6 +345,8 @@
 	public static String QuickAssistProcessor_extract_to_local_all_description;
 	public static String QuickAssistProcessor_extract_to_local_description;
 	public static String QuickAssistProcessor_extractmethod_description;
+	public static String QuickAssistProcessor_move_exception_to_separate_catch_block;
+	public static String QuickAssistProcessor_move_exceptions_to_separate_catch_block;
 	public static String SuppressWarningsSubProcessor_suppress_warnings_label;
 	public static String ReorgCorrectionsSubProcessor_accessrules_description;
 	public static String ReorgCorrectionsSubProcessor_project_seup_fix_description;
@@ -341,6 +354,7 @@
 	public static String UnresolvedElementsSubProcessor_change_full_type_description;
 	public static String LocalCorrectionsSubProcessor_remove_allocated_description;
 	public static String LocalCorrectionsSubProcessor_remove_redundant_superinterface;
+	public static String LocalCorrectionsSubProcessor_remove_type_arguments;
 	public static String LocalCorrectionsSubProcessor_return_allocated_description;
 	public static String LocalCorrectionsSubProcessor_qualify_left_hand_side_description;
 	public static String LocalCorrectionsSubProcessor_LocalCorrectionsSubProcessor_qualify_right_hand_side_description;
@@ -357,4 +371,7 @@
 	public static String LocalCorrectionsSubProcessor_throw_allocated_description;
 	public static String SuppressWarningsSubProcessor_fix_suppress_token_label;
 	public static String SuppressWarningsSubProcessor_remove_annotation_label;
+	public static String VarargsWarningsSubProcessor_add_safevarargs_label;
+	public static String VarargsWarningsSubProcessor_add_safevarargs_to_method_label;
+	public static String VarargsWarningsSubProcessor_remove_safevarargs_label;
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
index 4a17eff..6d51e23 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/CorrectionMessages.properties
@@ -46,8 +46,8 @@
 ReorgCorrectionsSubProcessor_renamecu_description=Rename compilation unit to ''{0}''
 ReorgCorrectionsSubProcessor_movecu_default_description=Move ''{0}'' to the default package
 ReorgCorrectionsSubProcessor_movecu_description=Move ''{0}'' to package ''{1}''
-ReorgCorrectionsSubProcessor_no_50jre_title=Change To 1.5 Quick Fix
-ReorgCorrectionsSubProcessor_no_50jre_message=The compiler compliance has been changed to 1.5, but no 1.5 JRE could be found in the installed JRE's. You have to manually set the correct JRE or add a new JRE in the preferences (Java - Installed JRE's).
+ReorgCorrectionsSubProcessor_no_required_jre_title=Change To {0} Quick Fix
+ReorgCorrectionsSubProcessor_no_required_jre_message=The compiler compliance has been changed to {0}, but no {0} JRE could be found in the installed JREs. You have to manually set the correct JRE or add a new JRE in the preferences (Java > Installed JREs).
 ReorgCorrectionsSubProcessor_50_compliance_operation=Updating to new JRE
 ReorgCorrectionsSubProcessor_accessrules_description=Configure access rules...
 ReorgCorrectionsSubProcessor_organizeimports_description=Organize imports
@@ -55,25 +55,29 @@
 ReorgCorrectionsSubProcessor_addcp_project_description=Add project ''{0}'' to build path of ''{1}''
 ReorgCorrectionsSubProcessor_addcp_archive_description=Add archive ''{0}'' to build path of ''{1}''
 ReorgCorrectionsSubProcessor_addcp_classfolder_description=Add class folder ''{0}'' to build path of ''{1}''
-ReorgCorrectionsSubProcessor_50_project_compliance_description=Change project compliance and JRE to 1.5
+ReorgCorrectionsSubProcessor_change_project_compliance_description=Change project compliance and JRE to {0}
 ReorgCorrectionsSubProcessor_configure_buildpath_description=Open the Java build path property page of project ''{0}''
-ReorgCorrectionsSubProcessor_50_workspace_compliance_description=Change workspace compliance and JRE to 1.5
-ReorgCorrectionsSubProcessor_50_compliance_changeworkspace_description=<p>Set workspace compiler compliance settings to '1.5'
-ReorgCorrectionsSubProcessor_50_compliance_changeproject_description=<p>Set project compiler compliance settings to '1.5'
+ReorgCorrectionsSubProcessor_change_workspace_compliance_description=Change workspace compliance and JRE to {0}
+ReorgCorrectionsSubProcessor_required_compliance_changeworkspace_description=<p>Set workspace compiler compliance settings to {0}
+ReorgCorrectionsSubProcessor_required_compliance_changeproject_description=<p>Set project compiler compliance settings to {0}
 ReorgCorrectionsSubProcessor_50_compliance_changeProjectJREToDefault_description=<p>Set project JRE build path entry to 'default JRE'
 ReorgCorrectionsSubProcessor_50_compliance_changeWorkspaceJRE_description=<p>Set workspace default JRE to ''{0}''
-ReorgCorrectionsSubProcessor_50_compliance_changeProjectJRE_description=<p>Set project JRE build path entry to {0}
+ReorgCorrectionsSubProcessor_50_compliance_changeProjectJRE_description=<p>Set project JRE build path entry to ''{0}''
 ReorgCorrectionsSubProcessor_addcp_variable_description=Add variable entry ''{0}'' to build path of ''{1}''
 ReorgCorrectionsSubProcessor_addcp_library_description=Add library ''{0}'' to build path of ''{1}''
 ReorgCorrectionsSubProcessor_configure_buildpath_label=Configure build path...
 ReorgCorrectionsSubProcessor_project_seup_fix_description=Fix project setup...
 ReorgCorrectionsSubProcessor_project_seup_fix_info=Evaluates project setup fixes to resolve the reference to the missing element ''{0}''
 
-LocalCorrectionsSubProcessor_surroundwith_description=Surround with try/catch
+LocalCorrectionsSubProcessor_surroundwith_trycatch_description=Surround with try/catch
+LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description=Surround with try/multi-catch
 LocalCorrectionsSubProcessor_add_missing_cases_description=Add missing case statements
 LocalCorrectionsSubProcessor_addthrows_description=Add throws declaration
 ClasspathFixProcessorDescriptor_error_processing_processors=Exception while processing classpath fix processors
 LocalCorrectionsSubProcessor_addadditionalcatch_description=Add catch clause to surrounding try
+LocalCorrectionsSubProcessor_addadditionalmulticatch_description=Add multi-catch clause to surrounding try
+LocalCorrectionsSubProcessor_addexceptiontoexistingcatch_description=Add exception to existing catch clause
+LocalCorrectionsSubProcessor_addexceptionstoexistingcatch_description=Add exceptions to existing catch clause
 LocalCorrectionsSubProcessor_unnecessaryinstanceof_description=Replace with null check
 LocalCorrectionsSubProcessor_unnecessarythrow_description=Remove thrown exception
 LocalCorrectionsSubProcessor_classtointerface_description=Change ''{0}'' to interface
@@ -89,6 +93,7 @@
 LocalCorrectionsSubProcessor_removesemicolon_description=Remove semicolon
 LocalCorrectionsSubProcessor_remove_allocated_description=Remove
 LocalCorrectionsSubProcessor_remove_redundant_superinterface=Remove super interface
+LocalCorrectionsSubProcessor_remove_type_arguments=Remove type arguments
 LocalCorrectionsSubProcessor_renaming_duplicate_method=Rename method ''{0}''
 LocalCorrectionsSubProcessor_removeunreachablecode_description=Remove
 LocalCorrectionsSubProcessor_removeunreachablecode_including_condition_description=Remove (including condition)
@@ -288,6 +293,7 @@
 
 QuickAssistProcessor_catchclausetothrows_description=Replace catch clause with throws
 QuickAssistProcessor_removecatchclause_description=Remove catch clause
+QuickAssistProcessor_removeexception_description=Remove exception
 QuickAssistProcessor_name_extension_from_interface={0}Extension
 
 
@@ -303,6 +309,7 @@
 QuickAssistProcessor_unwrap_synchronizedstatement=Remove surrounding 'synchronized' statement
 
 QuickAssistProcessor_splitdeclaration_description=Split variable declaration
+QuickAssistProcessor_exceptiontothrows_description=Replace exception with throws
 QuickAssistProcessor_extract_to_local_all_description=Extract to local variable (replace all occurrences)
 QuickAssistProcessor_extract_to_local_description=Extract to local variable
 QuickAssistProcessor_extractmethod_description=Extract to method
@@ -316,6 +323,7 @@
 QuickAssistProcessor_replacethenelsewithblock_description=Change 'if-else' statements to blocks
 QuickAssistProcessor_replacebodywithblock_description=Change body statement to block
 
+QuickAssistProcessor_infer_diamond_description=Insert inferred type arguments
 QuickAssistProcessor_invertequals_description=Invert equals
 QuickAssistProcessor_inline_local_description=Inline local variable
 QuickAssistProcessor_convert_anonym_to_nested=Convert anonymous to nested class
@@ -323,8 +331,12 @@
 QuickAssistProcessor_typetoarrayInitializer_description=Add type to initializer
 QuickAssistProcessor_convert_local_to_field_description=Convert local variable to field
 QuickAssistProcessor_convert_to_message_format=Use 'MessageFormat' for string concatenation
+QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks=Use separate catch blocks
+QuickAssistProcessor_convert_to_single_multicatch_block=Combine catch blocks
 QuickAssistProcessor_convert_to_string_buffer_description=Use ''{0}'' for string concatenation
 QuickAssistProcessor_createmethodinsuper_description=Create ''{1}()'' in super type ''{0}''
+QuickAssistProcessor_move_exception_to_separate_catch_block=Move exception to separate catch block
+QuickAssistProcessor_move_exceptions_to_separate_catch_block=Move exceptions to separate catch block
 
 LinkedNamesAssistProposal_proposalinfo=Link all references for a local rename (does not change references in other files)
 LinkedNamesAssistProposal_description=Rename in file
@@ -363,6 +375,8 @@
 AdvancedQuickAssistProcessor_pushNegationDown=Push negation down
 AdvancedQuickAssistProcessor_putConditionalExpressionInParentheses=Put conditional expression in parentheses
 AdvancedQuickAssistProcessor_convertSwitchToIf=Convert 'switch' to 'if-else'
+AdvancedQuickAssistProcessor_convertSwitchToIfRemovingNullCheck=Convert 'switch' to 'if-else' (removing null check on switch expression)
+AdvancedQuickAssistProcessor_convertIfElseToSwitch=Convert 'if-else' to 'switch'
 AdvancedQuickAssistProcessor_inverseIfContinue_description=Invert 'if/continue' statement, convert to 'if'
 AdvancedQuickAssistProcessor_inverseIfToContinue_description=Invert 'if' statement, convert to 'continue'
 AdvancedQuickAssistProcessor_exchangeInnerAndOuterIfConditions_description=Exchange conditions for inner and outer 'if' statements
@@ -390,3 +404,6 @@
 SuppressWarningsSubProcessor_remove_annotation_label=Remove ''{0}'' token 
 ModifierCorrectionSubProcessor_changefieldmodifiertononstatic_description=Remove ''static'' modifier of ''{0}''
 GetterSetterCorrectionSubProcessor_creategetterunsingencapsulatefield_description=Create getter and setter for ''{0}''
+VarargsWarningsSubProcessor_add_safevarargs_label=Add @SafeVarargs
+VarargsWarningsSubProcessor_add_safevarargs_to_method_label=Add @SafeVarargs to ''{0}(..)''
+VarargsWarningsSubProcessor_remove_safevarargs_label=Remove @SafeVarargs
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
index fbd00bf..263d850 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/LocalCorrectionsSubProcessor.java
@@ -75,6 +75,7 @@
 import org.eclipse.jdt.core.dom.MethodInvocation;
 import org.eclipse.jdt.core.dom.Modifier;
 import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.ParameterizedType;
 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
 import org.eclipse.jdt.core.dom.PrefixExpression;
 import org.eclipse.jdt.core.dom.PrimitiveType;
@@ -91,6 +92,8 @@
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.UnionType;
+import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
 import org.eclipse.jdt.core.dom.WhileStatement;
 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
@@ -178,7 +181,7 @@
 		if (selectedNode == null) {
 			return;
 		}
-		while (selectedNode != null && !(selectedNode instanceof Statement)) {
+		while (selectedNode != null && !(selectedNode instanceof Statement) && !(selectedNode instanceof VariableDeclarationExpression)) {
 			selectedNode= selectedNode.getParent();
 		}
 		if (selectedNode == null) {
@@ -193,19 +196,36 @@
 			length= selectionEnd - offset;
 		}
 
+		//Surround with proposals
 		SurroundWithTryCatchRefactoring refactoring= SurroundWithTryCatchRefactoring.create(cu, offset, length);
 		if (refactoring == null)
 			return;
 
 		refactoring.setLeaveDirty(true);
 		if (refactoring.checkActivationBasics(astRoot).isOK()) {
-			String label= CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_description;
+			String label= CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trycatch_description;
 			Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
 			CUCorrectionProposal proposal= new CUCorrectionProposal(label, cu, (CompilationUnitChange) refactoring.createChange(null), 6, image);
 			proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
 			proposals.add(proposal);
 		}
 
+		if (JavaModelUtil.is17OrHigher(cu.getJavaProject())) {
+			refactoring= SurroundWithTryCatchRefactoring.create(cu, offset, length, true);
+			if (refactoring == null)
+				return;
+
+			refactoring.setLeaveDirty(true);
+			if (refactoring.checkActivationBasics(astRoot).isOK()) {
+				String label= CorrectionMessages.LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description;
+				Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+				CUCorrectionProposal proposal= new CUCorrectionProposal(label, cu, (CompilationUnitChange) refactoring.createChange(null), 7, image);
+				proposal.setLinkedProposalModel(refactoring.getLinkedProposalModel());
+				proposals.add(proposal);
+			}
+		}
+
+		//Catch exception
 		BodyDeclaration decl= ASTResolving.findParentBodyDeclaration(selectedNode);
 		if (decl == null) {
 			return;
@@ -217,42 +237,129 @@
 		}
 
 		TryStatement surroundingTry= ASTResolving.findParentTryStatement(selectedNode);
-		if (surroundingTry != null && ASTNodes.isParent(selectedNode, surroundingTry.getBody())) {
-			ASTRewrite rewrite= ASTRewrite.create(surroundingTry.getAST());
+		AST ast= astRoot.getAST();
+		if (surroundingTry != null && (ASTNodes.isParent(selectedNode, surroundingTry.getBody()) || selectedNode.getLocationInParent() == TryStatement.RESOURCES_PROPERTY)) {
+			{
+				ASTRewrite rewrite= ASTRewrite.create(surroundingTry.getAST());
 
-			String label= CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalcatch_description;
-			Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
-			LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 7, image);
+				String label= CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalcatch_description;
+				Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+				LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 7, image);
 
-			ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot());
-			ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports);
+				ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot());
+				ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports);
 
-			AST ast= astRoot.getAST();
-			ListRewrite clausesRewrite= rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
-			for (int i= 0; i < uncaughtExceptions.length; i++) {
-				ITypeBinding excBinding= uncaughtExceptions[i];
-				String varName= StubUtility.getExceptionVariableName(cu.getJavaProject());
-				SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
-				var.setName(ast.newSimpleName(varName));
-				var.setType(imports.addImport(excBinding, ast, importRewriteContext));
-				CatchClause newClause= ast.newCatchClause();
-				newClause.setException(var);
-				String catchBody = StubUtility.getCatchBodyContent(cu, excBinding.getName(), varName, selectedNode, String.valueOf('\n'));
-				if (catchBody != null) {
-					ASTNode node= rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
-					newClause.getBody().statements().add(node);
+				ListRewrite clausesRewrite= rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
+				for (int i= 0; i < uncaughtExceptions.length; i++) {
+					ITypeBinding excBinding= uncaughtExceptions[i];
+					String varName= StubUtility.getExceptionVariableName(cu.getJavaProject());
+					SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
+					var.setName(ast.newSimpleName(varName));
+					var.setType(imports.addImport(excBinding, ast, importRewriteContext));
+					CatchClause newClause= ast.newCatchClause();
+					newClause.setException(var);
+					String catchBody= StubUtility.getCatchBodyContent(cu, excBinding.getName(), varName, selectedNode, String.valueOf('\n'));
+					if (catchBody != null) {
+						ASTNode node= rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
+						newClause.getBody().statements().add(node);
+					}
+					clausesRewrite.insertLast(newClause, null);
+
+					String typeKey= "type" + i; //$NON-NLS-1$
+					String nameKey= "name" + i; //$NON-NLS-1$
+					proposal.addLinkedPosition(rewrite.track(var.getType()), false, typeKey);
+					proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
+					addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
 				}
-				clausesRewrite.insertLast(newClause, null);
-
-				String typeKey= "type" + i; //$NON-NLS-1$
-				String nameKey= "name" + i; //$NON-NLS-1$
-				proposal.addLinkedPosition(rewrite.track(var.getType()), false, typeKey);
-				proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
-				addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
+				proposals.add(proposal);
 			}
-			proposals.add(proposal);
+
+			if (JavaModelUtil.is17OrHigher(cu.getJavaProject())) {
+				List<CatchClause> catchClauses= surroundingTry.catchClauses();
+
+				if (catchClauses != null && catchClauses.size() == 1) {
+					String label= uncaughtExceptions.length > 1
+							? CorrectionMessages.LocalCorrectionsSubProcessor_addexceptionstoexistingcatch_description
+							: CorrectionMessages.LocalCorrectionsSubProcessor_addexceptiontoexistingcatch_description;
+					Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+					ASTRewrite rewrite= ASTRewrite.create(ast);
+					LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 7, image);
+					ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot());
+					ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports);
+
+					CatchClause catchClause= catchClauses.get(0);
+					Type type= catchClause.getException().getType();
+					if (type instanceof UnionType) {
+						UnionType unionType= (UnionType) type;
+						ListRewrite listRewrite= rewrite.getListRewrite(unionType, UnionType.TYPES_PROPERTY);
+						for (int i= 0; i < uncaughtExceptions.length; i++) {
+							ITypeBinding excBinding= uncaughtExceptions[i];
+							Type type2= imports.addImport(excBinding, ast, importRewriteContext);
+							listRewrite.insertLast(type2, null);
+
+							String typeKey= "type" + i; //$NON-NLS-1$
+							proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
+							addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
+						}
+					} else {
+						UnionType newUnionType= ast.newUnionType();
+						List<Type> types= newUnionType.types();
+
+						types.add((Type) rewrite.createCopyTarget(type));
+						for (int i= 0; i < uncaughtExceptions.length; i++) {
+							ITypeBinding excBinding= uncaughtExceptions[i];
+							Type type2= imports.addImport(excBinding, ast, importRewriteContext);
+							types.add(type2);
+
+							String typeKey= "type" + i; //$NON-NLS-1$
+							proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
+							addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
+						}
+						rewrite.replace(type, newUnionType, null);
+					}
+					proposals.add(proposal);
+				} else if (catchClauses != null && catchClauses.size() == 0 && uncaughtExceptions.length > 1) {
+					String label= CorrectionMessages.LocalCorrectionsSubProcessor_addadditionalmulticatch_description;
+					Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+					ASTRewrite rewrite= ASTRewrite.create(ast);
+					LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, cu, rewrite, 7, image);
+					ImportRewrite imports= proposal.createImportRewrite(context.getASTRoot());
+					ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(decl, imports);
+
+					CatchClause newCatchClause= ast.newCatchClause();
+					String varName= StubUtility.getExceptionVariableName(cu.getJavaProject());
+					SingleVariableDeclaration var= ast.newSingleVariableDeclaration();
+					var.setName(ast.newSimpleName(varName));
+
+					UnionType newUnionType= ast.newUnionType();
+					List<Type> types= newUnionType.types();
+
+					for (int i= 0; i < uncaughtExceptions.length; i++) {
+						ITypeBinding excBinding= uncaughtExceptions[i];
+						Type type2= imports.addImport(excBinding, ast, importRewriteContext);
+						types.add(type2);
+
+						String typeKey= "type" + i; //$NON-NLS-1$
+						proposal.addLinkedPosition(rewrite.track(type2), false, typeKey);
+						addExceptionTypeLinkProposals(proposal, excBinding, typeKey);
+					}
+					String nameKey= "name"; //$NON-NLS-1$
+					proposal.addLinkedPosition(rewrite.track(var.getName()), false, nameKey);
+					var.setType(newUnionType);
+					newCatchClause.setException(var);
+					String catchBody= StubUtility.getCatchBodyContent(cu, "Exception", varName, selectedNode, String.valueOf('\n')); //$NON-NLS-1$
+					if (catchBody != null) {
+						ASTNode node= rewrite.createStringPlaceholder(catchBody, ASTNode.RETURN_STATEMENT);
+						newCatchClause.getBody().statements().add(node);
+					}
+					ListRewrite listRewrite= rewrite.getListRewrite(surroundingTry, TryStatement.CATCH_CLAUSES_PROPERTY);
+					listRewrite.insertFirst(newCatchClause, null);
+					proposals.add(proposal);
+				}
+			}
 		}
 
+		//Add throws declaration
 		if (decl instanceof MethodDeclaration) {
 			MethodDeclaration methodDecl= (MethodDeclaration) decl;
 			IMethodBinding binding= methodDecl.resolveBinding();
@@ -1328,6 +1435,35 @@
 		}
 	}
 
+	public static void addRemoveRedundantTypeArgumentsProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+		CompilationUnit astRoot= context.getASTRoot();
+		ASTNode selectedNode= problem.getCoveringNode(astRoot);
+		if (selectedNode == null)
+			return;
+
+		while (!(selectedNode instanceof ParameterizedType) && !(selectedNode instanceof Statement)) {
+			selectedNode= selectedNode.getParent();
+		}
+		if (!(selectedNode instanceof ParameterizedType)) {
+			return;
+		}
+		ParameterizedType parameterizedType= (ParameterizedType) selectedNode;
+
+		AST ast= astRoot.getAST();
+		ASTRewrite rewrite= ASTRewrite.create(ast);
+		ListRewrite listRewrite= rewrite.getListRewrite(parameterizedType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
+
+		List<Type> typeArguments= parameterizedType.typeArguments();
+		for (Iterator<Type> iterator= typeArguments.iterator(); iterator.hasNext();) {
+			listRewrite.remove(iterator.next(), null);
+		}
+
+		Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE);
+		String label= CorrectionMessages.LocalCorrectionsSubProcessor_remove_type_arguments;
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 6, image);
+		proposals.add(proposal);
+	}
+
 	public static void addFallThroughProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
 		ASTNode selectedNode= problem.getCoveringNode(context.getASTRoot());
 		if (selectedNode instanceof SwitchCase && selectedNode.getLocationInParent() == SwitchStatement.STATEMENTS_PROPERTY) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
index b9b68a1..f0f2862 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickAssistProcessor.java
@@ -40,11 +40,13 @@
 import org.eclipse.ltk.core.refactoring.TextFileChange;
 
 import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IJavaModelMarker;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.NamingConventions;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.dom.AST;
@@ -79,6 +81,7 @@
 import org.eclipse.jdt.core.dom.MethodInvocation;
 import org.eclipse.jdt.core.dom.Modifier;
 import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.ParameterizedType;
 import org.eclipse.jdt.core.dom.ParenthesizedExpression;
 import org.eclipse.jdt.core.dom.PrimitiveType;
 import org.eclipse.jdt.core.dom.SimpleName;
@@ -94,6 +97,7 @@
 import org.eclipse.jdt.core.dom.TryStatement;
 import org.eclipse.jdt.core.dom.Type;
 import org.eclipse.jdt.core.dom.TypeDeclaration;
+import org.eclipse.jdt.core.dom.UnionType;
 import org.eclipse.jdt.core.dom.VariableDeclaration;
 import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
 import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
@@ -181,7 +185,11 @@
 	public boolean hasAssists(IInvocationContext context) throws CoreException {
 		ASTNode coveringNode= context.getCoveringNode();
 		if (coveringNode != null) {
+			ArrayList<ASTNode> coveredNodes= AdvancedQuickAssistProcessor.getFullyCoveredNodes(context, coveringNode);
 			return getCatchClauseToThrowsProposals(context, coveringNode, null)
+				|| getPickoutTypeFromMulticatchProposals(context, coveringNode, coveredNodes, null)
+				|| getConvertToMultiCatchProposals(context, coveringNode, null)
+				|| getUnrollMultiCatchProposals(context, coveringNode, null)
 				|| getRenameLocalProposals(context, coveringNode, null, null)
 				|| getRenameRefactoringProposal(context, coveringNode, null, null)
 				|| getAssignToVariableProposals(context, coveringNode, null, null)
@@ -205,7 +213,8 @@
 				|| getRemoveBlockProposals(context, coveringNode, null)
 				|| getMakeVariableDeclarationFinalProposals(context, null)
 				|| getMissingCaseStatementProposals(context, coveringNode, null)
-				|| getConvertStringConcatenationProposals(context, null);
+				|| getConvertStringConcatenationProposals(context, null)
+				|| getInferDiamondArgumentsProposal(context, coveringNode, null, null);
 		}
 		return false;
 	}
@@ -213,6 +222,7 @@
 	public IJavaCompletionProposal[] getAssists(IInvocationContext context, IProblemLocation[] locations) throws CoreException {
 		ASTNode coveringNode= context.getCoveringNode();
 		if (coveringNode != null) {
+			ArrayList<ASTNode> coveredNodes= AdvancedQuickAssistProcessor.getFullyCoveredNodes(context, coveringNode);
 			ArrayList<ICommandAccess> resultingCollections= new ArrayList<ICommandAccess>();
 			boolean noErrorsAtLocation= noErrorsAtLocation(locations);
 
@@ -221,10 +231,14 @@
 			getRenameRefactoringProposal(context, coveringNode, locations, resultingCollections);
 			getAssignToVariableProposals(context, coveringNode, locations, resultingCollections);
 			getAssignParamToFieldProposals(context, coveringNode, resultingCollections);
+			getInferDiamondArgumentsProposal(context, coveringNode, locations, resultingCollections);
 
 			if (noErrorsAtLocation) {
 				boolean problemsAtLocation= locations.length != 0;
 				getCatchClauseToThrowsProposals(context, coveringNode, resultingCollections);
+				getPickoutTypeFromMulticatchProposals(context, coveringNode, coveredNodes, resultingCollections);
+				getConvertToMultiCatchProposals(context, coveringNode, resultingCollections);
+				getUnrollMultiCatchProposals(context, coveringNode, resultingCollections);
 				getUnWrapProposals(context, coveringNode, resultingCollections);
 				getJoinVariableProposals(context, coveringNode, resultingCollections);
 				getSplitVariableProposals(context, coveringNode, resultingCollections);
@@ -465,6 +479,77 @@
 		return false;
 	}
 
+	public static boolean getInferDiamondArgumentsProposal(IInvocationContext context, ASTNode node, IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
+		ParameterizedType createdType= null;
+		
+		if (node instanceof Name) {
+			Name name= ASTNodes.getTopMostName((Name) node);
+			if (name.getLocationInParent() == SimpleType.NAME_PROPERTY) {
+				SimpleType type= (SimpleType) name.getParent();
+				if (type.getLocationInParent() == ParameterizedType.TYPE_PROPERTY) {
+					createdType= (ParameterizedType) type.getParent();
+					if (createdType.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY) {
+						return false;
+					}
+				}
+			}
+		} else if (node instanceof ParameterizedType) {
+			createdType= (ParameterizedType) node;
+			if (createdType.getLocationInParent() != ClassInstanceCreation.TYPE_PROPERTY) {
+				return false;
+			}
+		} else if (node instanceof ClassInstanceCreation) {
+			ClassInstanceCreation creation= (ClassInstanceCreation) node;
+			Type type= creation.getType();
+			if (type instanceof ParameterizedType) {
+				createdType= (ParameterizedType) type;
+			}
+		}
+		
+		if (createdType == null || createdType.typeArguments().size() != 0) {
+			return false;
+		}
+		
+		ITypeBinding binding= createdType.resolveBinding();
+		if (binding == null) {
+			return false;
+		}
+		
+		ITypeBinding[] typeArguments= binding.getTypeArguments();
+		if (typeArguments.length == 0) {
+			return false;
+		}
+		
+		if (resultingCollections == null) {
+			return true;
+		}
+
+		// don't add if already added as quick fix
+		if (containsMatchingProblem(locations, IProblem.DiamondNotBelow17))
+			return false;
+		
+		AST ast= node.getAST();
+		ASTRewrite rewrite= ASTRewrite.create(ast);
+		ImportRewrite importRewrite= StubUtility.createImportRewrite(context.getASTRoot(), true);
+		ContextSensitiveImportRewriteContext importContext= new ContextSensitiveImportRewriteContext(context.getASTRoot(), createdType.getStartPosition(), importRewrite);
+
+		String label= CorrectionMessages.QuickAssistProcessor_infer_diamond_description;
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+		int relevance= locations == null ? 7 : 1; // if error -> higher than ReorgCorrectionsSubProcessor.getNeedHigherComplianceProposals()
+		LinkedCorrectionProposal proposal= new LinkedCorrectionProposal(label, context.getCompilationUnit(), rewrite, relevance, image);
+
+		ListRewrite argumentsRewrite= rewrite.getListRewrite(createdType, ParameterizedType.TYPE_ARGUMENTS_PROPERTY);
+		for (int i= 0; i < typeArguments.length; i++) {
+			ITypeBinding typeArgument= typeArguments[i];
+			Type argumentNode= importRewrite.addImport(typeArgument, ast, importContext);
+			argumentsRewrite.insertLast(argumentNode, null);
+			proposal.addLinkedPosition(rewrite.track(argumentNode), true, "arg" + i); //$NON-NLS-1$
+		}
+
+		resultingCollections.add(proposal);
+		return true;
+	}
+
 	private static boolean getJoinVariableProposals(IInvocationContext context, ASTNode node, Collection<ICommandAccess> resultingCollections) {
 		ASTNode parent= node.getParent();
 
@@ -577,6 +662,9 @@
 		if (fragParent instanceof VariableDeclarationStatement) {
 			statement= (VariableDeclarationStatement) fragParent;
 		} else if (fragParent instanceof VariableDeclarationExpression) {
+			if (fragParent.getLocationInParent() == TryStatement.RESOURCES_PROPERTY) {
+				return false;
+			}
 			statement= (Statement) fragParent.getParent();
 		} else {
 			return false;
@@ -1163,7 +1251,7 @@
 		}
 
 		Type type= catchClause.getException().getType();
-		if (!type.isSimpleType()) {
+		if (!type.isSimpleType() && !type.isUnionType()) {
 			return false;
 		}
 
@@ -1177,44 +1265,88 @@
 		}
 
 		AST ast= bodyDeclaration.getAST();
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+
+		SimpleType selectedMultiCatchType= null;
+		if (type.isUnionType() && node instanceof Name) {
+			Name topMostName= ASTNodes.getTopMostName((Name) node);
+			ASTNode parent= topMostName.getParent();
+			if (parent instanceof SimpleType) {
+				selectedMultiCatchType= (SimpleType) parent;
+			}
+		}
 
 		if (bodyDeclaration instanceof MethodDeclaration) {
 			MethodDeclaration methodDeclaration= (MethodDeclaration) bodyDeclaration;
 
 			ASTRewrite rewrite= ASTRewrite.create(ast);
-
-			removeCatchBlock(rewrite, catchClause);
-
-			ITypeBinding binding= type.resolveBinding();
-			if (binding == null || isNotYetThrown(binding, methodDeclaration.thrownExceptions())) {
-				Name name= ((SimpleType) type).getName();
-				Name newName= (Name) ASTNode.copySubtree(ast, name);
-
-				ListRewrite listRewriter= rewrite.getListRewrite(methodDeclaration, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
-				listRewriter.insertLast(newName, null);
+			if (selectedMultiCatchType != null) {
+				removeException(rewrite, (UnionType) type, selectedMultiCatchType);
+				addExceptionToThrows(ast, methodDeclaration, rewrite, selectedMultiCatchType);
+				String label= CorrectionMessages.QuickAssistProcessor_exceptiontothrows_description;
+				ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 6, image);
+				resultingCollections.add(proposal);
+			} else {
+				removeCatchBlock(rewrite, catchClause);
+				if (type.isUnionType()) {
+					UnionType unionType= (UnionType) type;
+					List<Type> types= unionType.types();
+					for (Type elementType : types) {
+						if (!(elementType instanceof SimpleType))
+							return false;
+						addExceptionToThrows(ast, methodDeclaration, rewrite, (SimpleType) elementType);
+					}
+				} else {
+					addExceptionToThrows(ast, methodDeclaration, rewrite, (SimpleType) type);
+				}
+				String label= CorrectionMessages.QuickAssistProcessor_catchclausetothrows_description;
+				ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 4, image);
+				resultingCollections.add(proposal);
 			}
-
-			String label= CorrectionMessages.QuickAssistProcessor_catchclausetothrows_description;
-			Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
-			ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 4, image);
-			resultingCollections.add(proposal);
 		}
-		{  // for initializers or method declarations
+		{ // for initializers or method declarations
 			ASTRewrite rewrite= ASTRewrite.create(ast);
-
-			removeCatchBlock(rewrite, catchClause);
-			String label= CorrectionMessages.QuickAssistProcessor_removecatchclause_description;
-			Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
-			ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image);
-			resultingCollections.add(proposal);
+			if (selectedMultiCatchType != null) {
+				removeException(rewrite, (UnionType) type, selectedMultiCatchType);
+				String label= CorrectionMessages.QuickAssistProcessor_removeexception_description;
+				ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 6, image);
+				resultingCollections.add(proposal);
+			} else {
+				removeCatchBlock(rewrite, catchClause);
+				String label= CorrectionMessages.QuickAssistProcessor_removecatchclause_description;
+				ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image);
+				resultingCollections.add(proposal);
+			}
 		}
 
 		return true;
 	}
 
+	private static void removeException(ASTRewrite rewrite, UnionType unionType, Type exception) {
+		ListRewrite listRewrite= rewrite.getListRewrite(unionType, UnionType.TYPES_PROPERTY);
+		List<Type> types= unionType.types();
+		for (Iterator<Type> iterator= types.iterator(); iterator.hasNext();) {
+			Type type= iterator.next();
+			if (type.equals(exception)) {
+				listRewrite.remove(type, null);
+			}
+		}
+	}
+
+	private static void addExceptionToThrows(AST ast, MethodDeclaration methodDeclaration, ASTRewrite rewrite, SimpleType type2) {
+		ITypeBinding binding= type2.resolveBinding();
+		if (binding == null || isNotYetThrown(binding, methodDeclaration.thrownExceptions())) {
+			Name name= type2.getName();
+			Name newName= (Name) ASTNode.copySubtree(ast, name);
+
+			ListRewrite listRewriter= rewrite.getListRewrite(methodDeclaration, MethodDeclaration.THROWN_EXCEPTIONS_PROPERTY);
+			listRewriter.insertLast(newName, null);
+		}
+	}
+
 	private static void removeCatchBlock(ASTRewrite rewrite, CatchClause catchClause) {
 		TryStatement tryStatement= (TryStatement) catchClause.getParent();
-		if (tryStatement.catchClauses().size() > 1 || tryStatement.getFinally() != null) {
+		if (tryStatement.catchClauses().size() > 1 || tryStatement.getFinally() != null || (tryStatement.getAST().apiLevel() >= AST.JLS4 && !tryStatement.resources().isEmpty())) {
 			rewrite.remove(catchClause, null);
 		} else {
 			Block block= tryStatement.getBody();
@@ -1253,6 +1385,244 @@
 		return true;
 	}
 
+	private static boolean getPickoutTypeFromMulticatchProposals(IInvocationContext context, ASTNode node, ArrayList<ASTNode> coveredNodes, Collection<ICommandAccess> resultingCollections) {
+		CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(node, ASTNode.CATCH_CLAUSE);
+		if (catchClause == null) {
+			return false;
+		}
+
+		Statement statement= ASTResolving.findParentStatement(node);
+		if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
+			return false; // selection is in a statement inside the body
+		}
+
+		Type type= catchClause.getException().getType();
+		if (!type.isUnionType()) {
+			return false;
+		}
+
+		SimpleType selectedMultiCatchType= null;
+		if (type.isUnionType() && node instanceof Name) {
+			Name topMostName= ASTNodes.getTopMostName((Name) node);
+			ASTNode parent= topMostName.getParent();
+			if (parent instanceof SimpleType) {
+				selectedMultiCatchType= (SimpleType) parent;
+			}
+		}
+
+		boolean multipleExceptions= coveredNodes.size() > 1;
+		if ((selectedMultiCatchType == null) && (!(node instanceof UnionType) || !multipleExceptions)) {
+			return false;
+		}
+
+		if (!multipleExceptions) {
+			coveredNodes.add(selectedMultiCatchType);
+		}
+
+		BodyDeclaration bodyDeclaration= ASTResolving.findParentBodyDeclaration(catchClause);
+		if (!(bodyDeclaration instanceof MethodDeclaration) && !(bodyDeclaration instanceof Initializer)) {
+			return false;
+		}
+
+		if (resultingCollections == null) {
+			return true;
+		}
+
+		AST ast= bodyDeclaration.getAST();
+		ASTRewrite rewrite= ASTRewrite.create(ast);
+
+		CatchClause newCatchClause= ast.newCatchClause();
+		SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration();
+		UnionType newUnionType= ast.newUnionType();
+		List<Type> types= newUnionType.types();
+		for (int i= 0; i < coveredNodes.size(); i++) {
+			ASTNode typeNode= coveredNodes.get(i);
+			types.add((Type) rewrite.createCopyTarget(typeNode));
+			rewrite.remove(typeNode, null);
+		}
+		newSingleVariableDeclaration.setType(newUnionType);
+		newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(catchClause.getException().getName()));
+		newCatchClause.setException(newSingleVariableDeclaration);
+
+		setCatchClauseBody(newCatchClause, rewrite, catchClause);
+
+		TryStatement tryStatement= (TryStatement)catchClause.getParent();
+		ListRewrite listRewrite= rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY);
+		listRewrite.insertAfter(newCatchClause, catchClause, null);
+
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_OBJS_EXCEPTION);
+		String label= !multipleExceptions
+				? CorrectionMessages.QuickAssistProcessor_move_exception_to_separate_catch_block
+				: CorrectionMessages.QuickAssistProcessor_move_exceptions_to_separate_catch_block;
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 6, image);
+		resultingCollections.add(proposal);
+		return true;
+	}
+
+	private static boolean getConvertToMultiCatchProposals(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
+		if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject()))
+			return false;
+
+		CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(covering, ASTNode.CATCH_CLAUSE);
+		if (catchClause == null) {
+			return false;
+		}
+
+		Statement statement= ASTResolving.findParentStatement(covering);
+		if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
+			return false; // selection is in a statement inside the body
+		}
+
+		Type type1= catchClause.getException().getType();
+		SimpleType selectedMultiCatchType= null;
+		if (type1.isUnionType() && covering instanceof Name) {
+			Name topMostName= ASTNodes.getTopMostName((Name) covering);
+			ASTNode parent= topMostName.getParent();
+			if (parent instanceof SimpleType) {
+				selectedMultiCatchType= (SimpleType) parent;
+			}
+		}
+		if (selectedMultiCatchType != null)
+			return false;
+
+		TryStatement tryStatement= (TryStatement) catchClause.getParent();
+		List<CatchClause> catchClauses= tryStatement.catchClauses();
+		if (catchClauses.size() <= 1)
+			return false;
+
+		String commonSource= null;
+		try {
+			IBuffer buffer= context.getCompilationUnit().getBuffer();
+			for (Iterator<CatchClause> iterator= catchClauses.iterator(); iterator.hasNext();) {
+				CatchClause catchClause1= iterator.next();
+				Block body= catchClause1.getBody();
+				String source= buffer.getText(body.getStartPosition(), body.getLength());
+				if (commonSource == null) {
+					commonSource= source;
+				} else {
+					if (!commonSource.equals(source))
+						return false;
+				}
+			}
+		} catch (JavaModelException e) {
+			return false;
+		}
+
+		if (resultingCollections == null)
+			return true;
+
+		AST ast= covering.getAST();
+		ASTRewrite rewrite= ASTRewrite.create(ast);
+		TightSourceRangeComputer sourceRangeComputer= new TightSourceRangeComputer();
+		sourceRangeComputer.addTightSourceNode(catchClauses.get(catchClauses.size() - 1));
+		rewrite.setTargetSourceRangeComputer(sourceRangeComputer);
+		
+		CatchClause firstCatchClause= catchClauses.get(0);
+
+		UnionType newUnionType= ast.newUnionType();
+		List<Type> types= newUnionType.types();
+		for (Iterator<CatchClause> iterator= catchClauses.iterator(); iterator.hasNext();) {
+			CatchClause catchClause1= iterator.next();
+			Type type= catchClause1.getException().getType();
+			if (type instanceof UnionType) {
+				List<Type> types2= ((UnionType) type).types();
+				for (Iterator<Type> iterator2= types2.iterator(); iterator2.hasNext();) {
+					types.add((Type) rewrite.createCopyTarget(iterator2.next()));
+				}
+			} else {
+				types.add((Type) rewrite.createCopyTarget(type));
+			}
+		}
+
+		SingleVariableDeclaration newExceptionDeclaration= ast.newSingleVariableDeclaration();
+		newExceptionDeclaration.setType(newUnionType);
+		newExceptionDeclaration.setName((SimpleName) rewrite.createCopyTarget(firstCatchClause.getException().getName()));
+		rewrite.replace(firstCatchClause.getException(), newExceptionDeclaration, null);
+
+		for (int i= 1; i < catchClauses.size(); i++) {
+			rewrite.remove(catchClauses.get(i), null);
+		}
+
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+		String label= CorrectionMessages.QuickAssistProcessor_convert_to_single_multicatch_block;
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 2, image);
+		resultingCollections.add(proposal);
+		return true;
+	}
+
+	private static boolean getUnrollMultiCatchProposals(IInvocationContext context, ASTNode covering, Collection<ICommandAccess> resultingCollections) {
+		if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject()))
+			return false;
+
+		CatchClause catchClause= (CatchClause) ASTResolving.findAncestor(covering, ASTNode.CATCH_CLAUSE);
+		if (catchClause == null) {
+			return false;
+		}
+
+		Statement statement= ASTResolving.findParentStatement(covering);
+		if (statement != catchClause.getParent() && statement != catchClause.getBody()) {
+			return false; // selection is in a statement inside the body
+		}
+
+		Type type1= catchClause.getException().getType();
+		SimpleType selectedMultiCatchType= null;
+		if (type1.isUnionType() && covering instanceof Name) {
+			Name topMostName= ASTNodes.getTopMostName((Name) covering);
+			ASTNode parent= topMostName.getParent();
+			if (parent instanceof SimpleType) {
+				selectedMultiCatchType= (SimpleType) parent;
+			}
+		}
+		if (selectedMultiCatchType != null)
+			return false;
+
+		SingleVariableDeclaration singleVariableDeclaration= catchClause.getException();
+		Type type= singleVariableDeclaration.getType();
+		if (!(type instanceof UnionType))
+			return false;
+
+		if (resultingCollections == null)
+			return true;
+
+		AST ast= covering.getAST();
+		ASTRewrite rewrite= ASTRewrite.create(ast);
+
+		TryStatement tryStatement= (TryStatement) catchClause.getParent();
+		ListRewrite listRewrite= rewrite.getListRewrite(tryStatement, TryStatement.CATCH_CLAUSES_PROPERTY);
+
+		UnionType unionType= (UnionType) type;
+		List<Type> types= unionType.types();
+		for (int i= types.size() - 1; i >= 0; i--) {
+			Type type2= types.get(i);
+			CatchClause newCatchClause= ast.newCatchClause();
+
+			SingleVariableDeclaration newSingleVariableDeclaration= ast.newSingleVariableDeclaration();
+			newSingleVariableDeclaration.setType((Type) rewrite.createCopyTarget(type2));
+			newSingleVariableDeclaration.setName((SimpleName) rewrite.createCopyTarget(singleVariableDeclaration.getName()));
+			newCatchClause.setException(newSingleVariableDeclaration);
+			setCatchClauseBody(newCatchClause, rewrite, catchClause);
+			listRewrite.insertAfter(newCatchClause, catchClause, null);
+		}
+		rewrite.remove(catchClause, null);
+
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+		String label= CorrectionMessages.QuickAssistProcessor_convert_to_multiple_singletype_catch_blocks;
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 2, image);
+		resultingCollections.add(proposal);
+		return true;
+	}
+
+	private static void setCatchClauseBody(CatchClause newCatchClause, ASTRewrite rewrite, CatchClause catchClause) {
+		// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=350285
+		
+//		newCatchClause.setBody((Block) rewrite.createCopyTarget(catchClause.getBody()));
+		
+		//newCatchClause#setBody() destroys the formatting, hence copy statement by statement.
+		List<Statement> statements= catchClause.getBody().statements();
+		for (Iterator<Statement> iterator2= statements.iterator(); iterator2.hasNext();) {
+			newCatchClause.getBody().statements().add(rewrite.createCopyTarget(iterator2.next()));
+		}
+	}
 
 	private static boolean getRenameLocalProposals(IInvocationContext context, ASTNode node, IProblemLocation[] locations, Collection<ICommandAccess> resultingCollections) {
 		if (!(node instanceof SimpleName)) {
@@ -1404,7 +1774,7 @@
 			label= CorrectionMessages.QuickAssistProcessor_unwrap_dostatement;
 		} else if (outer instanceof TryStatement) {
 			TryStatement tryStatement= (TryStatement) outer;
-			if (tryStatement.catchClauses().isEmpty()) {
+			if (tryStatement.catchClauses().isEmpty() && (tryStatement.getAST().apiLevel() >= AST.JLS4 && tryStatement.resources().isEmpty())) {
 				body= tryStatement.getBody();
 			}
 			label= CorrectionMessages.QuickAssistProcessor_unwrap_trystatement;
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
index d73ffa0..def8629 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/QuickFixProcessor.java
@@ -19,6 +19,7 @@
 
 import org.eclipse.jdt.core.IBuffer;
 import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.IProblem;
 
@@ -57,8 +58,10 @@
 			case IProblem.UndefinedType:
 			case IProblem.TypeMismatch:
 			case IProblem.UnhandledException:
+			case IProblem.UnhandledExceptionOnAutoClose:
 			case IProblem.UnreachableCatch:
 			case IProblem.InvalidCatchBlockSequence:
+			case IProblem.InvalidUnionTypeReferenceSequence:
 			case IProblem.VoidMethodReturnsValue:
 			case IProblem.ShouldReturnValue:
 			case IProblem.MissingReturnType:
@@ -200,6 +203,9 @@
 			case IProblem.UnnecessaryNLSTag:
 			case IProblem.AssignmentHasNoEffect:
 			case IProblem.UnsafeTypeConversion:
+			case IProblem.RawTypeReference:
+			case IProblem.UnsafeRawMethodInvocation:
+			case IProblem.RedundantSpecificationOfTypeArguments:
 			case IProblem.UndefinedAnnotationMember:
 			case IProblem.MissingValueForAnnotationMember:
 			case IProblem.FallthroughCase:
@@ -214,6 +220,17 @@
 			case IProblem.UnusedObjectAllocation:
 			case IProblem.MethodCanBeStatic:
 			case IProblem.MethodCanBePotentiallyStatic:
+			case IProblem.AutoManagedResourceNotBelow17:
+			case IProblem.MultiCatchNotBelow17:
+			case IProblem.PolymorphicMethodNotBelow17:
+			case IProblem.BinaryLiteralNotBelow17:
+			case IProblem.UnderscoresInLiteralsNotBelow17:
+			case IProblem.SwitchOnStringsNotBelow17:
+			case IProblem.DiamondNotBelow17:
+			case IProblem.PotentialHeapPollutionFromVararg :
+			case IProblem.UnsafeGenericArrayForVarargs:
+			case IProblem.SafeVarargsOnFixedArityMethod :
+			case IProblem.SafeVarargsOnNonFinalInstanceMethod:
 				return true;
 			default:
 				return SuppressWarningsSubProcessor.hasSuppressWarningsProposal(cu.getJavaProject(), problemId);
@@ -230,6 +247,7 @@
 				offset--;
 			}
 		} catch(JavaModelException e) {
+			// use start
 		}
 		return start;
 	}
@@ -323,10 +341,12 @@
 				TypeMismatchSubProcessor.addIncompatibleThrowsProposals(context, problem, proposals);
 				break;
 			case IProblem.UnhandledException:
+			case IProblem.UnhandledExceptionOnAutoClose:
 				LocalCorrectionsSubProcessor.addUncaughtExceptionProposals(context, problem, proposals);
 				break;
 			case IProblem.UnreachableCatch:
 			case IProblem.InvalidCatchBlockSequence:
+			case IProblem.InvalidUnionTypeReferenceSequence:
 				LocalCorrectionsSubProcessor.addUnreachableCatchProposals(context, problem, proposals);
 				break;
 			case IProblem.RedundantSuperinterface:
@@ -548,7 +568,18 @@
 			case IProblem.InvalidUsageOfVarargs:
 			case IProblem.InvalidUsageOfAnnotations:
 			case IProblem.InvalidUsageOfAnnotationDeclarations:
-				ReorgCorrectionsSubProcessor.getNeed50ComplianceProposals(context, problem, proposals);
+				ReorgCorrectionsSubProcessor.getNeedHigherComplianceProposals(context, problem, proposals, JavaCore.VERSION_1_5);
+				break;
+			case IProblem.DiamondNotBelow17:
+				TypeArgumentMismatchSubProcessor.getInferDiamondArgumentsProposal(context, problem, proposals);
+				//$FALL-THROUGH$
+			case IProblem.AutoManagedResourceNotBelow17:
+			case IProblem.MultiCatchNotBelow17:
+			case IProblem.PolymorphicMethodNotBelow17:
+			case IProblem.BinaryLiteralNotBelow17:
+			case IProblem.UnderscoresInLiteralsNotBelow17:
+			case IProblem.SwitchOnStringsNotBelow17:
+				ReorgCorrectionsSubProcessor.getNeedHigherComplianceProposals(context, problem, proposals, JavaCore.VERSION_1_7);
 				break;
 			case IProblem.NonGenericType:
 				TypeArgumentMismatchSubProcessor.removeMismatchedArguments(context, problem, proposals);
@@ -585,6 +616,9 @@
 				LocalCorrectionsSubProcessor.addDeprecatedFieldsToMethodsProposals(context, problem, proposals);
 				LocalCorrectionsSubProcessor.addTypePrametersToRawTypeReference(context, problem, proposals);
 				break;
+			case IProblem.RedundantSpecificationOfTypeArguments:
+				LocalCorrectionsSubProcessor.addRemoveRedundantTypeArgumentsProposals(context, problem, proposals);
+				break;
 			case IProblem.FallthroughCase:
 				LocalCorrectionsSubProcessor.addFallThroughProposals(context, problem, proposals);
 				break;
@@ -607,6 +641,16 @@
 			case IProblem.MethodCanBePotentiallyStatic:
 				ModifierCorrectionSubProcessor.addStaticMethodProposal(context, problem, proposals);
 				break;
+			case IProblem.PotentialHeapPollutionFromVararg :
+				VarargsWarningsSubProcessor.addAddSafeVarargsProposals(context, problem, proposals);
+				break;
+			case IProblem.UnsafeGenericArrayForVarargs:
+				VarargsWarningsSubProcessor.addAddSafeVarargsToDeclarationProposals(context, problem, proposals);
+				break;
+			case IProblem.SafeVarargsOnFixedArityMethod :
+			case IProblem.SafeVarargsOnNonFinalInstanceMethod:
+				VarargsWarningsSubProcessor.addRemoveSafeVarargsProposals(context, problem, proposals);
+				break;
 			default:
 		}
 		if (JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) {
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ReorgCorrectionsSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ReorgCorrectionsSubProcessor.java
index 727c9c0..f18ba79 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ReorgCorrectionsSubProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/ReorgCorrectionsSubProcessor.java
@@ -89,6 +89,8 @@
 import org.eclipse.jdt.launching.IVMInstall2;
 import org.eclipse.jdt.launching.IVMInstallType;
 import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
+import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
 
 import org.eclipse.jdt.ui.JavaElementLabels;
 import org.eclipse.jdt.ui.actions.OrganizeImportsAction;
@@ -362,38 +364,62 @@
 		}
 	}
 
-	private static final class ChangeTo50Compliance extends ChangeCorrectionProposal implements IWorkspaceRunnable {
+	private static final class ChangeToRequiredCompilerCompliance extends ChangeCorrectionProposal implements IWorkspaceRunnable {
 
 		private final IJavaProject fProject;
 		private final boolean fChangeOnWorkspace;
+		private final String fRequiredVersion;
 
 		private Job fUpdateJob;
-		private boolean f50JREFound;
+		private boolean fRequiredJREFound;
 
-		public ChangeTo50Compliance(String name, IJavaProject project, boolean changeOnWorkspace, int relevance) {
+		public ChangeToRequiredCompilerCompliance(String name, IJavaProject project, boolean changeOnWorkspace, String requiredVersion, int relevance) {
 			super(name, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE));
 			fProject= project;
 			fChangeOnWorkspace= changeOnWorkspace;
+			fRequiredVersion= requiredVersion;
 			fUpdateJob= null;
-			f50JREFound= false;
+			fRequiredJREFound= false;
 		}
 
-		private boolean is50orGreaterVMInstall(IVMInstall install) {
+		private boolean isRequiredOrGreaterVMInstall(IVMInstall install) {
 			if (install instanceof IVMInstall2) {
 				String compliance= JavaModelUtil.getCompilerCompliance((IVMInstall2) install, JavaCore.VERSION_1_3);
-				return JavaModelUtil.is50OrHigher(compliance);
+				return !JavaModelUtil.isVersionLessThan(compliance, fRequiredVersion);
 			}
 			return false;
 		}
 
-		private IVMInstall find50OrGreaterVMInstall() {
+		private String getVMInstallCompliance(IVMInstall install) {
+			if (install instanceof IVMInstall2) {
+				String compliance= JavaModelUtil.getCompilerCompliance((IVMInstall2) install, JavaCore.VERSION_1_3);
+				return compliance;
+			}
+			return JavaCore.VERSION_1_1;
+		}
+		
+		private IVMInstall findRequiredOrGreaterVMInstall() {
+			String bestMatchingCompliance= null;
+			IVMInstall bestMatchingVMInstall= null;
 			IVMInstallType[] installTypes= JavaRuntime.getVMInstallTypes();
 			for (int i= 0; i < installTypes.length; i++) {
 				IVMInstall[] installs= installTypes[i].getVMInstalls();
 				for (int k= 0; k < installs.length; k++) {
-					if (is50orGreaterVMInstall(installs[k])) {
-						return installs[k];
+					String vmInstallCompliance= getVMInstallCompliance(installs[k]);
+					
+					if (fRequiredVersion.equals(vmInstallCompliance)) {
+						return installs[k]; // perfect match
+						
+					} else if (JavaModelUtil.isVersionLessThan(vmInstallCompliance, fRequiredVersion)) {
+						continue; // no match
+						
+					} else if (bestMatchingVMInstall != null) {
+						if (JavaModelUtil.isVersionLessThan(bestMatchingCompliance, vmInstallCompliance)) {
+							continue; // the other one is the least matching
+						}
 					}
+					bestMatchingCompliance= vmInstallCompliance;
+					bestMatchingVMInstall= installs[k];
 				}
 			}
 			return null;
@@ -407,12 +433,16 @@
 		}
 
 		private boolean updateJRE( IProgressMonitor monitor) throws CoreException, JavaModelException {
+			// Caveat: Returns true iff the classpath has not been changed.
+			// If the classpath is changed, JDT Core triggers a build for free.
+			// If the classpath is not changed, we have to trigger a build because we changed
+			// the compiler compliance in #apply(IDocument).
 			try {
-				IVMInstall vm50Install= find50OrGreaterVMInstall();
-				f50JREFound= vm50Install != null;
-				if (vm50Install != null) {
-					IVMInstall install= JavaRuntime.getVMInstall(fProject); // can be null
-					if (fChangeOnWorkspace) {
+				if (fChangeOnWorkspace) {
+					IVMInstall vmInstall= findRequiredOrGreaterVMInstall();
+					fRequiredJREFound= vmInstall != null;
+					if (vmInstall != null) {
+						IVMInstall install= JavaRuntime.getVMInstall(fProject); // can be null
 						monitor.beginTask(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_operation, 4);
 						IVMInstall defaultVM= JavaRuntime.getDefaultVMInstall(); // can be null
 						if (defaultVM != null && !defaultVM.equals(install)) {
@@ -421,17 +451,20 @@
 						} else {
 							monitor.worked(1);
 						}
-						if (defaultVM == null || !is50orGreaterVMInstall(defaultVM)) {
-							JavaRuntime.setDefaultVMInstall(vm50Install, new SubProgressMonitor(monitor, 3), true);
+						if (defaultVM == null || !isRequiredOrGreaterVMInstall(defaultVM)) {
+							JavaRuntime.setDefaultVMInstall(vmInstall, new SubProgressMonitor(monitor, 3), true);
 							return false;
 						}
 						return true;
-					} else {
-						if (install == null || !is50orGreaterVMInstall(install)) {
-							IPath newPath= new Path(JavaRuntime.JRE_CONTAINER).append(vm50Install.getVMInstallType().getId()).append(vm50Install.getName());
-							updateClasspath(newPath, monitor);
-							return false;
-						}
+					}
+
+				} else {
+					IExecutionEnvironment bestEE= findBestMatchingEE();
+					fRequiredJREFound= bestEE != null;
+					if (bestEE != null) {
+						IPath newPath= JavaRuntime.newJREContainerPath(bestEE);
+						boolean classpathUpdated= updateClasspath(newPath, monitor);
+						return !classpathUpdated;
 					}
 				}
 			} finally {
@@ -440,16 +473,61 @@
 			return true;
 		}
 
-		private void updateClasspath(IPath newPath, IProgressMonitor monitor) throws JavaModelException {
+		private IExecutionEnvironment findBestMatchingEE() {
+			IExecutionEnvironmentsManager eeManager= JavaRuntime.getExecutionEnvironmentsManager();
+			IExecutionEnvironment[] ees= eeManager.getExecutionEnvironments();
+			IExecutionEnvironment bestEE= null;
+			String bestEECompliance= null;
+			
+			for (int i= 0; i < ees.length; i++) {
+				IExecutionEnvironment ee= ees[i];
+				String eeCompliance= JavaModelUtil.getExecutionEnvironmentCompliance(ee);
+				String eeId= ee.getId();
+				
+				if (fRequiredVersion.equals(eeCompliance)) {
+					if (eeId.startsWith("J") && eeId.endsWith(fRequiredVersion)) { //$NON-NLS-1$
+						bestEE= ee;
+						break; // perfect match
+					}
+					
+				} else if (JavaModelUtil.isVersionLessThan(eeCompliance, fRequiredVersion)) {
+					continue; // no match
+					
+				} else { // possible match
+					if (bestEE != null) {
+						if (! eeId.startsWith("J")) { //$NON-NLS-1$
+							continue; // avoid taking e.g. OSGi profile if a Java profile is available
+						}
+						if (JavaModelUtil.isVersionLessThan(bestEECompliance, eeCompliance)) {
+							continue; // the other one is the least matching
+						}
+					}
+				}
+				// found a new best
+				bestEE= ee;
+				bestEECompliance= eeCompliance;
+			}
+			return bestEE;
+		}
+
+		private boolean updateClasspath(IPath newPath, IProgressMonitor monitor) throws JavaModelException {
+			boolean updated= false;
+			
 			IClasspathEntry[] classpath= fProject.getRawClasspath();
 			IPath jreContainerPath= new Path(JavaRuntime.JRE_CONTAINER);
 			for (int i= 0; i < classpath.length; i++) {
 				IClasspathEntry curr= classpath[i];
 				if (curr.getEntryKind() == IClasspathEntry.CPE_CONTAINER && curr.getPath().matchingFirstSegments(jreContainerPath) > 0) {
-					classpath[i]= JavaCore.newContainerEntry(newPath, curr.getAccessRules(), curr.getExtraAttributes(), curr.isExported());
+					if (! newPath.equals(curr.getPath())) {
+						updated= true;
+						classpath[i]= JavaCore.newContainerEntry(newPath, curr.getAccessRules(), curr.getExtraAttributes(), curr.isExported());
+					}
 				}
 			}
-			fProject.setRawClasspath(classpath, monitor);
+			if (updated) {
+				fProject.setRawClasspath(classpath, monitor);
+			}
+			return updated;
 		}
 
 		/* (non-Javadoc)
@@ -459,35 +537,48 @@
 		public Object getAdditionalProposalInfo(IProgressMonitor monitor) {
 			StringBuffer message= new StringBuffer();
 			if (fChangeOnWorkspace) {
-				message.append(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeworkspace_description);
+				message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_required_compliance_changeworkspace_description, fRequiredVersion));
 			} else {
-				message.append(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeproject_description);
+				message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_required_compliance_changeproject_description, fRequiredVersion));
 			}
 
-			IVMInstall vm50Install= find50OrGreaterVMInstall();
-			if (vm50Install != null) {
-				try {
-					IVMInstall install= JavaRuntime.getVMInstall(fProject); // can be null
-					if (fChangeOnWorkspace) {
+			try {
+				IVMInstall install= JavaRuntime.getVMInstall(fProject); // can be null
+				if (fChangeOnWorkspace) {
+					IVMInstall vmInstall= findRequiredOrGreaterVMInstall();
+					if (vmInstall != null) {
 						IVMInstall defaultVM= JavaRuntime.getDefaultVMInstall(); // can be null
 						if (defaultVM != null && !defaultVM.equals(install)) {
 							message.append(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeProjectJREToDefault_description);
 						}
-						if (defaultVM == null || !is50orGreaterVMInstall(defaultVM)) {
-							message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeWorkspaceJRE_description, vm50Install.getName()));
-						}
-					} else {
-						if (install == null || !is50orGreaterVMInstall(install)) {
-							message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeProjectJRE_description, vm50Install.getName()));
+						if (defaultVM == null || !isRequiredOrGreaterVMInstall(defaultVM)) {
+							message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeWorkspaceJRE_description, vmInstall.getName()));
 						}
 					}
-				} catch (CoreException e) {
-					// ignore
+				} else {
+					IExecutionEnvironment bestEE= findBestMatchingEE();
+					if (bestEE != null) {
+						if (install == null || !isEEOnClasspath(bestEE)) {
+							message.append(Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_50_compliance_changeProjectJRE_description, bestEE.getId()));
+						}
+					}
 				}
+			} catch (CoreException e) {
+				// ignore
 			}
 			return message.toString();
 		}
 
+		private boolean isEEOnClasspath(IExecutionEnvironment ee) throws JavaModelException {
+			IPath eePath= JavaRuntime.newJREContainerPath(ee);
+			
+			for (IClasspathEntry entry: fProject.getRawClasspath()) {
+				if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().equals(eePath))
+					return true;
+			}
+			return false;
+		}
+
 		/* (non-Javadoc)
 		 * @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(IDocument)
 		 */
@@ -495,15 +586,15 @@
 		public void apply(IDocument document) {
 			if (fChangeOnWorkspace) {
 				Hashtable<String, String> map= JavaCore.getOptions();
-				JavaModelUtil.set50ComplianceOptions(map);
+				JavaModelUtil.setComplianceOptions(map, fRequiredVersion);
 				JavaCore.setOptions(map);
 			} else {
 				Map<String, String> map= fProject.getOptions(false);
 				int optionsCount= map.size();
-				JavaModelUtil.set50ComplianceOptions(map);
+				JavaModelUtil.setComplianceOptions(map, fRequiredVersion);
 				if (map.size() > optionsCount) {
 					// options have been added -> ensure that all compliance options from preference page set
-					JavaModelUtil.setDefaultClassfileOptions(map, JavaCore.VERSION_1_5);
+					JavaModelUtil.setDefaultClassfileOptions(map, fRequiredVersion);
 				}
 				fProject.setOptions(map);
 			}
@@ -520,27 +611,30 @@
 				fUpdateJob.schedule();
 			}
 
-			if (!f50JREFound) {
-				MessageDialog.openInformation(JavaPlugin.getActiveWorkbenchShell(), CorrectionMessages.ReorgCorrectionsSubProcessor_no_50jre_title, CorrectionMessages.ReorgCorrectionsSubProcessor_no_50jre_message);
+			if (!fRequiredJREFound) {
+				MessageDialog.openInformation(JavaPlugin.getActiveWorkbenchShell(),
+						Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_no_required_jre_title, fRequiredVersion),
+						Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_no_required_jre_message, fRequiredVersion));
 			}
 		}
 	}
 
 	/**
-	 * Adds a proposal to change to 5.0 compliance
+	 * Adds a proposal to increase the compiler compliance level
 	 * @param context the context
 	 * @param problem the current problem
 	 * @param proposals the resulting proposals
+	 * @param requiredVersion the minimal required Java compiler version
 	 */
-	public static void getNeed50ComplianceProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+	public static void getNeedHigherComplianceProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals, String requiredVersion) {
 		IJavaProject project= context.getCompilationUnit().getJavaProject();
 
-		String label1= CorrectionMessages.ReorgCorrectionsSubProcessor_50_project_compliance_description;
-		proposals.add(new ChangeTo50Compliance(label1, project, false, 5));
+		String label1= Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_change_project_compliance_description, requiredVersion);
+		proposals.add(new ChangeToRequiredCompilerCompliance(label1, project, false, requiredVersion, 5));
 
 		if (project.getOption(JavaCore.COMPILER_COMPLIANCE, false) == null) {
-			String label2= CorrectionMessages.ReorgCorrectionsSubProcessor_50_workspace_compliance_description;
-			proposals.add(new ChangeTo50Compliance(label2, project, true, 6));
+			String label2= Messages.format(CorrectionMessages.ReorgCorrectionsSubProcessor_change_workspace_compliance_description, requiredVersion);
+			proposals.add(new ChangeToRequiredCompilerCompliance(label2, project, true, requiredVersion, 6));
 		}
 	}
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/TypeArgumentMismatchSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/TypeArgumentMismatchSubProcessor.java
index 3baba23..bbda85b 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/TypeArgumentMismatchSubProcessor.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/TypeArgumentMismatchSubProcessor.java
@@ -67,4 +67,13 @@
 		}
 	}
 
+	public static void getInferDiamondArgumentsProposal(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+		ASTNode selectedNode= problem.getCoveredNode(context.getASTRoot());
+		if (!(selectedNode instanceof SimpleName)) {
+			return;
+		}
+		
+		QuickAssistProcessor.getInferDiamondArgumentsProposal(context, selectedNode, null, proposals);
+	}
+
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/VarargsWarningsSubProcessor.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/VarargsWarningsSubProcessor.java
new file mode 100644
index 0000000..6583f94
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/VarargsWarningsSubProcessor.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.internal.ui.text.correction;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.ui.ISharedImages;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.MarkerAnnotation;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.Modifier;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+import org.eclipse.jdt.internal.corext.util.Messages;
+
+import org.eclipse.jdt.ui.text.java.IInvocationContext;
+import org.eclipse.jdt.ui.text.java.IProblemLocation;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.ASTRewriteCorrectionProposal;
+import org.eclipse.jdt.internal.ui.text.correction.proposals.LinkedCorrectionProposal;
+
+public class VarargsWarningsSubProcessor {
+
+	private static class AddSafeVarargsProposal extends LinkedCorrectionProposal {
+
+		private IMethodBinding fMethodBinding;
+
+		private MethodDeclaration fMethodDeclaration;
+
+		public AddSafeVarargsProposal(String label, ICompilationUnit cu, MethodDeclaration methodDeclaration, IMethodBinding methodBinding, int relevance) {
+			super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_OBJS_JAVADOCTAG));
+			fMethodDeclaration= methodDeclaration;
+			fMethodBinding= methodBinding;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite()
+		 */
+		@Override
+		protected ASTRewrite getRewrite() throws CoreException {
+			if (fMethodDeclaration == null) {
+				CompilationUnit astRoot= ASTResolving.createQuickFixAST(getCompilationUnit(), null);
+				fMethodDeclaration= (MethodDeclaration) astRoot.findDeclaringNode(fMethodBinding.getKey());
+			}
+			AST ast= fMethodDeclaration.getAST();
+			ASTRewrite rewrite= ASTRewrite.create(ast);
+			ListRewrite listRewrite= rewrite.getListRewrite(fMethodDeclaration, MethodDeclaration.MODIFIERS2_PROPERTY);
+
+			MarkerAnnotation annotation= ast.newMarkerAnnotation();
+			String importString= createImportRewrite((CompilationUnit) fMethodDeclaration.getRoot()).addImport("java.lang.SafeVarargs"); //$NON-NLS-1$
+			annotation.setTypeName(ast.newName(importString));
+			listRewrite.insertFirst(annotation, null);
+
+			// set up linked mode
+			addLinkedPosition(rewrite.track(annotation), true, "annotation"); //$NON-NLS-1$
+
+			return rewrite;
+		}
+
+	}
+
+	public static void addAddSafeVarargsProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+		ASTNode coveringNode= problem.getCoveringNode(context.getASTRoot());
+
+		MethodDeclaration methodDeclaration= ASTResolving.findParentMethodDeclaration(coveringNode);
+		if (methodDeclaration == null)
+			return;
+		
+		IMethodBinding methodBinding= methodDeclaration.resolveBinding();
+		if (methodBinding == null)
+			return;
+		
+		int modifiers= methodBinding.getModifiers();
+		if (!Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers) && ! methodBinding.isConstructor())
+			return; 
+		
+		String label= CorrectionMessages.VarargsWarningsSubProcessor_add_safevarargs_label;
+		AddSafeVarargsProposal proposal= new AddSafeVarargsProposal(label, context.getCompilationUnit(), methodDeclaration, null, -2);
+		proposals.add(proposal);
+	}
+
+	public static void addAddSafeVarargsToDeclarationProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+		if (!JavaModelUtil.is17OrHigher(context.getCompilationUnit().getJavaProject()))
+			return;
+
+		ASTNode coveringNode= problem.getCoveringNode(context.getASTRoot());
+		IMethodBinding methodBinding;
+		if (coveringNode instanceof MethodInvocation) {
+			methodBinding= ((MethodInvocation) coveringNode).resolveMethodBinding();
+		} else if (coveringNode instanceof ClassInstanceCreation) {
+			methodBinding= ((ClassInstanceCreation) coveringNode).resolveConstructorBinding();
+		} else {
+			return;
+		}
+		if (methodBinding == null)
+			return;
+		
+		String label= Messages.format(CorrectionMessages.VarargsWarningsSubProcessor_add_safevarargs_to_method_label, methodBinding.getName());
+
+		ITypeBinding declaringType= methodBinding.getDeclaringClass();
+		CompilationUnit astRoot= (CompilationUnit) coveringNode.getRoot();
+		if (declaringType != null && declaringType.isFromSource()) {
+			try {
+				ICompilationUnit targetCu= ASTResolving.findCompilationUnitForBinding(context.getCompilationUnit(), astRoot, declaringType);
+				if (targetCu != null) {
+					AddSafeVarargsProposal proposal= new AddSafeVarargsProposal(label, targetCu, null, methodBinding.getMethodDeclaration(), -2);
+					proposals.add(proposal);
+				}
+			} catch (JavaModelException e) {
+				return;
+			}
+		}
+	}
+
+	public static void addRemoveSafeVarargsProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
+		ASTNode coveringNode= problem.getCoveringNode(context.getASTRoot());
+		if (!(coveringNode instanceof MethodDeclaration))
+			return;
+
+		MethodDeclaration methodDeclaration= (MethodDeclaration) coveringNode;
+		MarkerAnnotation annotation= null;
+
+		List<? extends ASTNode> modifiers= methodDeclaration.modifiers();
+		for (Iterator<? extends ASTNode> iterator= modifiers.iterator(); iterator.hasNext();) {
+			ASTNode node= iterator.next();
+			if (node instanceof MarkerAnnotation) {
+				annotation= (MarkerAnnotation) node;
+				if ("SafeVarargs".equals(annotation.resolveAnnotationBinding().getName())) { //$NON-NLS-1$
+					break;
+				}
+			}
+		}
+
+		if (annotation == null)
+			return;
+
+		ASTRewrite rewrite= ASTRewrite.create(coveringNode.getAST());
+		rewrite.remove(annotation, null);
+
+		String label= CorrectionMessages.VarargsWarningsSubProcessor_remove_safevarargs_label;
+		Image image= JavaPlugin.getDefault().getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE);
+		ASTRewriteCorrectionProposal proposal= new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), rewrite, 5, image);
+		proposals.add(proposal);
+	}
+
+}
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaMethodCompletionProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaMethodCompletionProposal.java
index 7077f1e..6a99476 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaMethodCompletionProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaMethodCompletionProposal.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Tom Eicher <eclipse@tom.eicher.name> - [content assist] prefix complete casted method proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=247547
@@ -324,4 +324,17 @@
 		return ""; //$NON-NLS-1$
 
 	}
+
+	/*
+	 * @see org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal#createRequiredTypeCompletionProposal(org.eclipse.jdt.core.CompletionProposal, org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext)
+	 * @since 3.7
+	 */
+	@Override
+	protected LazyJavaCompletionProposal createRequiredTypeCompletionProposal(CompletionProposal completionProposal, JavaContentAssistInvocationContext invocationContext) {
+		LazyJavaCompletionProposal requiredProposal= super.createRequiredTypeCompletionProposal(completionProposal, invocationContext);
+		if (fProposal.getKind() == CompletionProposal.CONSTRUCTOR_INVOCATION && requiredProposal instanceof LazyGenericTypeProposal)
+			((LazyGenericTypeProposal) requiredProposal).canUseDiamond(fProposal.canUseDiamond(fInvocationContext.getCoreContext()));
+		return requiredProposal;
+	}
+
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyGenericTypeProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyGenericTypeProposal.java
index a7871b5..5258569 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyGenericTypeProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyGenericTypeProposal.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -193,6 +193,8 @@
 
 	private IRegion fSelectedRegion; // initialized by apply()
 	private TypeArgumentProposal[] fTypeArgumentProposals;
+	private boolean fCanUseDiamond;
+
 
 	public LazyGenericTypeProposal(CompletionProposal typeProposal, JavaContentAssistInvocationContext context) {
 		super(typeProposal, context);
@@ -203,15 +205,27 @@
 	 */
 	@Override
 	public void apply(IDocument document, char trigger, int offset) {
+		boolean onlyAppendArguments;
+		try {
+			onlyAppendArguments= fProposal.getCompletion().length == 0 && offset > 0 && document.getChar(offset - 1) == '<';
+		} catch (BadLocationException e) {
+			onlyAppendArguments= false;
+		}
 
-		if (shouldAppendArguments(document, offset, trigger)) {
+		if (onlyAppendArguments || shouldAppendArguments(document, offset, trigger)) {
 			try {
 				TypeArgumentProposal[] typeArgumentProposals= computeTypeArgumentProposals();
 				if (typeArgumentProposals.length > 0) {
 
 					int[] offsets= new int[typeArgumentProposals.length];
 					int[] lengths= new int[typeArgumentProposals.length];
-					StringBuffer buffer= createParameterList(typeArgumentProposals, offsets, lengths);
+					StringBuffer buffer;
+
+					if (canUseDiamond()) {
+						buffer= new StringBuffer(getReplacementString());
+						buffer.append("<>"); //$NON-NLS-1$
+					} else
+						buffer= createParameterList(typeArgumentProposals, offsets, lengths, onlyAppendArguments);
 
 					// set the generic type as replacement string
 					boolean insertClosingParenthesis= trigger == '(' && autocloseBrackets();
@@ -663,16 +677,18 @@
 		}
 	}
 
-	private StringBuffer createParameterList(TypeArgumentProposal[] typeArguments, int[] offsets, int[] lengths) {
+	private StringBuffer createParameterList(TypeArgumentProposal[] typeArguments, int[] offsets, int[] lengths, boolean onlyAppendArguments) {
 		StringBuffer buffer= new StringBuffer();
 		buffer.append(getReplacementString());
 
 		FormatterPrefs prefs= getFormatterPrefs();
 		final char LESS= '<';
 		final char GREATER= '>';
-		if (prefs.beforeOpeningBracket)
-			buffer.append(SPACE);
-		buffer.append(LESS);
+		if (!onlyAppendArguments) {
+			if (prefs.beforeOpeningBracket)
+				buffer.append(SPACE);
+			buffer.append(LESS);
+		}
 		if (prefs.afterOpeningBracket)
 			buffer.append(SPACE);
 		StringBuffer separator= new StringBuffer(3);
@@ -692,7 +708,9 @@
 		}
 		if (prefs.beforeClosingBracket)
 			buffer.append(SPACE);
-		buffer.append(GREATER);
+
+		if (!onlyAppendArguments)
+			buffer.append(GREATER);
 
 		return buffer;
 	}
@@ -811,4 +829,27 @@
 			return false;
 		}
 	}
+
+	/**
+	 * Sets whether this proposal can use the diamond.
+	 * 
+	 * @param canUseDiamond <code>true</code> if a diamond can be inserted
+	 * @see CompletionProposal#canUseDiamond(org.eclipse.jdt.core.CompletionContext)
+	 * @since 3.7
+	 */
+	void canUseDiamond(boolean canUseDiamond) {
+		fCanUseDiamond= canUseDiamond;
+	}
+
+	/**
+	 * Tells whether this proposal can use the diamond.
+	 * 
+	 * @return <code>true</code> if a diamond can be used
+	 * @see CompletionProposal#canUseDiamond(org.eclipse.jdt.core.CompletionContext)
+	 * @since 3.7
+	 */
+	protected boolean canUseDiamond() {
+		return fCanUseDiamond;
+	}
+
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyJavaTypeCompletionProposal.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyJavaTypeCompletionProposal.java
index b4deb8d..ba77460 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyJavaTypeCompletionProposal.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/LazyJavaTypeCompletionProposal.java
@@ -4,7 +4,7 @@
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
- *
+ * 
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
@@ -42,6 +42,7 @@
 
 import org.eclipse.jdt.internal.ui.JavaPlugin;
 
+
 /**
  * If passed compilation unit is not null, the replacement string will be seen as a qualified type name.
   */
@@ -103,7 +104,7 @@
 		if (fCompilationUnit != null && JavaModelUtil.isPackageInfo(fCompilationUnit))
 			return qualifiedTypeName;
 
- 		if (qualifiedTypeName.indexOf('.') == -1)
+		if (qualifiedTypeName.indexOf('.') == -1 && replacement.length() > 0)
  			// default package - no imports needed
  			return qualifiedTypeName;
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLabelComposer.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLabelComposer.java
index 541fe1a..824d4ca 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLabelComposer.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLabelComposer.java
@@ -373,23 +373,34 @@
 
 			// parameters
 			fBuffer.append('(');
+			String[] declaredParameterTypes= method.getParameterTypes();
 			if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES | JavaElementLabels.M_PARAMETER_NAMES)) {
 				String[] types= null;
 				int nParams= 0;
 				boolean renderVarargs= false;
+				boolean isPolymorphic= false;
 				if (getFlag(flags, JavaElementLabels.M_PARAMETER_TYPES)) {
 					if (resolvedSig != null) {
 						types= Signature.getParameterTypes(resolvedSig);
 					} else {
-						types= method.getParameterTypes();
+						types= declaredParameterTypes;
 					}
 					nParams= types.length;
 					renderVarargs= method.exists() && Flags.isVarargs(method.getFlags());
+					if (renderVarargs
+							&& resolvedSig != null
+							&& declaredParameterTypes.length == 1
+							&& JavaModelUtil.isPolymorphicSignature(method)) {
+						renderVarargs= false;
+						isPolymorphic= true;
+					}
 				}
 				String[] names= null;
 				if (getFlag(flags, JavaElementLabels.M_PARAMETER_NAMES) && method.exists()) {
 					names= method.getParameterNames();
-					if (types == null) {
+					if (isPolymorphic) {
+						// handled specially below
+					} else	if (types == null) {
 						nParams= names.length;
 					} else { // types != null
 						if (nParams != names.length) {
@@ -429,11 +440,15 @@
 						if (types != null) {
 							fBuffer.append(' ');
 						}
-						fBuffer.append(names[i]);
+						if (isPolymorphic) {
+							fBuffer.append(names[0] + i);
+						} else {
+							fBuffer.append(names[i]);
+						}
 					}
 				}
 			} else {
-				if (method.getParameterTypes().length > 0) {
+				if (declaredParameterTypes.length > 0) {
 					fBuffer.append(JavaElementLabels.ELLIPSIS_STRING);
 				}
 			}
@@ -744,6 +759,10 @@
 			case Signature.CAPTURE_TYPE_SIGNATURE:
 				appendTypeSignatureLabel(enclosingElement, typeSig.substring(1), flags);
 				break;
+			case Signature.INTERSECTION_TYPE_SIGNATURE:
+				String[] typeBounds= Signature.getIntersectionTypeBounds(typeSig);
+				appendTypeBoundsSignaturesLabel(enclosingElement, typeBounds, flags);
+				break;
 			default:
 				// unknown
 		}
@@ -773,6 +792,15 @@
 		}
 	}
 
+	private void appendTypeBoundsSignaturesLabel(IJavaElement enclosingElement, String[] typeArgsSig, long flags) {
+		for (int i = 0; i < typeArgsSig.length; i++) {
+			if (i > 0) {
+				fBuffer.append(" | "); //$NON-NLS-1$
+			}
+			appendTypeSignatureLabel(enclosingElement, typeArgsSig[i], flags);
+		}
+	}
+	
 	/**
 	 * Appends labels for type parameters from a signature.
 	 *
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/SharedASTProvider.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/SharedASTProvider.java
index 7e36eca..6ac4a42 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/SharedASTProvider.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/SharedASTProvider.java
@@ -31,7 +31,7 @@
  * <p>Clients can make the following assumptions about the AST:
  * <dl>
  *    <li>the AST has a {@link ITypeRoot} as source: {@link CompilationUnit#getTypeRoot()} is not null.</li>
- *    <li>the {@link AST#apiLevel() AST API level} is {@link AST#JLS3 API level 3} or higher</li>
+ *    <li>the {@link AST#apiLevel() AST API level} is {@link AST#JLS4 API level 4} or higher</li>
  *    <li>the AST has bindings resolved ({@link AST#hasResolvedBindings()})</li>
  *    <li>{@link AST#hasStatementsRecovery() statement} and {@link AST#hasBindingsRecovery() bindings}
  *           recovery are enabled
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java
index 002fa81..997ed24 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/IJavaEditorActionDefinitionIds.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -221,8 +221,16 @@
 	public static final String SURROUND_WITH_TRY_CATCH= "org.eclipse.jdt.ui.edit.text.java.surround.with.try.catch"; //$NON-NLS-1$
 
 	/**
-	 * Action definition ID of the source -> override methods action
-	 * (value <code>"org.eclipse.jdt.ui.edit.text.java.override.methods"</code>).
+	 * Action definition ID of the source -> surround with try/multi-catch action (value
+	 * <code>"org.eclipse.jdt.ui.edit.text.java.surround.with.try.multicatch"</code>).
+	 * 
+	 * @since 3.7.1
+	 */
+	public static final String SURROUND_WITH_TRY_MULTI_CATCH= "org.eclipse.jdt.ui.edit.text.java.surround.with.try.multicatch"; //$NON-NLS-1$
+
+	/**
+	 * Action definition ID of the source -> override methods action (value
+	 * <code>"org.eclipse.jdt.ui.edit.text.java.override.methods"</code>).
 	 */
 	public static final String OVERRIDE_METHODS= "org.eclipse.jdt.ui.edit.text.java.override.methods"; //$NON-NLS-1$
 
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/JdtActionConstants.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/JdtActionConstants.java
index 0b35a33..db0ca1c 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/JdtActionConstants.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/JdtActionConstants.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2009 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -210,6 +210,14 @@
 	public static final String SURROUND_WITH_TRY_CATCH= "org.eclipse.jdt.ui.actions.SurroundWithTryCatch"; //$NON-NLS-1$
 
 	/**
+	 * Source menu: name of standard Surround with try/multi-catch block global action (value
+	 * <code>"org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatch"</code>).
+	 * 
+	 * @since 3.7.1
+	 */
+	public static final String SURROUND_WITH_TRY_MULTI_CATCH= "org.eclipse.jdt.ui.actions.SurroundWithTryMultiCatch"; //$NON-NLS-1$
+
+	/**
 	 * Source menu: name of standard Override Methods global action
 	 * (value <code>"org.eclipse.jdt.ui.actions.OverrideMethods"</code>).
 	 */
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryCatchAction.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryCatchAction.java
index dc78525..f687c4e 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryCatchAction.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryCatchAction.java
@@ -58,7 +58,7 @@
  */
 public class SurroundWithTryCatchAction extends SelectionDispatchAction {
 
-	private CompilationUnitEditor fEditor;
+	CompilationUnitEditor fEditor;
 
 	/**
 	 * Note: This constructor is for internal use only. Clients should not call this constructor.
@@ -70,7 +70,7 @@
 		super(editor.getEditorSite());
 		setText(RefactoringMessages.SurroundWithTryCatchAction_label);
 		fEditor= editor;
-		setEnabled((fEditor != null && SelectionConverter.getInputAsCompilationUnit(fEditor) != null));
+		setEnabled(isApplicable());
 		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.SURROUND_WITH_TRY_CATCH_ACTION);
 	}
 
@@ -81,7 +81,7 @@
 		ICompilationUnit cu= SelectionConverter.getInputAsCompilationUnit(fEditor);
 		if (cu == null || !ElementValidator.checkValidateEdit(cu, getShell(), getDialogTitle()))
 			return;
-		SurroundWithTryCatchRefactoring refactoring= SurroundWithTryCatchRefactoring.create(cu, selection);
+		SurroundWithTryCatchRefactoring refactoring= createRefactoring(selection, cu);
 
 		if (refactoring == null)
 			return;
@@ -120,12 +120,20 @@
 		}
 	}
 
-	@Override
-	public void selectionChanged(ITextSelection selection) {
-		setEnabled(selection.getLength() > 0 && (fEditor != null && SelectionConverter.getInputAsCompilationUnit(fEditor) != null));
+	SurroundWithTryCatchRefactoring createRefactoring(ITextSelection selection, ICompilationUnit cu) {
+		return SurroundWithTryCatchRefactoring.create(cu, selection);
 	}
 
-	private static String getDialogTitle() {
+	@Override
+	public void selectionChanged(ITextSelection selection) {
+		setEnabled(selection.getLength() > 0 && isApplicable());
+	}
+
+	boolean isApplicable() {
+		return fEditor != null && SelectionConverter.getInputAsCompilationUnit(fEditor) != null;
+	}
+
+	String getDialogTitle() {
 		return RefactoringMessages.SurroundWithTryCatchAction_dialog_title;
 	}
 }
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryMultiCatchAction.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryMultiCatchAction.java
new file mode 100644
index 0000000..ce4dc77
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/actions/SurroundWithTryMultiCatchAction.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.ui.actions;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+
+import org.eclipse.jface.text.ITextSelection;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+
+import org.eclipse.jdt.internal.corext.refactoring.surround.SurroundWithTryCatchRefactoring;
+import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
+import org.eclipse.jdt.internal.corext.util.Messages;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.actions.SelectionConverter;
+import org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor;
+import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
+import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
+
+/**
+ * Action to surround a set of statements with a try/multi-catch block.
+ * 
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * 
+ * @since 3.7.1
+ * 
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class SurroundWithTryMultiCatchAction extends SurroundWithTryCatchAction {
+
+	/**
+	 * Note: This constructor is for internal use only. Clients should not call this constructor.
+	 * @param editor the compilation unit editor
+	 *
+	 * @noreference This constructor is not intended to be referenced by clients.
+	 */
+	public SurroundWithTryMultiCatchAction(CompilationUnitEditor editor) {
+		super(editor);
+		setText(RefactoringMessages.SurroundWithTryMultiCatchAction_label);
+	}
+
+	@Override
+	public void run(ITextSelection selection) {
+		ICompilationUnit compilationUnit= SelectionConverter.getInputAsCompilationUnit(fEditor);
+		IJavaProject javaProject= compilationUnit.getJavaProject();
+		if (!JavaModelUtil.is17OrHigher(javaProject)) {
+			String message= Messages.format(RefactoringMessages.SurroundWithTryMultiCatchAction_not17, BasicElementLabels.getJavaElementName(javaProject.getElementName()));
+			MessageDialog.openInformation(JavaPlugin.getActiveWorkbenchShell(), getDialogTitle(), message);
+			return;
+		}
+		super.run(selection);
+	}
+
+	@Override
+	SurroundWithTryCatchRefactoring createRefactoring(ITextSelection selection, ICompilationUnit cu) {
+		return SurroundWithTryCatchRefactoring.create(cu, selection, true);
+	}
+
+	@Override
+	String getDialogTitle() {
+		return RefactoringMessages.SurroundWithTryMultiCatchAction_dialog_title;
+	}
+
+	@Override
+	boolean isApplicable() {
+		if (!super.isApplicable())
+			return false;
+		
+		ICompilationUnit compilationUnit= SelectionConverter.getInputAsCompilationUnit(fEditor);
+		IJavaProject javaProject= compilationUnit.getJavaProject();
+		return JavaModelUtil.is17OrHigher(javaProject);
+	}
+
+}