Bug 484686 - ArrayIndexOutOfBoundsException in ASTInstruction

Change-Id: I199b76e86bbf2903318448971119418c72725d82
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
index a5b001c..eac28cc 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -395,6 +395,7 @@
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug329294WithGenerics"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug403028"));
+				cfgs.add(createLaunchConfiguration(jp, "a.b.c.bug484686"));
 				cfgs.add(createLaunchConfiguration(jp, "a.b.c.GenericMethodEntryTest"));
 				loaded15 = true;
 				waitForBuild();
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
index f71f772..0e3f8a8 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/variables/DetailFormatterTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) Mar 12, 2015 IBM Corporation and others.
+ * Copyright (c) Mar 12, 2016 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
@@ -336,4 +336,40 @@
 			removeAllBreakpoints();
 		}
 	}
+
+	/**
+	 * Tests a detail formatter made from an collection with no type arguments
+	 * 
+	 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=484686
+	 * @throws Exception
+	 */
+	public void testHoverWithNoTypeArguments() throws Exception {
+		IJavaThread thread = null;
+		DetailFormatter formatter = null;
+		JavaDetailFormattersManager jdfm = JavaDetailFormattersManager.getDefault();
+		try {
+			String typename = "a.b.c.bug484686";
+			createLineBreakpoint(8, typename);
+			thread = launchToBreakpoint(typename);
+			assertNotNull("The program did not suspend", thread);
+			String snippet = "StringBuilder sb = new StringBuilder();\n" + "for (Object obj : this) { \n" + "sb.append(obj).append(\"\\n\"); }\n"
+					+ "return sb.toString();";
+			formatter = new DetailFormatter("java.util.Collection", snippet, true);
+			jdfm.setAssociatedDetailFormatter(formatter);
+			IJavaVariable var = thread.findVariable("coll");
+			assertNotNull("the variable 'coll' must exist in the frame", var);
+			jdfm.computeValueDetail((IJavaValue) var.getValue(), thread, fListener);
+			long timeout = System.currentTimeMillis() + 5000;
+			while (fListener.value == null && System.currentTimeMillis() < timeout) {
+				Thread.sleep(100);
+			}
+			assertNotNull("The IValue of the detailComputed callback cannot be null", fListener.value);
+			assertNotNull("The computed value of the detail should not be null", fListener.result);
+		}
+		finally {
+			jdfm.removeAssociatedDetailFormatter(formatter);
+			terminateAndRemove(thread);
+			removeAllBreakpoints();
+		}
+	}
 }
diff --git a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug484686.java b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug484686.java
new file mode 100644
index 0000000..5cff91a
--- /dev/null
+++ b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/bug484686.java
@@ -0,0 +1,10 @@
+package a.b.c;
+import java.util.Collection;
+import java.util.HashMap;
+public class bug484686 {
+	public static void main(String[] args) {
+		HashMap t = new HashMap<String, String>();
+	    Collection coll = t.entrySet();
+	    coll.getClass(); // breakpoint here
+	}
+}
diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
index 83791aa..d494ab6 100644
--- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
+++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTInstructionCompiler.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 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
@@ -2239,8 +2239,11 @@
 			push(new PushLocalVariable(iteratorIdentifier));
 			storeInstruction();
 			storeInstruction();
-			if (checkAutoBoxing(typeBinding.getTypeArguments()[0], paramBinding)) {
-				storeInstruction();
+			ITypeBinding[] typeArguments = typeBinding.getTypeArguments();
+			if (typeArguments != null && typeArguments.length > 0 ){
+				if (checkAutoBoxing(typeArguments[0], paramBinding)) {
+					storeInstruction();
+				}
 			}
 			storeInstruction();
 			addPopInstruction();