gt: 		while (current != null) {
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.Collection;
  import java.util.List;
  
  import org.eclipse.swt.dnd.DragSource;
  import org.eclipse.swt.dnd.DragSourceAdapter;
  import org.eclipse.swt.dnd.DragSourceEvent;
  import org.eclipse.swt.dnd.DropTargetAdapter;
  import org.eclipse.swt.dnd.DropTargetEvent;
  import org.eclipse.swt.events.DisposeEvent;
  import org.eclipse.swt.events.FocusEvent;
  import org.eclipse.swt.events.FocusListener;
  import org.eclipse.swt.graphics.Cursor;
  import org.eclipse.swt.widgets.Canvas;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.swt.widgets.Event;
  
  import org.eclipse.core.runtime.Assert;
  import org.eclipse.jface.action.IMenuListener;
  import org.eclipse.jface.action.IMenuManager;
  import org.eclipse.jface.action.MenuManager;
  
  import org.eclipse.draw2d.ExclusionSearch;
  import org.eclipse.draw2d.IFigure;
  import org.eclipse.draw2d.LightweightSystem;
  import org.eclipse.draw2d.geometry.Point;
  import org.eclipse.swt.SWT;
  
  import org.eclipse.gef.AccessibleEditPart;
  import org.eclipse.gef.EditDomain;
  import org.eclipse.gef.EditPart;
  import org.eclipse.gef.EditPartViewer;
  import org.eclipse.gef.ExposeHelper;
  import org.eclipse.gef.GraphicalEditPart;
  import org.eclipse.gef.GraphicalViewer;
  import org.eclipse.gef.Handle;
  import org.eclipse.gef.LayerConstants;
  import org.eclipse.gef.MouseWheelHandler;
  import org.eclipse.gef.MouseWheelHelper;
  import org.eclipse.gef.RootEditPart;
  import org.eclipse.gef.editparts.LayerManager;
  import org.eclipse.gef.editparts.ScalableRootEditPart;
  
  /**
   * An EditPartViewer implementation based on {@link org.eclipse.draw2d.IFigure
   * Figures}.
   * 
   * @author hudsonr
   */
  public class GraphicalViewerImpl extends AbstractEditPartViewer implements
  		GraphicalViewer {
  
  	private final LightweightSystem lws = createLightweightSystem();
  	IFigure rootFigure;
  	private DomainEventDispatcher eventDispatcher;
  	private FocusListener lFocus;
  
  	/**
  	 * Constructs a GraphicalViewerImpl with the default root editpart.
  	 */
  	public GraphicalViewerImpl() {
  		createDefaultRoot();
  		setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.NONE),
  				MouseWheelDelegateHandler.SINGLETON);
  	}
  
  	/**
  	 * @see org.eclipse.gef.EditPartViewer#createControl(org.eclipse.swt.widgets.Composite)
  	 */
  	public Control createControl(Composite composite) {
  		setControl(new Canvas(composite, SWT.NO_BACKGROUND));
  		return getControl();
  	}
  
  	/**
  	 * Creates the default root editpart. Called during construction.
  	 */
  	protected void createDefaultRoot() {
  		setRootEditPart(new ScalableRootEditPart());
  	}
  
  	/**
  	 * Creates the lightweight system used to host figures. Subclasses should
  	 * not need to override this method.
  	 * 
  	 * @return the lightweight system
  	 */
  	protected LightweightSystem createLightweightSystem() {
  		return new LightweightSystem();
  	}
  
  	/**
  	 * @see AbstractEditPartViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
  	 */
  	protected void handleDispose(DisposeEvent e) {
  		super.handleDispose(e);
  		getLightweightSystem().getUpdateManager().dispose();
  	}
  
  	/**
  	 * This method is invoked when this viewer's control gains focus. It gives
  	 * focus to the {@link AbstractEditPartViewer#focusPart focusPart}, if there
  	 * is one.
  	 * 
  	 * @param fe
  	 *            the focusEvent received by this viewer's control
  	 */
  	protected void handleFocusGained(FocusEvent fe) {
  		if (focusPart != null)
  			focusPart.setFocus(true);
  	}
  
  	/**
  	 * This method is invoked when this viewer's control loses focus. It removes
  	 * focus from the {@link AbstractEditPartViewer#focusPart focusPart}, if
  	 * there is one.
  	 * 
  	 * @param fe
  	 *            the focusEvent received by this viewer's control
  	 */
  	protected void handleFocusLost(FocusEvent fe) {
  		if (focusPart != null)
  			focusPart.setFocus(false);
  	}
  
  	/**
  	 * @see GraphicalViewer#findHandleAt(org.eclipse.draw2d.geometry.Point)
  	 */
  	public Handle findHandleAt(Point p) {
  		LayerManager layermanager = (LayerManager) getEditPartRegistry().get(
  				LayerManager.ID);
  		if (layermanager == null)
  			return null;
  		List list = new ArrayList(3);
  		list.add(layermanager.getLayer(LayerConstants.PRIMARY_LAYER));
  		list.add(layermanager.getLayer(LayerConstants.CONNECTION_LAYER));
  		list.add(layermanager.getLayer(LayerConstants.FEEDBACK_LAYER));
  		IFigure handle = getLightweightSystem().getRootFigure()
  				.findFigureAtExcluding(p.x, p.y, list);
  		if (handle instanceof Handle)
  			return (Handle) handle;
  		return null;
  	}
  
  	/**
  	 * @see EditPartViewer#findObjectAtExcluding(Point, Collection,
  	 *      EditPartViewer.Conditional)
  	 */
  	public EditPart findObjectAtExcluding(Point pt, Collection exclude,
  			final Conditional condition) {
  		class ConditionalTreeSearch extends ExclusionSearch {
  			ConditionalTreeSearch(Collection coll) {
  				super(coll);
  			}
  
  			public boolean accept(IFigure figure) {
  				EditPart editpart = null;
  				while (editpart == null && figure != null) {
  					editpart = (EditPart) getVisualPartMap().get(figure);
  					figure = figure.getParent();
  				}
  				return editpart != null
  						&& (condition == null || condition.evaluate(editpart));
  			}
  		}
  		IFigure figure = getLightweightSystem().getRootFigure().findFigureAt(
  				pt.x, pt.y, new ConditionalTreeSearch(exclude));
  		EditPart part = null;
  		while (part == null && figure != null) {
  			part = (EditPart) getVisualPartMap().get(figure);
  			figure = figure.getParent();
  		}
  		if (part == null)
  			return getContents();
  		return part;
  	}
  
  	/**
  	 * Flushes and pending layouts and paints in the lightweight system.
  	 * 
  	 * @see org.eclipse.gef.EditPartViewer#flush()
  	 */
  	public void flush() {
  		getLightweightSystem().getUpdateManager().performUpdate();
  	}
  
  	/**
  	 * Returns the event dispatcher
  	 * 
  	 * @deprecated This method should not be called by subclasses
  	 * @return the event dispatcher
  	 */
  	protected DomainEventDispatcher getEventDispatcher() {
  		return eventDispatcher;
  	}
  
  	/**
  	 * Convenience method for finding the layer manager.
  	 * 
  	 * @return the LayerManager
  	 */
  	protected LayerManager getLayerManager() {
  		return (LayerManager) getEditPartRegistry().get(LayerManager.ID);
  	}
  
  	/**
  	 * Returns the lightweight system.
  	 * 
  	 * @return the system
  	 */
  	protected LightweightSystem getLightweightSystem() {
  		return lws;
  	}
  
  	/**
  	 * Returns the root figure
  	 * 
  	 * @deprecated There is no reason to call this method $TODO delete this
  	 *             method
  	 * @return the root figure
  	 */
  	protected IFigure getRootFigure() {
  		return rootFigure;
  	}
  
  	/**
  	 * Extended to flush paints during drop callbacks.
  	 * 
  	 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#hookDropTarget()
  	 */
  	protected void hookDropTarget() {
  		// Allow the real drop targets to make their changes first.
  		super.hookDropTarget();
  
  		// Then force and update since async paints won't occurs during a Drag
  		// operation
  		getDropTarget().addDropListener(new DropTargetAdapter() {
  			public void dragEnter(DropTargetEvent event) {
  				flush();
  			}
  
  			public void dragLeave(DropTargetEvent event) {
  				flush();
  			}
  
  			public void dragOver(DropTargetEvent event) {
  				flush();
  			}
  		});
  	}
  
  	/**
  	 * Extended to tell the lightweight system what its control is.
  	 * 
  	 * @see org.eclipse.gef.ui.parts.AbstractEditPartViewer#hookControl()
  	 */
  	protected void hookControl() {
  		super.hookControl();
  		Control control = getControl();
  		Object innerCanvas = control.getData(Canvas.class.getName());
  		if (innerCanvas instanceof Canvas) {
  			control = (Canvas) innerCanvas;
  		}
  		getLightweightSystem().setControl((Canvas) control);
  		control.addFocusListener(lFocus = new FocusListener() {
  			public void focusGained(FocusEvent e) {
  				handleFocusGained(e);
  			}
  
  			public void focusLost(FocusEvent e) {
  				handleFocusLost(e);
  			}
  		});
  	}
  
  	/**
  	 * Registers the accessible editpart with the event dispatcher.
  	 * 
  	 * @param acc
  	 *            the accessible
  	 */
  	public void registerAccessibleEditPart(AccessibleEditPart acc) {
  		Assert.isNotNull(acc);
  		DomainEventDispatcher domainEventDispatcher = getEventDispatcher();
  		if (domainEventDispatcher != null) {
  			domainEventDispatcher.putAccessible(acc);
  		}
  	}
  
  	/**
  	 * Reveals the specified editpart by using {@link ExposeHelper}s. A
  	 * bottom-up scan through the parent-chain is performed, looking for expose
  	 * helpers along the way, and asking them to expose the given editpart.
  	 * 
  	 * @see org.eclipse.gef.EditPartViewer#reveal(EditPart)
  	 */
  	public void reveal(EditPart part) {
  		if (part == null)
  			return;
  		EditPart current = part.getParent();
  