Bug 372840: [quick fix] Add a quick fix to add the missing default in a switch statement
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java
index 0195faa..0b89f12 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/AssistQuickFixTest.java
@@ -5895,9 +5895,27 @@
 		List proposals= collectAssists(context, false);
 
 		assertCorrectLabels(proposals);
-		assertNumberOfProposals(proposals, 2);
+		assertNumberOfProposals(proposals, 3);
 
-		String[] expected= new String[1];
+		String[] expected= new String[2];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    enum MyEnum {\n");
+		buf.append("        X1, X2, X3\n");
+		buf.append("    }\n");
+		buf.append("    \n");
+		buf.append("    public void foo(MyEnum x) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            default :\n");
+		buf.append("                break;\n");
+		buf.append("        \n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
 		buf= new StringBuffer();
 		buf.append("package p;\n");
 		buf.append("\n");
@@ -5920,7 +5938,7 @@
 		buf.append("        }\n");
 		buf.append("    }\n");
 		buf.append("}\n");
-		expected[0]= buf.toString();
+		expected[1]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
 	}
@@ -5949,9 +5967,29 @@
 		List proposals= collectAssists(context, false);
 
 		assertCorrectLabels(proposals);
-		assertNumberOfProposals(proposals, 2);
+		assertNumberOfProposals(proposals, 3);
 
-		String[] expected= new String[1];
+		String[] expected= new String[2];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    enum MyEnum {\n");
+		buf.append("        X1, X2, X3\n");
+		buf.append("    }\n");
+		buf.append("    \n");
+		buf.append("    public void foo(MyEnum x) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            case X1 :\n");
+		buf.append("                break;\n");
+		buf.append("            default :\n");
+		buf.append("                break;\n");
+		buf.append("        \n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
 		buf= new StringBuffer();
 		buf.append("package p;\n");
 		buf.append("\n");
@@ -5974,7 +6012,7 @@
 		buf.append("        }\n");
 		buf.append("    }\n");
 		buf.append("}\n");
-		expected[0]= buf.toString();
+		expected[1]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
 	}
@@ -6003,9 +6041,29 @@
 		List proposals= collectAssists(context, false);
 
 		assertCorrectLabels(proposals);
-		assertNumberOfProposals(proposals, 1);
+		assertNumberOfProposals(proposals, 2);
 
-		String[] expected= new String[1];
+		String[] expected= new String[2];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    enum MyEnum {\n");
+		buf.append("        X1, X2, X3\n");
+		buf.append("    }\n");
+		buf.append("    \n");
+		buf.append("    public void foo(MyEnum x) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            case X1 :\n");
+		buf.append("                break;\n");
+		buf.append("            default :\n");
+		buf.append("                break;\n");
+		buf.append("        \n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
 		buf= new StringBuffer();
 		buf.append("package p;\n");
 		buf.append("\n");
@@ -6028,7 +6086,7 @@
 		buf.append("        }\n");
 		buf.append("    }\n");
 		buf.append("}\n");
-		expected[0]= buf.toString();
+		expected[1]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
 	}
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 afe97e9..67fb02e 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
@@ -8771,9 +8771,27 @@
 		ArrayList proposals= collectCorrections(cu, astRoot, 4, 1);
 
 		assertCorrectLabels(proposals);
-		assertNumberOfProposals(proposals, 1);
+		assertNumberOfProposals(proposals, 2);
 
-		String[] expected= new String[1];
+		String[] expected= new String[2];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    enum MyEnum {\n");
+		buf.append("        X1, X2, X3\n");
+		buf.append("    }\n");
+		buf.append("    \n");
+		buf.append("    public void foo(MyEnum x) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            default :\n");
+		buf.append("                break;\n");
+		buf.append("        \n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
 		buf= new StringBuffer();
 		buf.append("package p;\n");
 		buf.append("\n");
@@ -8796,7 +8814,7 @@
 		buf.append("        }\n");
 		buf.append("    }\n");
 		buf.append("}\n");
-		expected[0]= buf.toString();
+		expected[1]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
 	}
@@ -8829,9 +8847,28 @@
 		ArrayList proposals= collectCorrections(cu, astRoot, 3, 1);
 
 		assertCorrectLabels(proposals);
-		assertNumberOfProposals(proposals, 1);
+		assertNumberOfProposals(proposals, 2);
 
-		String[] expected= new String[1];
+		String[] expected= new String[2];
+		buf= new StringBuffer();
+		buf.append("package p;\n");
+		buf.append("\n");
+		buf.append("public class E {\n");
+		buf.append("    enum MyEnum {\n");
+		buf.append("        X1, X2, X3\n");
+		buf.append("    }\n");
+		buf.append("    \n");
+		buf.append("    public void foo(MyEnum x) {\n");
+		buf.append("        switch (x) {\n");
+		buf.append("            case X1 :\n");
+		buf.append("                break;\n");
+		buf.append("            default :\n");
+		buf.append("                break;\n");
+		buf.append("        }\n");
+		buf.append("    }\n");
+		buf.append("}\n");
+		expected[0]= buf.toString();
+
 		buf= new StringBuffer();
 		buf.append("package p;\n");
 		buf.append("\n");
@@ -8853,7 +8890,7 @@
 		buf.append("        }\n");
 		buf.append("    }\n");
 		buf.append("}\n");
-		expected[0]= buf.toString();
+		expected[1]= buf.toString();
 
 		assertExpectedExistInProposals(proposals, expected);
 	}
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 bbbc5c9..96490a6 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
@@ -84,6 +84,7 @@
 	public static String ReorgCorrectionsSubProcessor_addcp_library_description;
 	public static String LocalCorrectionsSubProcessor_surroundwith_trycatch_description;
 	public static String LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description;
+	public static String LocalCorrectionsSubProcessor_add_default_case_description;
 	public static String LocalCorrectionsSubProcessor_add_missing_cases_description;
 	public static String LocalCorrectionsSubProcessor_addthrows_description;
 	public static String ClasspathFixProcessorDescriptor_error_processing_processors;
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 6a34aa6c..f7642fa 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
@@ -71,6 +71,7 @@
 
 LocalCorrectionsSubProcessor_surroundwith_trycatch_description=Surround with try/catch
 LocalCorrectionsSubProcessor_surroundwith_trymulticatch_description=Surround with try/multi-catch
+LocalCorrectionsSubProcessor_add_default_case_description=Add 'default' case
 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
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 036e258..98f9cc9 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
@@ -1607,17 +1607,16 @@
 				return;
 			}
 
-			String[] missingEnumCases= evaluateMissingEnumConstantCases(binding, statement.statements());
-			boolean missingDefault= evaluateMissingDefaultCase(statement.statements());
-			if (missingEnumCases.length == 0 && !missingDefault)
+			ArrayList<String> missingEnumCases= new ArrayList<String>();
+			boolean hasDefault= evaluateMissingSwitchCases(binding, statement.statements(), missingEnumCases);
+			if (missingEnumCases.size() == 0 && hasDefault)
 				return;
 
-			proposals.add(createMissingEnumConstantCaseProposals(context, statement, missingEnumCases));
+			createMissingCaseProposals(context, statement, missingEnumCases, proposals);
 		}
 	}
 
-	public static String[] evaluateMissingEnumConstantCases(ITypeBinding enumBindings, List<Statement> switchStatements) {
-		ArrayList<String> enumConstNames= new ArrayList<String>();
+	public static boolean evaluateMissingSwitchCases(ITypeBinding enumBindings, List<Statement> switchStatements, ArrayList<String> enumConstNames) {
 		IVariableBinding[] fields= enumBindings.getDeclaredFields();
 		for (int i= 0; i < fields.length; i++) {
 			if (fields[i].isEnumConstant()) {
@@ -1625,6 +1624,7 @@
 			}
 		}
 
+		boolean hasDefault=false;
 		List<Statement> statements= switchStatements;
 		for (int i= 0; i < statements.size(); i++) {
 			Statement curr= statements.get(i);
@@ -1632,25 +1632,15 @@
 				Expression expression= ((SwitchCase) curr).getExpression();
 				if (expression instanceof SimpleName) {
 					enumConstNames.remove(((SimpleName) expression).getFullyQualifiedName());
+				} else if(expression== null){
+					hasDefault=true;
 				}
 			}
 		}
-		return enumConstNames.toArray(new String[enumConstNames.size()]);
+		return hasDefault;
 	}
 
-	public static boolean evaluateMissingDefaultCase(List<Statement> switchStatements) {
-		List<Statement> statements= switchStatements;
-		for (int i= 0; i < statements.size(); i++) {
-			Statement curr= statements.get(i);
-			if (curr instanceof SwitchCase) {
-				if (((SwitchCase) curr).getExpression() == null)
-					return false;
-			}
-		}
-		return true;
-	}
-
-	public static ASTRewriteCorrectionProposal createMissingEnumConstantCaseProposals(IInvocationContext context, SwitchStatement switchStatement, String[] enumConstNames) {
+	public static void createMissingCaseProposals(IInvocationContext context, SwitchStatement switchStatement, ArrayList<String> enumConstNames, Collection<ICommandAccess> proposals) {
 		List<Statement> statements= switchStatement.statements();
 		int defaultIndex= statements.size();
 		for (int i= 0; i < statements.size(); i++) {
@@ -1660,32 +1650,48 @@
 				break;
 			}
 		}
-		AST ast= switchStatement.getAST();
-		ASTRewrite astRewrite= ASTRewrite.create(ast);
-
 		boolean hasDefault= defaultIndex < statements.size();
+		int index= defaultIndex;
 
-		ListRewrite listRewrite= astRewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
-		for (int i= 0; i < enumConstNames.length; i++) {
-			SwitchCase newSwitchCase= ast.newSwitchCase();
-			newSwitchCase.setExpression(ast.newName(enumConstNames[i]));
-			listRewrite.insertAt(newSwitchCase, defaultIndex, null);
-			defaultIndex++;
-			if (!hasDefault) {
-				listRewrite.insertAt(ast.newBreakStatement(), defaultIndex, null);
+		AST ast= switchStatement.getAST();
+		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
+
+		if (enumConstNames.size() > 0) {
+			ASTRewrite astRewrite= ASTRewrite.create(ast);
+			ListRewrite listRewrite= astRewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
+			for (int i= 0; i < enumConstNames.size(); i++) {
+				SwitchCase newSwitchCase= ast.newSwitchCase();
+				newSwitchCase.setExpression(ast.newName(enumConstNames.get(i)));
+				listRewrite.insertAt(newSwitchCase, defaultIndex, null);
 				defaultIndex++;
+				if (!hasDefault) {
+					listRewrite.insertAt(ast.newBreakStatement(), defaultIndex, null);
+					defaultIndex++;
+				}
 			}
+			if (!hasDefault) {
+				SwitchCase newSwitchCase= ast.newSwitchCase();
+				newSwitchCase.setExpression(null);
+				listRewrite.insertAt(newSwitchCase, defaultIndex, null);
+				defaultIndex++;
+				listRewrite.insertAt(ast.newBreakStatement(), defaultIndex, null);
+			}
+			String label= CorrectionMessages.LocalCorrectionsSubProcessor_add_missing_cases_description;
+			proposals.add(new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), astRewrite, 10, image));
 		}
 		if (!hasDefault) {
+			ASTRewrite astRewrite= ASTRewrite.create(ast);
+			ListRewrite listRewrite= astRewrite.getListRewrite(switchStatement, SwitchStatement.STATEMENTS_PROPERTY);
+
 			SwitchCase newSwitchCase= ast.newSwitchCase();
 			newSwitchCase.setExpression(null);
-			listRewrite.insertAt(newSwitchCase, defaultIndex, null);
-			defaultIndex++;
-			listRewrite.insertAt(ast.newBreakStatement(), defaultIndex, null);
+			listRewrite.insertAt(newSwitchCase, index, null);
+			index++;
+			listRewrite.insertAt(ast.newBreakStatement(), index, null);
+
+			String label= CorrectionMessages.LocalCorrectionsSubProcessor_add_default_case_description;
+			proposals.add(new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), astRewrite, 10, image));
 		}
-		String label= CorrectionMessages.LocalCorrectionsSubProcessor_add_missing_cases_description;
-		Image image= JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
-		return new ASTRewriteCorrectionProposal(label, context.getCompilationUnit(), astRewrite, 10, image);
 	}
 
 	public static void addMissingHashCodeProposals(IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
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 4141952..64ac735 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
@@ -2633,15 +2633,15 @@
 		if (expressionBinding == null || !expressionBinding.isEnum())
 			return false;
 
-		String[] missingEnumCases= LocalCorrectionsSubProcessor.evaluateMissingEnumConstantCases(expressionBinding, switchStatement.statements());
-		boolean missingDefault= LocalCorrectionsSubProcessor.evaluateMissingDefaultCase(switchStatement.statements());
-		if (missingEnumCases.length == 0 && !missingDefault)
+		ArrayList<String> missingEnumCases= new ArrayList<String>();
+		boolean hasDefault= LocalCorrectionsSubProcessor.evaluateMissingSwitchCases(expressionBinding, switchStatement.statements(), missingEnumCases);
+		if (missingEnumCases.size() == 0 && hasDefault)
 			return false;
 
 		if (proposals == null)
 			return true;
 
-		proposals.add(LocalCorrectionsSubProcessor.createMissingEnumConstantCaseProposals(context, switchStatement, missingEnumCases));
+		LocalCorrectionsSubProcessor.createMissingCaseProposals(context, switchStatement, missingEnumCases, proposals);
 		return true;
 	}