gt: 		EditPart parent = focusPart.getParent();
context: /*******************************************************************************
   * Copyright (c) 2000, 2010 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.gef.ui.parts;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.eclipse.swt.events.KeyEvent;
  
  import org.eclipse.draw2d.IFigure;
  import org.eclipse.draw2d.geometry.Point;
  import org.eclipse.swt.SWT;
  
  import org.eclipse.gef.EditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.DrawerEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.GroupEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.IPaletteStackEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.PaletteStackEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.PinnablePaletteStackEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.TemplateEditPart;
  import org.eclipse.gef.internal.ui.palette.editparts.ToolEntryEditPart;
  import org.eclipse.gef.palette.PaletteEntry;
  import org.eclipse.gef.palette.PaletteStack;
  import org.eclipse.gef.ui.palette.PaletteViewer;
  
  /**
   * KeyHandler for the {@link org.eclipse.gef.ui.palette.PaletteViewer Palette}.
   * Handles selection traversal of Palette entries and collapse/expand of
   * categories.
   */
  public class PaletteViewerKeyHandler extends GraphicalViewerKeyHandler {
  
  	/**
  	 * Constructs a key handler for the specified palette viewer.
  	 * 
  	 * @param viewer
  	 *            the palette viewer
  	 */
  	public PaletteViewerKeyHandler(PaletteViewer viewer) {
  		super(viewer);
  	}
  
  	private boolean acceptCollapseDrawer(KeyEvent event) {
  		boolean result = isViewerMirrored() ? event.keyCode == SWT.ARROW_RIGHT
  				: event.keyCode == SWT.ARROW_LEFT;
  		return result && isExpandedDrawer(getFocusEditPart());
  	}
  
  	private boolean acceptExpandDrawer(KeyEvent event) {
  		boolean result = isViewerMirrored() ? event.keyCode == SWT.ARROW_LEFT
  				: event.keyCode == SWT.ARROW_RIGHT;
  		return result && isCollapsedDrawer(getFocusEditPart());
  	}
  
  	private boolean acceptIntoExpandedDrawer(KeyEvent event) {
  		boolean result = event.keyCode == SWT.ARROW_DOWN;
  		result = result
  				|| (isViewerMirrored() ? event.keyCode == SWT.ARROW_LEFT
  						: event.keyCode == SWT.ARROW_RIGHT);
  		return result && isExpandedDrawer(getFocusEditPart());
  	}
  
  	private boolean acceptExpandStack(KeyEvent event) {
  		return event.keyCode == SWT.ARROW_DOWN
  				&& (event.stateMask & SWT.ALT) > 0
  				&& isCollapsedStack(getFocusEditPart());
  	}
  
  	private boolean acceptCollapseStack(KeyEvent event) {
  		return event.keyCode == SWT.ARROW_UP && (event.stateMask & SWT.ALT) > 0
  				&& isExpandedStack(getFocusEditPart());
  	}
  
  	private boolean acceptSetFocusOnDrawer(KeyEvent event) {
  		boolean result = isViewerMirrored() ? event.keyCode == SWT.ARROW_RIGHT
  				: event.keyCode == SWT.ARROW_LEFT;
  		return (result || event.keyCode == SWT.ARROW_UP)
  				&& (getFocusEditPart().getParent() instanceof DrawerEditPart || (getFocusEditPart()
  						.getParent() instanceof IPaletteStackEditPart && getFocusEditPart()
  						.getParent().getParent() instanceof DrawerEditPart));
  	}
  
  	private boolean acceptNextContainer(KeyEvent event) {
  		return event.keyCode == SWT.ARROW_DOWN;
  	}
  
  	private void buildNavigationList(EditPart palettePart, EditPart exclusion,
  			ArrayList navList, EditPart stackPart) {
  		if (palettePart != exclusion) {
  			if (isCollapsedDrawer(palettePart)) {
  				navList.add(palettePart);
  				return;
  			} else if (stackPart instanceof PaletteStackEditPart
  					&& stackPart.getChildren().contains(palettePart)) {
  				// we only want to add the top level item to the navlist
  				if (((PaletteStack) stackPart.getModel()).getActiveEntry()
  						.equals(palettePart.getModel()))
  					navList.add(palettePart);
  			} else if (stackPart instanceof PinnablePaletteStackEditPart
  					&& stackPart.getChildren().contains(palettePart)) {
  				// we only want to add the top level item to the navlist unless
  				// the palette stack is expanded
  				if (((PinnablePaletteStackEditPart) stackPart).isExpanded()
  						|| ((PaletteStack) stackPart.getModel())
  								.getActiveEntry()
  								.equals(palettePart.getModel())) {
  					navList.add(palettePart);
  				}
  			} else if ((palettePart instanceof ToolEntryEditPart
  					|| palettePart instanceof DrawerEditPart || palettePart instanceof TemplateEditPart)) {
  				navList.add(palettePart);
  			}
  		}
  
  		List children = palettePart.getChildren();
  		for (int k = 0; k < children.size(); k++) {
  			EditPart ep = (EditPart) children.get(k);
  			if (ep instanceof IPaletteStackEditPart)
  				stackPart = ep;
  			buildNavigationList(ep, exclusion, navList, stackPart);
  		}
  	}
  
  	private void collapseDrawer() {
  		DrawerEditPart drawer = (DrawerEditPart) getFocusEditPart();
  		drawer.setExpanded(false);
  	}
  
  	private void expandDrawer() {
  		DrawerEditPart drawer = (DrawerEditPart) getFocusEditPart();
  		drawer.setExpanded(true);
  	}
  
  	/**
  	 * Figures' navigation points are used to determine their direction compared
  	 * to one another, and the distance between them.
  	 * 
  	 * @param figure
  	 *            the figure whose navigation point is to be returned
  	 * @return the top-left of the given figure
  	 */
  	protected Point getNavigationPoint(IFigure figure) {
  		return figure.getBounds().getTopLeft();
  	}
  
  	/**
  	 * @return a list of {@link org.eclipse.gef.EditPart EditParts} that can be
  	 *         traversed to from the current
  	 *         {@link GraphicalViewerKeyHandler#getFocusEditPart() focus part}
  	 */
  	protected List getNavigationSiblings() {
  		ArrayList siblingsList = new ArrayList();
  		EditPart focusPart = getFocusEditPart();
  		EditPart parent = focusPart.getParent();
  		if (parent == null) {
  			siblingsList.add(focusPart);
  			return siblingsList;
  		}
  		if (parent instanceof GroupEditPart
  				|| parent instanceof IPaletteStackEditPart) {
  			EditPart grandParent = parent.getParent();
  			buildNavigationList(grandParent, grandParent, siblingsList,
  					grandParent);
  		} else
  			buildNavigationList(parent, parent, siblingsList, parent);
  		return siblingsList;
  	}
  
  	/**
  	 * Returns <code>true</code> if the passed Editpart is a collapsed
  	 * {@link org.eclipse.gef.ui.palette.DrawerEditPart Drawer}, false
  	 * otherwise.
  	 */
  	boolean isCollapsedDrawer(EditPart part) {
  		return part instanceof DrawerEditPart
  				&& !((DrawerEditPart) part).isExpanded();
  	}
  
  	/**
  	 * Returns <code>true</code> if the passed Editpart is an expanded
  	 * {@link org.eclipse.gef.ui.palette.DrawerEditPart Drawer}, false
  	 * otherwise.
  	 */
  	boolean isExpandedDrawer(EditPart part) {
  		return part instanceof DrawerEditPart
  				&& ((DrawerEditPart) part).isExpanded();
  	}
  
  	/**
  	 * Returns <code>true</code> if the passed focusPart is a collapsed pinnable
  	 * palette stack, false otherwise.
  	 */
  	boolean isCollapsedStack(EditPart focusPart) {
  		EditPart parent = focusPart.getParent();
  		return parent instanceof PaletteStackEditPart
  				|| (parent instanceof PinnablePaletteStackEditPart && !((PinnablePaletteStackEditPart) parent)
  						.isExpanded());
  	}
  
  	/**
  	 * Returns <code>true</code> if the passed focusPart is an expanded pinnable
  	 * palette stack, false otherwise.
  	 */
  	boolean isExpandedStack(EditPart focusPart) {
  