/*******************************************************************************
 * 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.tools;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Scrollable;

import org.eclipse.core.runtime.Platform;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.rap.swt.SWT;

import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditDomain;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.MouseWheelHandler;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.Tool;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStackEvent;
import org.eclipse.gef.commands.CommandStackEventListener;
import org.eclipse.gef.editparts.LayerManager;

/**
 * The base implementation for {@link Tool}s. The base implementation provides a
 * framework for a <EM>state machine</EM> which processes mouse and keyboard
 * input. The state machine consists of a series of states identified by
 * <code>int</code>s. Each mouse or keyboard event results in a transition,
 * sometimes to the same state in which the input was received. The interesting
 * transitions have corresponding actions assigned to them, such as
 * {@link #handleDragStarted()}.
 * <P>
 * The base implementation performs <EM>no</em> state transitions by default,
 * but does route events to different method handlers based on state. It is up
 * to subclasses to set the appropriate states.
 * <P>
 * There are two broad "categories" of methods on AbstractTool. There are the
 * methods defined on the {@link Tool} interface which handle the job of
 * receiving raw user input. For example,
 * {@link #mouseDrag(MouseEvent, EditPartViewer)}. Then, there are the methods
 * which correspond to higher-level interpretation of these events, such as
 * {@link #handleDragInProgress()}, which is called from
 * <code>mouseMove(...)</code>, but <em>only</em> when the drag threshold has
 * been passed. These methods are generally more subclass-friendly. Subclasses
 * should <em>not</em> override the methods which receive raw input.
 */
public abstract class AbstractTool extends org.eclipse.gef.util.FlagSupport
		implements Tool, RequestConstants {

	/**
	 * The property to be used in {@link #setProperties(Map)} for
	 * {@link #setUnloadWhenFinished(boolean)}
	 */
	public static final Object PROPERTY_UNLOAD_WHEN_FINISHED = "unloadWhenFinished"; //$NON-NLS-1$

	private static final int DRAG_THRESHOLD = 5;
	private static final int FLAG_ACTIVE = 8;
	private static final int FLAG_HOVER = 2;
	private static final int FLAG_PAST_THRESHOLD = 1;
	private static final int FLAG_UNLOAD = 4;
	{
		setFlag(FLAG_UNLOAD, true);
	}

	/**
	 * The highest-bit flag being used.
	 */
	protected static final int MAX_FLAG = 8;

	/**
	 * The maximum state flag defined by this class
	 */
	protected static final int MAX_STATE = 32;

	/**
	 * constant used for mouse button 1.
	 * 
	 * @deprecated Use {@link SWT#BUTTON1} instead.
	 */
	protected static final int MOUSE_BUTTON1 = SWT.BUTTON1;
	/**
	 * constant used for mouse button 2.
	 * 
	 * @deprecated Use {@link SWT#BUTTON2} instead.
	 */
	protected static final int MOUSE_BUTTON2 = SWT.BUTTON2;
	/**
	 * constant used for mouse button 3.
	 * 
	 * @deprecated Use {@link SWT#BUTTON3} instead.
	 */
	protected static final int MOUSE_BUTTON3 = SWT.BUTTON3;
	/**
	 * constant used to indicate any of the mouse buttons.
	 * 
	 * @deprecated Use {@link SWT#BUTTON_MASK} instead.
	 */
	protected static final int MOUSE_BUTTON_ANY = SWT.BUTTON_MASK;

	/**
	 * The state indicating that the keyboard is being used to perform a drag
	 * that is normally done using the mouse.
	 */
	protected static final int STATE_ACCESSIBLE_DRAG = 16;

	/**
	 * The state indicating that a keyboard drag is in progress. The threshold
	 * for keyboard drags is non-existent, so this state would be entered very
	 * quickly.
	 */
	protected static final int STATE_ACCESSIBLE_DRAG_IN_PROGRESS = 32;

	/**
	 * The state indicating that one or more buttons are pressed, but the user
	 * has not moved past the drag threshold. Many tools will do nothing during
	 * this state but wait until {@link #STATE_DRAG_IN_PROGRESS} is entered.
	 */
	protected static final int STATE_DRAG = 2;

	/**
	 * The state indicating that the drag detection theshold has been passed,
	 * and a drag is in progress.
	 */
	protected static final int STATE_DRAG_IN_PROGRESS = 4;

	/**
	 * The first state that a tool is in. The tool will generally be in this
	 * state immediately following {@link #activate()}.
	 */
	protected static final int STATE_INITIAL = 1;

	/**
	 * The state indicating that an input event has invalidated the interaction.
	 * For example, during a mouse drag, pressing additional mouse button might
	 * invalidate the drag.
	 */
	protected static final int STATE_INVALID = 8;

	/**
	 * The final state for a tool to be in. Once a tool reaches this state, it
	 * will not change states until it is activated() again.
	 */
	protected static final int STATE_TERMINAL = 1 << 30;

	/**
	 * Key modifier for ignoring snap while dragging. It's CTRL on Mac, and ALT
	 * on all other platforms.
	 */
	static final int MODIFIER_NO_SNAPPING;

	static {
		if (Platform.OS_MACOSX.equals(Platform.getOS())) {
			MODIFIER_NO_SNAPPING = SWT.CTRL;
		} else {
			MODIFIER_NO_SNAPPING = SWT.ALT;
		}
	}

	private long accessibleBegin;

	private int accessibleStep;
	private Command command;

	private CommandStackEventListener commandStackListener = new CommandStackEventListener() {
		public void stackChanged(CommandStackEvent event) {
			if (event.isPreChangeEvent())
				handleCommandStackChanged();
		}
	};
	private Input current;
	private EditPartViewer currentViewer;
	private Cursor defaultCursor, disabledCursor;
	private EditDomain domain;
	private List operationSet;
	private int startX, startY, state;

	boolean acceptAbort(KeyEvent e) {
		return e.character == SWT.ESC;
	}

	/**
	 * Returns true if the event corresponds to an arrow key with the
	 * appropriate modifiers and if the system is in a state where the arrow key
	 * should be accepted.
	 * 
	 * @param e
	 *            the key event
	 * @return true if the arrow key should be accepted by this tool
	 * @since 3.4
	 */
	protected boolean acceptArrowKey(KeyEvent e) {
		int key = e.keyCode;
		if (!(isInState(STATE_INITIAL | STATE_ACCESSIBLE_DRAG
				| STATE_ACCESSIBLE_DRAG_IN_PROGRESS)))
			return false;
		return (key == SWT.ARROW_UP) || (key == SWT.ARROW_RIGHT)
				|| (key == SWT.ARROW_DOWN) || (key == SWT.ARROW_LEFT);
	}

	boolean acceptDragCommit(KeyEvent e) {
		return isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS)
				&& e.character == 13;
	}

	int accGetStep() {
		return accessibleStep;
	}

	void accStepIncrement() {
		if (accessibleBegin == -1) {
			accessibleBegin = new Date().getTime();
			accessibleStep = 1;
		} else {
			accessibleStep = 4;
			long elapsed = new Date().getTime() - accessibleBegin;
			if (elapsed > 1000)
				accessibleStep = Math.min(16, (int) (elapsed / 150));
		}
	}

	void accStepReset() {
		accessibleBegin = -1;
	}

	/**
	 * Activates the tool. Any initialization should be performed here. This
	 * method is called when a tool is selected.
	 * 
	 * @see #deactivate()
	 */
	public void activate() {
		resetFlags();
		accessibleBegin = -1;
		getCurrentInput().verifyMouseButtons = true;
		setState(STATE_INITIAL);
		setFlag(FLAG_ACTIVE, true);
		getDomain().getCommandStack().addCommandStackEventListener(
				commandStackListener);
	}

	/**
	 * Convenience method to add the given figure to the feedback layer.
	 * 
	 * @param figure
	 *            the feedback being added
	 */
	protected void addFeedback(IFigure figure) {
		LayerManager lm = (LayerManager) getCurrentViewer()
				.getEditPartRegistry().get(LayerManager.ID);
		if (lm == null)
			return;
		lm.getLayer(LayerConstants.FEEDBACK_LAYER).add(figure);
	}

	/**
	 * This method is invoked from {@link #setProperties(Map)}. Sub-classes can
	 * override to add support for more properties. This method should fail
	 * silently in case of any error.
	 * <p>
	 * AbstractTool uses introspection to match any keys with properties. For
	 * instance, the key "defaultCursor" would lead to the invocation of
	 * {@link #setDefaultCursor(Cursor)} with the provided value.
	 * 
	 * @param key
	 *            the key; may be <code>null</code>
	 * @param value
	 *            the new value
	 * @since 3.1
	 * @see #setProperties(Map)
	 */
	protected void applyProperty(Object key, Object value) {
		if (PROPERTY_UNLOAD_WHEN_FINISHED.equals(key)) {
			if (value instanceof Boolean)
				setUnloadWhenFinished(((Boolean) value).booleanValue());
			return;
		}

		if (!(key instanceof String))
			return;

		try {
			PropertyDescriptor[] descriptors = Introspector.getBeanInfo(
					getClass(), Introspector.IGNORE_ALL_BEANINFO)
					.getPropertyDescriptors();
			PropertyDescriptor property = null;
			for (int i = 0; i < descriptors.length; i++) {
				if (descriptors[i].getName().equals(key)) {
					property = descriptors[i];
					break;
				}
			}
			if (property != null) {
				Method setter = property.getWriteMethod();
				// setter.setAccessible(true);
				setter.invoke(this, new Object[] { value });
			}
		} catch (IntrospectionException ie) {
		} catch (IllegalAccessException iae) {
		} catch (InvocationTargetException ite) {
		} catch (SecurityException se) {
		}
	}

	/**
	 * Returns the appropriate cursor for the tools current state. If the tool
	 * is in its terminal state, <code>null</code> is returned. Otherwise,
	 * either the default or disabled cursor is returned, based on the existence
	 * of a current command, and whether that current command is executable.
	 * <P>
	 * Subclasses may override or extend this method to calculate the
	 * appropriate cursor based on other conditions.
	 * 
	 * @see #getDefaultCursor()
	 * @see #getDisabledCursor()
	 * @see #getCurrentCommand()
	 * @return <code>null</code> or a cursor to be displayed.
	 */
	protected Cursor calculateCursor() {
		if (isInState(STATE_TERMINAL))
			return null;
		Command command = getCurrentCommand();
		if (command == null || !command.canExecute())
			return getDisabledCursor();
		return getDefaultCursor();
	}

	/**
	 * Added for compatibility. {@link DragTracker#commitDrag()} was added for
	 * accessibility reasons. Since all tool implementations must inherit from
	 * this base class, then implementing this method here avoids breaking
	 * subclasses that implemented the {@link DragTracker} interface.
	 */
	public void commitDrag() {
	}

	/**
	 * Returns a new List of editparts that this tool is operating on. This
	 * method is called once during {@link #getOperationSet()}, and its result
	 * is cached.
	 * <P>
	 * By default, the operations set is the current viewer's entire selection.
	 * Subclasses may override this method to filter or alter the operation set
	 * as necessary.
	 * 
	 * @return a list of editparts being operated on
	 */
	protected List createOperationSet() {
		return new ArrayList(getCurrentViewer().getSelectedEditParts());
	}

	/**
	 * Deactivates the tool. This method is called whenever the user switches to
	 * another tool. Use this method to do some clean-up when the tool is
	 * switched. The abstract tool allows cursors for viewers to be changed.
	 * When the tool is deactivated it must revert to normal the cursor of the
	 * last tool it changed.
	 * 
	 * @see #activate()
	 */
	public void deactivate() {
		setFlag(FLAG_ACTIVE, false);
		setViewer(null);
		setCurrentCommand(null);
		setState(STATE_TERMINAL);
		operationSet = null;
		current = null;
		getDomain().getCommandStack().removeCommandStackEventListener(
				commandStackListener);
	}

	/**
	 * Prints a string in the GEF Debug console if the Tools debug option is
	 * selected.
	 * 
	 * @param message
	 *            a message for the debug trace tool
	 * @deprecated
	 */
	protected void debug(String message) {
	}

	/**
	 * Executes the given command on the command stack.
	 * 
	 * @since 3.1
	 * @param command
	 *            the command to execute
	 */
	protected void executeCommand(Command command) {
		getDomain().getCommandStack().removeCommandStackEventListener(
				commandStackListener);
		try {
			getDomain().getCommandStack().execute(command);
		} finally {
			getDomain().getCommandStack().addCommandStackEventListener(
					commandStackListener);
		}
	}

	/**
	 * Execute the currently active command.
	 */
	protected void executeCurrentCommand() {
		Command curCommand = getCurrentCommand();
		if (curCommand != null && curCommand.canExecute())
			executeCommand(curCommand);
		setCurrentCommand(null);
	}

	/**
	 * Called when a viewer that the editor controls gains focus.
	 * 
	 * @param event
	 *            The SWT focus event
	 * @param viewer
	 *            The viewer that the focus event is over.
	 */
	public void focusGained(FocusEvent event, EditPartViewer viewer) {
		setViewer(viewer);
		handleFocusGained();
	}

	/**
	 * Called when a viewer that the editor controls loses focus.
	 * 
	 * @param event
	 *            The SWT focus event
	 * @param viewer
	 *            The viewer that the focus event is over.
	 */
	public void focusLost(FocusEvent event, EditPartViewer viewer) {
		setViewer(viewer);
		handleFocusLost();
	}

	/**
	 * Returns a new, updated command based on the tool's current properties.
	 * The default implementation returns an unexecutable command. Some tools do
	 * not work commands and the model, but simply change the viewer's state in
	 * some way.
	 * 
	 * @return a newly obtained command
	 */
	protected Command getCommand() {
		return org.eclipse.gef.commands.UnexecutableCommand.INSTANCE;
	}

	/**
	 * Returns the identifier of the command that is being sought. This name is
	 * also the named that will be logged in the debug view.
	 * 
	 * @return the identifier for the command
	 */
	protected abstract String getCommandName();

	/**
	 * Returns the currently cached command.
	 * 
	 * @return the current command
	 * @see #setCurrentCommand(Command)
	 */
	protected Command getCurrentCommand() {
		return command;
	}

	/**
	 * Returns the input object encapsulating the current mouse and keyboard
	 * state.
	 * 
	 * @return the current input
	 */
	protected Input getCurrentInput() {
		if (current == null)
			current = new Input();
		return current;
	}

	/**
	 * Return the viewer that the tool is currently receiving input from, or
	 * <code>null</code>. The last viewer to dispatch an event is defined as the
	 * current viewer. Current viewer is automatically updated as events are
	 * received, and is set to <code>null</code> on <code>deactivate()</code>.
	 * 
	 * @return the current viewer
	 */
	protected EditPartViewer getCurrentViewer() {
		return currentViewer;
	}

	/**
	 * Returns the debug name for this tool.
	 * 
	 * @return the debug name
	 */
	protected String getDebugName() {
		return getClass().getName();
	}

	/**
	 * Returns a String representation of the given state for debug purposes.
	 * 
	 * @param state
	 *            the state
	 * @return the string for the given state
	 */
	protected String getDebugNameForState(int state) {
		switch (state) {
		case STATE_INITIAL:
			return "Initial State";//$NON-NLS-1$
		case STATE_DRAG:
			return "Drag State";//$NON-NLS-1$
		case STATE_DRAG_IN_PROGRESS:
			return "Drag In Progress State";//$NON-NLS-1$
		case STATE_INVALID:
			return "Invalid State"; //$NON-NLS-1$
		case STATE_TERMINAL:
			return "Terminal State"; //$NON-NLS-1$
		case STATE_ACCESSIBLE_DRAG:
			return "Accessible Drag"; //$NON-NLS-1$
		case STATE_ACCESSIBLE_DRAG_IN_PROGRESS:
			return "Accessible Drag In Progress"; //$NON-NLS-1$
		}
		return "Unknown state:";//$NON-NLS-1$
	}

	/**
	 * Returns the cursor used under normal conditions.
	 * 
	 * @see #setDefaultCursor(Cursor)
	 * @return the default cursor
	 */
	protected Cursor getDefaultCursor() {
		return defaultCursor;
	}

	/**
	 * Returns the cursor used under abnormal conditions.
	 * 
	 * @see #calculateCursor()
	 * @see #setDisabledCursor(Cursor)
	 * @return the disabled cursor
	 */
	protected Cursor getDisabledCursor() {
		if (disabledCursor != null)
			return disabledCursor;
		return getDefaultCursor();
	}

	/**
	 * Returns the EditDomain. A tool is told its EditDomain when it becomes
	 * active. A tool may need to know its edit domain prior to receiving any
	 * events from any of that domain's viewers.
	 * 
	 * @return the editdomain
	 */
	protected EditDomain getDomain() {
		return domain;
	}

	/**
	 * Return the number of pixels that the mouse has been moved since that drag
	 * was started. The drag start is determined by where the mouse button was
	 * first pressed.
	 * 
	 * @see #getStartLocation()
	 * @return the drag delta
	 */
	protected Dimension getDragMoveDelta() {
		return getLocation().getDifference(getStartLocation());
	}

	/**
	 * Returns the current x, y position of the mouse cursor.
	 * 
	 * @return the mouse location
	 */
	protected Point getLocation() {
		return new Point(getCurrentInput().getMouseLocation());
	}

	/**
	 * Lazily creates and returns the list of editparts on which the tool
	 * operates. The list is initially <code>null</code>, in which case
	 * {@link #createOperationSet()} is called, and its results cached until the
	 * tool is deactivated.
	 * 
	 * @return the operation set.
	 */
	protected List getOperationSet() {
		if (operationSet == null)
			operationSet = createOperationSet();
		return operationSet;
	}

	/**
	 * Returns the starting mouse location for the current tool operation. This
	 * is typically the mouse location where the user first pressed a mouse
	 * button. This is important for tools that interpret mouse drags.
	 * 
	 * @return the start location
	 */
	protected Point getStartLocation() {
		return new Point(startX, startY);
	}

	/**
	 * Returns the tool's current state.
	 * 
	 * @return the current state
	 */
	protected int getState() {
		return state;
	}

	/**
	 * Called when the mouse button has been pressed. By default, nothing
	 * happens and <code>false</code> is returned. Subclasses may override this
	 * method to interpret the meaning of a mouse down. Returning
	 * <code>true</code> indicates that the button down was handled in some way.
	 * 
	 * @param button
	 *            which button went down
	 * @return <code>true</code> if the buttonDown was handled
	 */
	protected boolean handleButtonDown(int button) {
		return false;
	}

	/**
	 * Called when the mouse button has been released. By default, nothing
	 * happens and <code>false</code> is returned. Subclasses may override this
	 * method to interpret the mouse up. Returning <code>true</code> indicates
	 * that the mouse up was handled in some way.
	 * 
	 * @see #mouseUp(MouseEvent, EditPartViewer)
	 * @param button
	 *            the button being released
	 * @return <code>true</code> if the button up was handled
	 */
	protected boolean handleButtonUp(int button) {
		return false;
	}

	/**
	 * Called when the command stack has changed, for instance, when a delete or
	 * undo command has been executed. By default, state is set to
	 * <code>STATE_INVALID</code> and handleInvalidInput is called. Subclasses
	 * may override this method to change what happens when the command stack
	 * changes. Returning <code>true</code> indicates that the change was
	 * handled in some way.
	 * 
	 * @return <code>true</code> if the change was handled in some way
	 */
	protected boolean handleCommandStackChanged() {
		if (!isInState(STATE_INITIAL | STATE_INVALID)) {
			setState(STATE_INVALID);
			handleInvalidInput();
			return true;
		}
		return false;
	}

	/**
	 * Called when a mouse double-click occurs. By default, nothing happens and
	 * <code>false</code> is returned. Subclasses may override this method to
	 * interpret double-clicks. Returning <code>true</code> indicates that the
	 * event was handled in some way.
	 * 
	 * @param button
	 *            which button was double-clicked
	 * @return <code>true</code> if the event was handled
	 * @see #mouseDoubleClick(MouseEvent, EditPartViewer)
	 */
	protected boolean handleDoubleClick(int button) {
		return false;
	}

	/**
	 * Called whenever the mouse is being dragged. This method continues to be
	 * called even once {@link #handleDragInProgress()} starts getting called.
	 * By default, nothing happens, and <code>false</code> is returned.
	 * Subclasses may override this method to interpret a drag. Returning
	 * <code>true</code> indicates that the drag was handled in some way.
	 * 
	 * @return <code>true</code> if the drag is handled
	 * @see #mouseDrag(MouseEvent, EditPartViewer)
	 */
	protected boolean handleDrag() {
		return false;
	}

	/**
	 * Called whenever a mouse is being dragged and the drag threshold has been
	 * exceeded. Prior to the drag threshold being exceeded, only
	 * {@link #handleDrag()} is called. This method gets called repeatedly for
	 * every mouse move during the drag. By default, nothing happens and
	 * <code>false</code> is returned. Subclasses may override this method to
	 * interpret the drag. Returning <code>true</code> indicates that the drag
	 * was handled.
	 * 
	 * @see #movedPastThreshold()
	 * @see #mouseDrag(MouseEvent, EditPartViewer)
	 * @return <code>true</code> if the drag was handled
	 */
	protected boolean handleDragInProgress() {
		return false;
	}

	/**
	 * Called only one time during a drag when the drag threshold has been
	 * exceeded. By default, nothing happens and <code>false</code> is returned.
	 * Subclasses may override to interpret the drag starting. Returning
	 * <code>true</code> indicates that the event was handled.
	 * 
	 * @see #movedPastThreshold()
	 * @see #mouseDrag(MouseEvent, EditPartViewer)
	 * @return true if the drag starting was handled
	 */
	protected boolean handleDragStarted() {
		return false;
	}

	/**
	 * Called when the current tool operation is to be completed. In other
	 * words, the "state machine" and has accepted the sequence of input (i.e.
	 * the mouse gesture). By default, the tool will either reactivate itself,
	 * or ask the edit domain to load the default tool.
	 * <P>
	 * Subclasses should extend this method to first do whatever it is that the
	 * tool does, and then call <code>super</code>.
	 * 
	 * @see #unloadWhenFinished()
	 */
	protected void handleFinished() {
		if (unloadWhenFinished())
			getDomain().loadDefaultTool();
		else
			reactivate();
	}

	/**
	 * Handles high-level processing of a focus gained event. By default,
	 * nothing happens and <code>false</code> is returned. Subclasses may
	 * override this method to interpret the focus gained event. Return
	 * <code>true</code> to indicate that the event was processed.
	 * 
	 * @see #focusGained(FocusEvent, EditPartViewer)
	 * @return <code>true</code> if the event was handled
	 */
	protected boolean handleFocusGained() {
		return false;
	}

	/**
	 * Handles high-level processing of a focus lost event. By default, nothing
	 * happens and <code>false</code> is returned. Subclasses may override this
	 * method to interpret the focus lost event. Return <code>true</code> to
	 * indicate that the event was processed.
	 * 
	 * @see #focusLost(FocusEvent, EditPartViewer)
	 * @return <code>true</code> if the event was handled
	 */
	protected boolean handleFocusLost() {
		return false;
	}

	/**
	 * Handles high-level processing of a mouse hover event. By default, nothing
	 * happens and <code>false</code> is returned. Subclasses may override this
	 * method to interpret the hover. Return <code>true</code> to indicate that
	 * the hover was handled.
	 * 
	 * @see #mouseHover(MouseEvent, EditPartViewer)
	 * @return <code>true</code> if the hover was handled
	 */
	protected boolean handleHover() {
		return false;
	}

	/**
	 * Called when invalid input is encountered. The state does not change, so
	 * the caller must set the state to {@link AbstractTool#STATE_INVALID}.
	 * 
	 * @return <code>true</code>
	 */
	protected boolean handleInvalidInput() {
		return false;
	}

	/**
	 * Handles high-level processing of a key down event. By default, the
	 * KeyEvent is checked to see if it is the ESCAPE key. If so, the domain's
	 * default tool is reloaded, and <code>true</code> is returned. Subclasses
	 * may extend this method to interpret additional key down events. Returns
	 * <code>true</code> if the given key down was handled.
	 * 
	 * @see #keyDown(KeyEvent, EditPartViewer)
	 * @param e
	 *            the key event
	 * @return <code>true</code> if the key down was handled.
	 */
	protected boolean handleKeyDown(KeyEvent e) {
		if (acceptAbort(e)) {
			getDomain().loadDefaultTool();
			return true;
		}
		return false;
	}

	/**
	 * Override to process a traverse event. If the event's
	 * {@link KeyEvent#doit doit} field is set to <code>false</code>, the
	 * traversal will be prevented from occurring. Otherwise, a traverse will
	 * occur.
	 * 
	 * @param event
	 *            the SWT traverse event
	 * @since 3.1
	 */
	protected void handleKeyTraversed(TraverseEvent event) {
	}

	/**
	 * Handles high-level processing of a key up event. By default, does nothing
	 * and returns <code>false</code>. Subclasses may extend this method to
	 * process key up events. Returns <code>true</code> if the key up was
	 * processed in some way.
	 * 
	 * @see #keyUp(KeyEvent, EditPartViewer)
	 * @param e
	 *            the key event
	 * @return <code>true</code> if the event was handled
	 */
	protected boolean handleKeyUp(KeyEvent e) {
		return false;
	}

	/**
	 * Handles high-level processing of a mouse move. By default, does nothing
	 * and returns <code>false</code>. Subclasses may extend this method to
	 * process mouse moves. Returns <code>true</code> if the mouse move was
	 * processed.
	 * 
	 * @see #mouseMove(MouseEvent, EditPartViewer)
	 * @return <code>true</code> if the mouse move was handled
	 */
	protected boolean handleMove() {
		return false;
	}

	/**
	 * Handles when a native drag has ended. By default, does nothing and
	 * returns <code>false</code>. Subclasses may extend this method to process
	 * native drags ending.
	 * 
	 * @param event
	 *            the drag event
	 * @return <code>true</code> if the native drag finished was handled
	 */
	protected boolean handleNativeDragFinished(DragSourceEvent event) {
		return false;
	}

	/**
	 * Handles when a native drag has started. By default, does nothing and
	 * returns <code>false</code>. Subclasses may extend this method to process
	 * native drag starts.
	 * <P>
	 * When a native drag starts, all subsequent mouse events will not be
	 * received, including the mouseUp event. The only event that will be
	 * received is the drag finished event.
	 * 
	 * @param event
	 *            the drag event
	 * @return <code>true</code> if the native drag start was handled
	 */
	protected boolean handleNativeDragStarted(DragSourceEvent event) {
		return false;
	}

	/**
	 * Called when the mouse enters an EditPartViewer. By default, does nothing
	 * and returns <code>false</code>. Subclasses may extend this method to
	 * process the viewer enter. Returns <code>true</code> to indicate if the
	 * viewer entered was process in some way.
	 * 
	 * @return <code>true</code> if the viewer entered was handled
	 */
	protected boolean handleViewerEntered() {
		return false;
	}

	/**
	 * Called when the mouse exits an EditPartViewer. By default, does nothing
	 * and returns <code>false</code>. Subclasses may extend this method to
	 * process viewer exits. Returns <code>true</code> to indicate if the viewer
	 * exited was process in some way.
	 * 
	 * @return <code>true</code> if the viewer exited was handled
	 */
	protected boolean handleViewerExited() {
		return false;
	}

	/**
	 * Returns <code>true</code> if the tool is active.
	 * 
	 * @return <code>true</code> if active
	 */
	protected boolean isActive() {
		return getFlag(FLAG_ACTIVE);
	}

	boolean isCurrentViewerMirrored() {
		return (getCurrentViewer().getControl().getStyle() & SWT.MIRRORED) != 0;
	}

	/**
	 * Returns <code>true</code> if the tool is hovering.
	 * 
	 * @return <code>true</code> if hovering
	 */
	protected boolean isHoverActive() {
		return getFlag(FLAG_HOVER);
	}

	boolean isInDragInProgress() {
		return isInState(STATE_DRAG_IN_PROGRESS
				| STATE_ACCESSIBLE_DRAG_IN_PROGRESS);
	}

	/*
	 * Returns <code>true</code> if the current {@link Input} is synchronized
	 * with the current MouseEvent.
	 */
	private boolean isInputSynched(MouseEvent event) {
		Input input = getCurrentInput();
		return input.isMouseButtonDown(1) == ((event.stateMask & SWT.BUTTON1) != 0)
				&& input.isMouseButtonDown(2) == ((event.stateMask & SWT.BUTTON2) != 0)
				&& input.isMouseButtonDown(3) == ((event.stateMask & SWT.BUTTON3) != 0)
				&& input.isMouseButtonDown(4) == ((event.stateMask & SWT.BUTTON4) != 0)
				&& input.isMouseButtonDown(5) == ((event.stateMask & SWT.BUTTON5) != 0);
	}

	/**
	 * Returns <code>true</code> if the tool is in the given state.
	 * 
	 * @param state
	 *            the state being queried
	 * @return <code>true</code> if the tool is in the given state
	 */
	protected boolean isInState(int state) {
		return ((getState() & state) != 0);
	}

	/**
	 * Default implementation always returns <code>true</code>. Sub-classes may
	 * override.
	 * 
	 * @param viewer
	 *            the viewer where the event occured
	 * @return <code>true</code> if this tool is interested in events occuring
	 *         in the given viewer; <code>false</code> otherwise
	 * @since 3.1
	 */
	protected boolean isViewerImportant(EditPartViewer viewer) {
		return true;
	}

	/**
	 * Receives a KeyDown event for the given viewer. Subclasses wanting to
	 * handle this event should override {@link #handleKeyDown(KeyEvent)}.
	 * 
	 * @param evt
	 *            the key event
	 * @param viewer
	 *            the originating viewer
	 */
	public void keyDown(KeyEvent evt, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(evt);
		handleKeyDown(evt);
	}

	/**
	 * Receives a traversal event for the given viewer. Subclasses wanting to
	 * handle this event should override
	 * {@link #handleKeyTraversed(TraverseEvent)}.
	 * 
	 * @param event
	 *            the traverse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void keyTraversed(TraverseEvent event, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(event);
		handleKeyTraversed(event);
	}

	/**
	 * Receives a KeyUp event for the given viewer. Subclasses wanting to handle
	 * this event should override {@link #handleKeyUp(KeyEvent)}.
	 * 
	 * @param evt
	 *            the key event
	 * @param viewer
	 *            the originating viewer
	 */
	public void keyUp(KeyEvent evt, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(evt);
		handleKeyUp(evt);
	}

	/**
	 * Handles mouse double click events within a viewer. Subclasses wanting to
	 * handle this event should override {@link #handleDoubleClick(int)}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void mouseDoubleClick(MouseEvent me, EditPartViewer viewer) {
		if (me.button > 5 || !isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(me);

		handleDoubleClick(me.button);
	}

	/**
	 * Handles mouse down events within a viewer. Subclasses wanting to handle
	 * this event should override {@link #handleButtonDown(int)}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void mouseDown(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);

		getCurrentInput().setInput(me);
		getCurrentInput().setMouseButton(me.button, true);

		setStartLocation(new Point(me.x, me.y));

		handleButtonDown(me.button);
	}

	/**
	 * Handles mouse drag events within a viewer. Subclasses wanting to handle
	 * this event should override {@link #handleDrag()} and/or
	 * {@link #handleDragInProgress()}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void mouseDrag(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		boolean wasDragging = movedPastThreshold();
		getCurrentInput().setInput(me);
		handleDrag();
		if (movedPastThreshold()) {
			if (!wasDragging)
				handleDragStarted();
			handleDragInProgress();
		}
	}

	/**
	 * Handles mouse hover event. within a viewer. Subclasses wanting to handle
	 * this event should override {@link #handleHover()}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 * 
	 */
	public void mouseHover(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(me);
		handleHover();
	}

	/**
	 * Handles mouse moves (if the mouse button is up) within a viewer.
	 * Subclasses wanting to handle this event should override
	 * {@link #handleMove()}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void mouseMove(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		if (!isInputSynched(me)) {
			boolean b1 = getCurrentInput().isMouseButtonDown(1);
			boolean b2 = getCurrentInput().isMouseButtonDown(2);
			boolean b3 = getCurrentInput().isMouseButtonDown(3);
			boolean b4 = getCurrentInput().isMouseButtonDown(4);
			boolean b5 = getCurrentInput().isMouseButtonDown(5);
			getCurrentInput().verifyMouseButtons = true;
			getCurrentInput().setInput(me);
			if (b1)
				handleButtonUp(1);
			if (b2)
				handleButtonUp(2);
			if (b3)
				handleButtonUp(3);
			if (b4)
				handleButtonUp(4);
			if (b5)
				handleButtonUp(5);
			if (getDomain().getActiveTool() != this)
				return;
			/*
			 * processing one of the buttonUps may have caused the tool to
			 * reactivate itself, which causes the viewer to get nulled-out. If
			 * we are going to call another handleXxx method below, we must set
			 * the viewer again to be paranoid.
			 */
			setViewer(viewer);
		} else
			getCurrentInput().setInput(me);
		if (isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS))
			handleDragInProgress();
		else
			handleMove();
	}

	/**
	 * Handles mouse up within a viewer. Subclasses wanting to handle this event
	 * should override {@link #handleButtonUp(int)}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void mouseUp(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		getCurrentInput().setInput(me);
		getCurrentInput().setMouseButton(me.button, false);
		handleButtonUp(me.button);
	}

	/**
	 * Handles mouse-wheel scrolling for a viewer. Sub-classes may override as
	 * needed. The default implementation delegates to
	 * {@link #performViewerMouseWheel(Event, EditPartViewer)} IFF the tool is
	 * in the initial state. Mouse-wheel events generated at other times are
	 * ignored.
	 * 
	 * @param event
	 *            the SWT scroll event
	 * @param viewer
	 *            the originating viewer
	 * @see #performViewerMouseWheel(Event, EditPartViewer)
	 */
	public void mouseWheelScrolled(Event event, EditPartViewer viewer) {
		if (isInState(STATE_INITIAL))
			performViewerMouseWheel(event, viewer);
	}

	/**
	 * Returns <code>true</code> if the threshold has been exceeded during a
	 * mouse drag.
	 * 
	 * @return <code>true</code> if the threshold has been exceeded
	 */
	protected boolean movedPastThreshold() {
		if (getFlag(FLAG_PAST_THRESHOLD))
			return true;
		Point start = getStartLocation(), end = getLocation();
		if (Math.abs(start.x - end.x) > DRAG_THRESHOLD
				|| Math.abs(start.y - end.y) > DRAG_THRESHOLD) {
			setFlag(FLAG_PAST_THRESHOLD, true);
			return true;
		}
		return false;
	}

	/**
	 * @see org.eclipse.gef.Tool#nativeDragFinished(DragSourceEvent,
	 *      EditPartViewer)
	 */
	public void nativeDragFinished(DragSourceEvent event, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		handleNativeDragFinished(event);
	}

	/**
	 * @see org.eclipse.gef.Tool#nativeDragStarted(DragSourceEvent,
	 *      EditPartViewer)
	 */
	public void nativeDragStarted(DragSourceEvent event, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		setViewer(viewer);
		handleNativeDragStarted(event);
	}

	/**
	 * Delegates mouse-wheel event handling to registered
	 * {@link MouseWheelHandler MouseWheelHandlers} based on the given Event's
	 * statemask. Does nothing if there are no matching handlers found.
	 * 
	 * @param event
	 *            the SWT scroll event
	 * @param viewer
	 *            the originating viewer
	 * @since 3.1
	 */
	protected void performViewerMouseWheel(Event event, EditPartViewer viewer) {
		MouseWheelHandler handler = (MouseWheelHandler) viewer
				.getProperty(MouseWheelHandler.KeyGenerator
						.getKey(event.stateMask));
		if (handler != null)
			handler.handleMouseWheel(event, viewer);
	}

	/**
	 * Places the mouse in the viewer based on the point given. If the point
	 * given is outside the viewer, then the mouse is placed in the location
	 * nearest the given point but within the viewer.
	 * 
	 * @param p
	 *            the point
	 * @since 3.4
	 */
	protected void placeMouseInViewer(Point p) {
		if (getCurrentViewer() == null)
			return;
		Control c = getCurrentViewer().getControl();
		Rectangle rect;
		if (c instanceof Scrollable)
			rect = ((Scrollable) c).getClientArea();
		else
			rect = c.getBounds();
		if (p.x > rect.x + rect.width - 1)
			p.x = rect.x + rect.width - 1;
		else if (p.x < rect.x)
			p.x = rect.x;
		if (p.y > rect.y + rect.height - 1)
			p.y = rect.y + rect.height - 1;
		else if (p.y < rect.y)
			p.y = rect.y;
		org.eclipse.swt.graphics.Point swt = new org.eclipse.swt.graphics.Point(
				p.x, p.y);
		swt = c.toDisplay(swt);
		// UNSUPPORTED - api not supported in RAP
		// c.getDisplay().setCursorLocation(swt);
	}

	/**
	 * Calls <code>deactivate()</code> and then <code>activate()</code>.
	 */
	protected void reactivate() {
		// Fix for Bug# 91448
		EditPartViewer viewer = getCurrentViewer();
		deactivate();
		activate();
		if (viewer != null) {
			Control c = viewer.getControl();
			if (c != null && !c.isDisposed() && c.isFocusControl())
				setViewer(viewer);
		}
	}

	/**
	 * Sets the cursor being displayed to the appropriate cursor. If the tool is
	 * active, the current cursor being displayed is updated by calling
	 * {@link #calculateCursor()}.
	 */
	protected void refreshCursor() {
		if (isActive())
			setCursor(calculateCursor());
	}

	/**
	 * Releases tool capture.
	 * 
	 * @see #setToolCapture()
	 */
	protected void releaseToolCapture() {
		getCurrentViewer().setRouteEventsToEditDomain(false);
	}

	/**
	 * Convenience method to removes a figure from the feedback layer.
	 * 
	 * @param figure
	 *            the figure being removed
	 */
	protected void removeFeedback(IFigure figure) {
		LayerManager lm = (LayerManager) getCurrentViewer()
				.getEditPartRegistry().get(LayerManager.ID);
		if (lm == null)
			return;
		lm.getLayer(LayerConstants.FEEDBACK_LAYER).remove(figure);
	}

	/**
	 * Resets all stateful flags to their initial values. Subclasses should
	 * extend this method to reset their own custom flags.
	 */
	protected void resetFlags() {
		setFlag(FLAG_PAST_THRESHOLD, false);
		setFlag(FLAG_HOVER, false);
	}

	/**
	 * Used to cache a command obtained from {@link #getCommand()}.
	 * 
	 * @param c
	 *            the command
	 * @see #getCurrentCommand()
	 */
	protected void setCurrentCommand(Command c) {
		command = c;
		refreshCursor();
	}

	/**
	 * Shows the given cursor on the current viewer.
	 * 
	 * @param cursor
	 *            the cursor to display
	 */
	protected void setCursor(Cursor cursor) {
		if (getCurrentViewer() != null)
			getCurrentViewer().setCursor(cursor);
	}

	/**
	 * Sets the default cursor.
	 * 
	 * @param cursor
	 *            the cursor
	 * @see #getDefaultCursor()
	 */
	public void setDefaultCursor(Cursor cursor) {
		if (defaultCursor == cursor)
			return;
		defaultCursor = cursor;
		refreshCursor();
	}

	/**
	 * Sets the disabled cursor.
	 * 
	 * @param cursor
	 *            the cursor
	 * @see #getDisabledCursor()
	 */
	public void setDisabledCursor(Cursor cursor) {
		if (disabledCursor == cursor)
			return;
		disabledCursor = cursor;
		refreshCursor();
	}

	/**
	 * Sets the EditDomain.
	 * 
	 * @param domain
	 *            the edit domain
	 * @see #getDomain()
	 */
	public void setEditDomain(EditDomain domain) {
		this.domain = domain;
	}

	/**
	 * Sets whether the hover flag is true or false. Subclasses which do
	 * something on hover can use this flag to track whether they have received
	 * a hover or not.
	 * 
	 * @param value
	 *            whether hover is active
	 */
	protected void setHoverActive(boolean value) {
		setFlag(FLAG_HOVER, value);
	}

	void setMouseCapture(boolean value) {
		// UNSUPPORTED - capture api not implemented in RAP
		// if (getCurrentViewer() != null
		// && getCurrentViewer().getControl() != null
		// && !getCurrentViewer().getControl().isDisposed())
		// getCurrentViewer().getControl().setCapture(value);
	}

	/**
	 * An example is {@link #PROPERTY_UNLOAD_WHEN_FINISHED} -> Boolean.
	 * AbstractTool uses introspection to set properties that are not explicitly
	 * specified. For instance, the key "defaultCursor" will cause
	 * {@link #setDefaultCursor(Cursor)} to be invoked with the given value.
	 * 
	 * @see org.eclipse.gef.Tool#setProperties(java.util.Map)
	 */
	public void setProperties(Map properties) {
		if (properties == null)
			return;
		Iterator entries = properties.entrySet().iterator();
		while (entries.hasNext()) {
			Entry entry = (Entry) entries.next();
			applyProperty(entry.getKey(), entry.getValue());
		}
	}

	/**
	 * Sets the start mouse location, typically for a drag operation.
	 * 
	 * @param p
	 *            the start location
	 */
	protected void setStartLocation(Point p) {
		startX = p.x;
		startY = p.y;
	}

	/**
	 * Sets the tools state.
	 * 
	 * @param state
	 *            the new state
	 */
	protected void setState(int state) {
		this.state = state;
	}

	/**
	 * Sets tool capture. When a tool has capture, viewers will make every
	 * effort to send events through the editdomain to the tool. Therefore, the
	 * default handling of some events is bypassed.
	 */
	protected void setToolCapture() {
		getCurrentViewer().setRouteEventsToEditDomain(true);
	}

	/**
	 * Setting this to <code>true</code> will cause the tool to be unloaded
	 * after one operation has completed. The default value is <code>true</code>
	 * . The tool is unloaded, and the edit domains default tool will be
	 * activated.
	 * 
	 * @param value
	 *            whether the tool should be unloaded on completion
	 */
	public void setUnloadWhenFinished(boolean value) {
		setFlag(FLAG_UNLOAD, value);
	}

	/**
	 * Sets the active EditPartViewer. The active viewer is the viewer from
	 * which the last event was received.
	 * 
	 * @param viewer
	 *            the viewer
	 */
	public void setViewer(EditPartViewer viewer) {
		if (viewer == currentViewer)
			return;

		setCursor(null);
		currentViewer = viewer;
		if (currentViewer != null) {
			org.eclipse.swt.graphics.Point p = currentViewer.getControl()
					.toControl(Display.getCurrent().getCursorLocation());
			getCurrentInput().setMouseLocation(p.x, p.y);
		}
		refreshCursor();
	}

	/**
	 * Returns <code>true</code> if the give state transition succeeds. This is
	 * a "test and set" operation, where the tool is tested to be in the
	 * specified start state, and if so, is set to the given end state. The
	 * method returns the result of the first test.
	 * 
	 * @param start
	 *            the start state being tested
	 * @param end
	 *            the end state
	 * @return <code>true</code> if the state transition is successful
	 */
	protected boolean stateTransition(int start, int end) {
		if ((getState() & start) != 0) {
			setState(end);
			return true;
		} else
			return false;
	}

	/**
	 * Returns <code>true</code> if the tool is set to unload when its current
	 * operation is complete.
	 * 
	 * @return <code>true</code> if the tool should be unloaded when finished
	 */
	protected final boolean unloadWhenFinished() {
		return getFlag(FLAG_UNLOAD);
	}

	/**
	 * Receives the mouse entered event. Subclasses wanting to handle this event
	 * should override {@link #handleViewerEntered()}.
	 * <p>
	 * FEATURE in SWT: mouseExit comes after mouseEntered on the new control.
	 * Therefore, if the current viewer is not <code>null</code>, it means the
	 * exit has not been sent yet by SWT. To maintain proper ordering, GEF fakes
	 * the exit and calls {@link #handleViewerExited()}. The real exit will then
	 * be ignored.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void viewerEntered(MouseEvent me, EditPartViewer viewer) {
		if (!isViewerImportant(viewer))
			return;
		getCurrentInput().setInput(me);
		if (getCurrentViewer() != null && getCurrentViewer() != viewer)
			handleViewerExited();
		setViewer(viewer);
		handleViewerEntered();
	}

	/**
	 * Handles the mouse exited event. Subclasses wanting to handle this event
	 * should override {@link #handleViewerExited()}.
	 * 
	 * @param me
	 *            the mouse event
	 * @param viewer
	 *            the originating viewer
	 */
	public void viewerExited(MouseEvent me, EditPartViewer viewer) {
		/*
		 * FEATURE in SWT. mouseExited comes after mouseEntered. So only call
		 * handle exit if we didn't previously fake it on viewer entered.
		 */
		if (viewer == getCurrentViewer()) {
			getCurrentInput().setInput(me);
			handleViewerExited();
			setViewer(null);
		}
	}

	/**
	 * Allows the user to access mouse and keyboard input.
	 */
	public static class Input extends org.eclipse.gef.util.FlagSupport {
		int modifiers;
		Point mouse = new Point();
		boolean verifyMouseButtons;

		/**
		 * Returns the event modifiers. Modifiers are defined in
		 * {@link MouseEvent#stateMask}, and include things like the mouse
		 * buttons and keyboard modifier keys.
		 * 
		 * @return the event modifiers
		 */
		protected int getModifiers() {
			return modifiers;
		}

		/**
		 * Returns the current location of the mouse.
		 * 
		 * @return the mouse location
		 */
		public Point getMouseLocation() {
			return mouse;
		}

		/**
		 * Returns <code>true</code> if the ALT key is pressed.
		 * 
		 * @return <code>true</code> if the ALT key is pressed
		 */
		public boolean isAltKeyDown() {
			return (modifiers & SWT.ALT) != 0;
		}

		/**
		 * Returns <code>true</code> if any of the mouse buttons are pressed.
		 * 
		 * @return <code>true</code> if any of the mouse buttons are pressed
		 */
		public boolean isAnyButtonDown() {
			return getFlag(2 | 4 | 8 | 16 | 32);
		}

		/**
		 * Returns <code>true</code> if the CTRL key is pressed.
		 * 
		 * @return <code>true</code> of CTRL pressed
		 */
		public boolean isControlKeyDown() {
			return (modifiers & SWT.CONTROL) != 0;
		}

		/**
		 * Returns <code>true</code> if any of the given mod keys are pressed.
		 * 
		 * @param mod
		 *            SWT.MOD1, SWT.MOD2, SWT.MOD3, SWT.MOD4 or any combination
		 *            thereof
		 * @return <code>true</code> if the given mod key is pressed
		 * @since 3.1
		 */
		public boolean isModKeyDown(int mod) {
			return (modifiers & mod) != 0;
		}

		/**
		 * Returns <code>true</code> if the specified button is down.
		 * 
		 * @param which
		 *            which button
		 * @return <code>true</code> if the button is down
		 */
		public boolean isMouseButtonDown(int which) {
			return getFlag(1 << which);
		}

		/**
		 * Returns <code>true</code> if the SHIFT key is pressed.
		 * 
		 * @return <code>true</code> if SHIFT pressed
		 */
		public boolean isShiftKeyDown() {
			return (modifiers & SWT.SHIFT) != 0;
		}

		/**
		 * Sets the keyboard input based on the KeyEvent.
		 * 
		 * @param ke
		 *            the key event providing the input
		 */
		public void setInput(KeyEvent ke) {
			modifiers = ke.stateMask;
		}

		/**
		 * Sets the mouse and keyboard input based on the MouseEvent.
		 * 
		 * @param me
		 *            the mouse event providing the input
		 */
		public void setInput(MouseEvent me) {
			setMouseLocation(me.x, me.y);
			modifiers = me.stateMask;
			if (verifyMouseButtons) {
				setMouseButton(1, (modifiers & SWT.BUTTON1) != 0);
				setMouseButton(2, (modifiers & SWT.BUTTON2) != 0);
				setMouseButton(3, (modifiers & SWT.BUTTON3) != 0);
				setMouseButton(4, (modifiers & SWT.BUTTON4) != 0);
				setMouseButton(5, (modifiers & SWT.BUTTON5) != 0);
				verifyMouseButtons = false;
			}
		}

		/**
		 * Sets mouse button # <code>which</code> to be pressed if
		 * <code>state</code> is true.
		 * 
		 * @param which
		 *            which button
		 * @param state
		 *            <code>true</code> if button down
		 */
		public void setMouseButton(int which, boolean state) {
			setFlag(1 << which, state);
		}

		/**
		 * Sets the current location of the mouse
		 * 
		 * @param x
		 *            x location
		 * @param y
		 *            y location
		 * @since 3.4
		 */
		public void setMouseLocation(int x, int y) {
			mouse.setLocation(x, y);
		}
	}

}
