Bug 65063 AIOOBE when expanding selection to previous element
3.0RC1 - in the CU: package org.test; public class Test { } - set the cursor within "package" - invoke twice Edit->Expand Selection To->Previous Element -> results in the following exception: java.lang.ArrayIndexOutOfBoundsException: -2 at org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSele ctPreviousAction.getPreviousNode(StructureSelectPreviousAction.java:69) at org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSele ctPreviousAction.internalGetNewSelectionRange(StructureSelectPreviousAction.java :53) at org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSele ctionAction.getNewSelectionRange(StructureSelectionAction.java:108) at org.eclipse.jdt.internal.ui.javaeditor.selectionactions.StructureSele ctionAction.run(StructureSelectionAction.java:85) at org.eclipse.jface.action.Action.runWithEvent(Action.java:881) at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:141) at org.eclipse.ui.internal.commands.Command.execute(Command.java:132) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(Workben chKeyboard.java:469) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboar d.java:887) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(Workbe nchKeyboard.java:928) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindi ngs(WorkbenchKeyboard.java:546) at org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$2(WorkbenchKeyb oard.java:494) at org.eclipse.ui.internal.keys.WorkbenchKeyboard$1.handleEvent(Workbenc hKeyboard.java:259) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:82) at org.eclipse.swt.widgets.Display.filterEvent(Display.java:712) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:795) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:820) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:805) at org.eclipse.swt.widgets.Control.sendKeyEvent(Control.java:1724) at org.eclipse.swt.widgets.Control.sendKeyEvent(Control.java:1720) at org.eclipse.swt.widgets.Control.WM_SYSKEYDOWN(Control.java:4382) at org.eclipse.swt.widgets.Control.windowProc(Control.java:3022) at org.eclipse.swt.widgets.Display.windowProc(Display.java:3282) at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method) at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:1459) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2380) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1363) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1334) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.jav a:253) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:141) at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:96 ) at org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformAct ivator.java:334) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja va:273) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja va:128) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at org.eclipse.core.launcher.Main.basicRun(Main.java:185) at org.eclipse.core.launcher.Main.run(Main.java:638) at org.eclipse.core.launcher.Main.main(Main.java:622) -2
org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/selectionactions/StructureSelectPreviousAction.java
*/	
	ISourceRange internalGetNewSelectionRange(ISourceRange oldSourceRange, ISourceReference sr, SelectionAnalyzer selAnalyzer) throws JavaModelException{
		ASTNode first= selAnalyzer.getFirstSelectedNode();
		if (first == null) 
			return getLastCoveringNodeRange(oldSourceRange, sr, selAnalyzer); 
		
		ASTNode parent= first.getParent();
		if (parent == null)	
			return getLastCoveringNodeRange(oldSourceRange, sr, selAnalyzer); 
		
		ASTNode previousNode= getPreviousNode(parent, selAnalyzer.getSelectedNodes()[0]);
		if (previousNode == parent)
			return getSelectedNodeSourceRange(sr, parent);	
			
		int offset= previousNode.getStartPosition();
		int end= oldSourceRange.getOffset() + oldSourceRange.getLength() - 1;
		return StructureSelectionAction.createSourceRange(offset, end);
	}
	
	private static ASTNode getPreviousNode(ASTNode parent, ASTNode node){
		ASTNode[] siblingNodes= StructureSelectionAction.getChildNodes(parent);
		if (siblingNodes == null || siblingNodes.length == 0)
			return parent;
		if (node == siblingNodes[0])
			return parent;
		else
			return siblingNodes[StructureSelectionAction.findIndex(siblingNodes, node) - 1];
	}
}