/*******************************************************************************
 * 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.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Display;

import org.eclipse.jface.viewers.StructuredSelection;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.KeyHandler;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.util.EditPartUtilities;

/**
 * A Tool which selects multiple {@link EditPart}s inside a rectangular area of
 * a Graphical Viewer. Selection behavior can be configured by selecting (via
 * {@link #setMarqueeBehavior(int)}) one of six supported marquee behaviors,
 * which are:
 * 
 * <ul>
 * <li>{@link #BEHAVIOR_NODES_CONTAINED}</li>
 * <li>{@link #BEHAVIOR_NODES_TOUCHED}</li>
 * <li>{@link #BEHAVIOR_CONNECTIONS_CONTAINED}</li>
 * <li>{@link #BEHAVIOR_CONNECTIONS_TOUCHED}</li>
 * <li>{@link #BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS}</li>
 * <li>{@link #BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS}</li>
 * </ul>
 * 
 * By default, only edit parts whose figure's are on the primary layer that are
 * fully enclosed in the marquee selection rectangle will be considered (
 * {@link #BEHAVIOR_NODES_CONTAINED}).
 * 
 * Besides different marquee behaviors, the tool supports different modes, which
 * the user can influence by pressing modifier keys at the beginning of the drag
 * operation. I.e. if the SHIFT key is pressed at the beginning of the drag, the
 * enclosed items will be appended to the current viewer selection. If the MOD1
 * key is pressed at the beginning of the drag, the enclosed items will have
 * their selection state inverted.
 * 
 * @author ebordeau
 * @author dlee
 * @author rhudson
 * @author delee
 * @author msorens
 * @author pshah
 * @author anyssen
 */
public class MarqueeSelectionTool extends AbstractTool {

	class MarqueeRectangleFigure extends Figure {

		private static final int DELAY = 110; // animation delay in millisecond
		private int offset = 0;
		private boolean schedulePaint = true;

		/**
		 * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics)
		 */
		protected void paintFigure(Graphics graphics) {
			Rectangle bounds = getBounds().getCopy();
			graphics.translate(getLocation());

			graphics.setXORMode(true);
			graphics.setForegroundColor(ColorConstants.white());
			graphics.setBackgroundColor(ColorConstants.black());
			graphics.setLineStyle(Graphics.LINE_DOT);

			int[] points = new int[6];

			points[0] = 0 + offset;
			points[1] = 0;
			points[2] = bounds.width - 1;
			points[3] = 0;
			points[4] = bounds.width - 1;
			points[5] = bounds.height - 1;

			graphics.drawPolyline(points);

			points[0] = 0;
			points[1] = 0 + offset;
			points[2] = 0;
			points[3] = bounds.height - 1;
			points[4] = bounds.width - 1;
			points[5] = bounds.height - 1;

			graphics.drawPolyline(points);

			graphics.translate(getLocation().getNegated());

			if (schedulePaint) {
				Display.getCurrent().timerExec(DELAY, new Runnable() {
					public void run() {
						offset++;
						if (offset > 5)
							offset = 0;

						schedulePaint = true;
						repaint();
					}
				});
			}

			schedulePaint = false;
		}
	}

	/**
	 * This behavior selects connections that intersect the marquee rectangle.
	 * 
	 * @since 3.7
	 */
	public static final int BEHAVIOR_CONNECTIONS_CONTAINED = new Integer(6)
			.intValue();

	/**
	 * This behavior selects connections that intersect the marquee rectangle.
	 * 
	 * @since 3.1
	 */
	public static final int BEHAVIOR_CONNECTIONS_TOUCHED = new Integer(2)
			.intValue();

	/**
	 * This behavior selects nodes completely encompassed by the marquee
	 * rectangle. This is the default behavior for this tool.
	 * 
	 * @since 3.1
	 */
	public static final int BEHAVIOR_NODES_CONTAINED = new Integer(1)
			.intValue();

	/**
	 * This behavior selects nodes completely encompassed by the marquee
	 * rectangle, and all connections between those nodes.
	 * 
	 * @since 3.7
	 */
	public static final int BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS = new Integer(
			3).intValue();

	/**
	 * This behavior selects nodes that intersect the marquee rectangle.
	 * 
	 * @since 3.7
	 */
	public static final int BEHAVIOR_NODES_TOUCHED = new Integer(4).intValue();

	/**
	 * This behavior selects nodes that intersect the marquee rectangle.
	 * 
	 * @since 3.7
	 */
	public static final int BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS = new Integer(
			5).intValue();

	/**
	 * This behavior selects nodes completely encompassed by the marquee
	 * rectangle, and all connections between those nodes.
	 * 
	 * @since 3.1
	 * @deprecated use {@link #BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS}
	 *             instead.
	 */
	public static final int BEHAVIOR_NODES_AND_CONNECTIONS = BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS;

	static final int DEFAULT_MODE = 0;
	static final int TOGGLE_MODE = 1;
	static final int APPEND_MODE = 2;

	private static final Request MARQUEE_REQUEST = new Request(
			RequestConstants.REQ_SELECTION);

	/**
	 * The property to be used in
	 * {@link AbstractTool#setProperties(java.util.Map)} for
	 * {@link #setMarqueeBehavior(int)}.
	 */
	public static final Object PROPERTY_MARQUEE_BEHAVIOR = "marqueeBehavior"; //$NON-NLS-1$

	/**
	 * Constant defining the default marquee selection behavior.
	 * 
	 * @since 3.7
	 */
	public static final int DEFAULT_MARQUEE_BEHAVIOR = BEHAVIOR_NODES_CONTAINED;

	private Set allChildren = new HashSet();
	private int marqueeBehavior = DEFAULT_MARQUEE_BEHAVIOR;
	private Figure marqueeRectangleFigure;
	private int mode;

	private Collection selectedEditParts;

	private Request targetRequest;

	/**
	 * Creates a new MarqueeSelectionTool of default type
	 * {@link #BEHAVIOR_NODES_CONTAINED}.
	 */
	public MarqueeSelectionTool() {
		setDefaultCursor(SharedCursors.CROSS);
		setUnloadWhenFinished(false);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#applyProperty(java.lang.Object,
	 *      java.lang.Object)
	 */
	protected void applyProperty(Object key, Object value) {
		if (PROPERTY_MARQUEE_BEHAVIOR.equals(key)) {
			if (value instanceof Integer)
				setMarqueeBehavior(((Integer) value).intValue());
			return;
		}
		super.applyProperty(key, value);
	}

	/**
	 * Called from {@link #performMarqueeSelect()} to determine those
	 * {@link EditPart}s that are affected by the current marquee selection. In
	 * default and append mode, the edit parts returned here will become
	 * selected in the current viewer's new selection (which is calculated and
	 * set in {@link #performMarqueeSelect()}), while in toggle mode their
	 * selection state will be inverted.
	 * 
	 * Calculation is delegated to
	 * {@link #calculatePrimaryMarqueeSelectedEditParts()} and
	 * {@link #calculateSecondaryMarqueeSelectedEditParts(Collection)} to
	 * compute the set of marquee selected edit parts in a two step-process,
	 * where all directly affected edit parts are determined first, and those
	 * indirectly affected (related connections in case of
	 * {@link #BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS}, or
	 * {@link #BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS}) afterwards.
	 * 
	 * Clients may overwrite to customize the calculation of marquee selected
	 * edit parts.
	 * 
	 * @return A collection containing all edit parts that should be regarded as
	 *         being included in the current marquee selection, i.e. which
	 *         should get selected in default or append mode, and whose
	 *         selection state should get inverted in toggle mode.
	 * @since 3.7
	 */
	protected Collection calculateMarqueeSelectedEditParts() {
		Collection marqueeSelectedEditParts = new HashSet();
		marqueeSelectedEditParts
				.addAll(calculatePrimaryMarqueeSelectedEditParts());
		marqueeSelectedEditParts
				.addAll(calculateSecondaryMarqueeSelectedEditParts(marqueeSelectedEditParts));
		return marqueeSelectedEditParts;
	}

	/**
	 * Responsible of calculating those edit parts that should be regarded as
	 * directly affected by the current marquee selection. By default, the
	 * method calculates which edit parts are potential candidates based on the
	 * current marquee behavior and delegates to
	 * {@link #isMarqueeSelectable(GraphicalEditPart)} and
	 * {@link #isPrimaryMarqueeSelectedEditPart(GraphicalEditPart)} to decide
	 * whether the candidate is to be included in the marquee selection.
	 * 
	 * @return A {@link Collection} containing all {@link EditPart}s that should
	 *         be regarded as being directly affected by the current marquee
	 *         selection.
	 * @since 3.7
	 */
	private Collection calculatePrimaryMarqueeSelectedEditParts() {
		Collection editPartsToProcess = new HashSet();
		if (marqueeBehavior != BEHAVIOR_CONNECTIONS_CONTAINED
				&& marqueeBehavior != BEHAVIOR_CONNECTIONS_TOUCHED) {
			// process nodes
			editPartsToProcess.addAll(EditPartUtilities
					.getAllChildren((GraphicalEditPart) getCurrentViewer()
							.getRootEditPart()));
		}

		if (marqueeBehavior != BEHAVIOR_NODES_CONTAINED
				&& marqueeBehavior != BEHAVIOR_NODES_TOUCHED) {
			// process connections
			editPartsToProcess
					.addAll(EditPartUtilities
							.getAllNestedConnectionEditParts((GraphicalEditPart) getCurrentViewer()
									.getRootEditPart()));
		}

		// process all edit parts and determine which are affected by the
		// current marquee selection
		Collection marqueeSelectedEditParts = new ArrayList();
		for (Iterator iterator = editPartsToProcess.iterator(); iterator
				.hasNext();) {
			GraphicalEditPart editPart = (GraphicalEditPart) iterator.next();
			if (isMarqueeSelectable(editPart)
					&& isPrimaryMarqueeSelectedEditPart(editPart)) {
				marqueeSelectedEditParts.add(editPart);
			}
		}
		return marqueeSelectedEditParts;
	}

	/**
	 * Responsible of calculating those edit parts that should be regarded as
	 * being indirectly affected by the marquee selection. By default, the
	 * method calculates which edit parts are potential candidates based on the
	 * current marquee behavior and delegates to
	 * {@link #isMarqueeSelectable(GraphicalEditPart)} and
	 * {@link #isSecondaryMarqueeSelectedEditPart(Collection, EditPart)} to
	 * decide whether the candidate is to be included in the marquee selection.
	 * 
	 * @param directlyMarqueeSelectedEditParts
	 *            A collection containing those {@link EditPart}s that were
	 *            already identified as being directly affected by the marquee
	 *            selection
	 * @return A {@link Collection} containing all {@link EditPart}s that are
	 *         indirectly affected by the current marquee selection
	 * @since 3.7
	 */
	private Collection calculateSecondaryMarqueeSelectedEditParts(
			Collection directlyMarqueeSelectedEditParts) {

		Collection editPartsToProcess = new HashSet();
		for (Iterator iterator = directlyMarqueeSelectedEditParts.iterator(); iterator
				.hasNext();) {
			GraphicalEditPart marqueeSelectedEditPart = (GraphicalEditPart) iterator
					.next();
			editPartsToProcess.addAll(marqueeSelectedEditPart
					.getSourceConnections());
			editPartsToProcess.addAll(marqueeSelectedEditPart
					.getTargetConnections());
		}

		// process all edit parts and decide, whether they are indirectly
		// affected by marquee selection
		Collection secondaryMarqueeSelectedEditParts = new HashSet();
		for (Iterator iterator = editPartsToProcess.iterator(); iterator
				.hasNext();) {
			GraphicalEditPart editPart = (GraphicalEditPart) iterator.next();
			if (isSecondaryMarqueeSelectedEditPart(
					directlyMarqueeSelectedEditParts, editPart)) {
				secondaryMarqueeSelectedEditParts.add(editPart);
			}
		}
		return secondaryMarqueeSelectedEditParts;
	}

	private Request createTargetRequest() {
		return MARQUEE_REQUEST;
	}

	/**
	 * Erases feedback if necessary and puts the tool into the terminal state.
	 */
	public void deactivate() {
		if (isInState(STATE_DRAG_IN_PROGRESS)) {
			eraseMarqueeFeedback();
			eraseTargetFeedback();
		}
		super.deactivate();
		allChildren.clear();
		setState(STATE_TERMINAL);
	}

	private void eraseMarqueeFeedback() {
		if (marqueeRectangleFigure != null) {
			removeFeedback(marqueeRectangleFigure);
			marqueeRectangleFigure = null;
		}
	}

	private void eraseTargetFeedback() {
		if (selectedEditParts == null)
			return;
		Iterator oldEditParts = selectedEditParts.iterator();
		while (oldEditParts.hasNext()) {
			EditPart editPart = (EditPart) oldEditParts.next();
			editPart.eraseTargetFeedback(getTargetRequest());
		}
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
	 */
	protected String getCommandName() {
		return REQ_SELECTION;
	}

	/**
	 * Returns the current marquee selection rectangle.
	 * 
	 * @return A {@link Rectangle} representing the current marquee selection.
	 * @since 3.7
	 */
	protected Rectangle getCurrentMarqueeSelectionRectangle() {
		return new Rectangle(getStartLocation(), getLocation());
	}

	/**
	 * Returns the current selection mode, i.e. default, append, or toggle
	 * 
	 * @return on of {@link #DEFAULT_MODE}, {@link #APPEND_MODE}, or
	 *         {@link #TOGGLE_MODE}
	 * @since 3.7
	 */
	protected int getCurrentSelectionMode() {
		return mode;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
	 */
	protected String getDebugName() {
		return "Marquee Tool: " + marqueeBehavior;//$NON-NLS-1$
	}

	private IFigure getMarqueeFeedbackFigure() {
		if (marqueeRectangleFigure == null) {
			marqueeRectangleFigure = new MarqueeRectangleFigure();
			addFeedback(marqueeRectangleFigure);
		}
		return marqueeRectangleFigure;
	}

	private Request getTargetRequest() {
		if (targetRequest == null)
			targetRequest = createTargetRequest();
		return targetRequest;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
	 */
	protected boolean handleButtonDown(int button) {
		if (!isCurrentViewerGraphical())
			return true;
		if (button != 1) {
			setState(STATE_INVALID);
			handleInvalidInput();
		}
		if (stateTransition(STATE_INITIAL, STATE_DRAG_IN_PROGRESS)) {
			if (getCurrentInput().isModKeyDown(SWT.MOD1))
				setSelectionMode(TOGGLE_MODE);
			else if (getCurrentInput().isShiftKeyDown())
				setSelectionMode(APPEND_MODE);
			else
				setSelectionMode(DEFAULT_MODE);
		}
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int button) {
		if (stateTransition(STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) {
			eraseTargetFeedback();
			eraseMarqueeFeedback();
			performMarqueeSelect();
		}
		handleFinished();
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()
	 */
	protected boolean handleDragInProgress() {
		if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
			showMarqueeFeedback();
			eraseTargetFeedback();
			selectedEditParts = calculateMarqueeSelectedEditParts();
			showTargetFeedback();
		}
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleFocusLost()
	 */
	protected boolean handleFocusLost() {
		if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
			handleFinished();
			return true;
		}
		return false;
	}

	/**
	 * This method is called when mouse or keyboard input is invalid and erases
	 * the feedback.
	 * 
	 * @return <code>true</code>
	 */
	protected boolean handleInvalidInput() {
		eraseTargetFeedback();
		eraseMarqueeFeedback();
		return true;
	}

	/**
	 * Handles high-level processing of a key down event. KeyEvents are
	 * forwarded to the current viewer's {@link KeyHandler}, via
	 * {@link KeyHandler#keyPressed(KeyEvent)}.
	 * 
	 * @see AbstractTool#handleKeyDown(KeyEvent)
	 */
	protected boolean handleKeyDown(KeyEvent e) {
		if (super.handleKeyDown(e))
			return true;
		if (getCurrentViewer().getKeyHandler() != null)
			return getCurrentViewer().getKeyHandler().keyPressed(e);
		return false;
	}

	/**
	 * Decides whether the given edit part may potentially be included in the
	 * current marquee selection.
	 * 
	 * @param editPart
	 *            the {@link EditPart} of interest
	 * @return <code>true</code> if the given edit part may be included into the
	 *         marquee selection, <code>false</code> otherwise
	 * @since 3.7
	 */
	protected boolean isMarqueeSelectable(GraphicalEditPart editPart) {
		// IMPORTANT: MarqueeSelectionTool is not a TargetingTool, thus the
		// pre-selection does not depend on hit-testing. Therefore, the visible
		// state of the edit part's figure has to be taken into consideration as
		// well.
		return editPart.getTargetEditPart(MARQUEE_REQUEST) == editPart
				&& editPart.isSelectable()
				&& FigureUtilities.isNotFullyClipped(editPart.getFigure());
	}

	/**
	 * Determines which edit parts are directly affected by the current marquee
	 * selection. Calculation is performed by regarding the current marquee
	 * selection rectangle ( {@link #getCurrentMarqueeSelectionRectangle()}),
	 * taking into consideration the current marquee behavior (contained vs.
	 * touched) that was provided ( {@link #setMarqueeBehavior(int)} ).
	 * 
	 * @param editPart
	 *            the {@link EditPart} whose state is to be determined
	 * @return <code>true</code> if the {@link EditPart} should be regarded as
	 *         being included in the current marquee selection,
	 *         <code>false</code> otherwise.
	 * @since 3.7
	 */
	private boolean isPrimaryMarqueeSelectedEditPart(GraphicalEditPart editPart) {
		// figure bounds are used to determine if edit part is included in
		// selection
		IFigure figure = editPart.getFigure();
		Rectangle r = figure.getBounds().getCopy();
		figure.translateToAbsolute(r);

		boolean included = false;
		Rectangle marqueeSelectionRectangle = getCurrentMarqueeSelectionRectangle();
		if (editPart instanceof ConnectionEditPart) {
			if (marqueeBehavior == BEHAVIOR_CONNECTIONS_TOUCHED
					|| marqueeBehavior == BEHAVIOR_CONNECTIONS_CONTAINED) {
				if (marqueeSelectionRectangle.intersects(r)) {
					// children will contain ConnectionEditParts only in case
					// behavior is BEHAVIOR_CONNECTIONS_TOUCHED or
					// BEHAVIOR_CONNECTIONS_CONTAINED
					Rectangle relMarqueeRect = Rectangle.getSINGLETON();
					figure.translateToRelative(relMarqueeRect
							.setBounds(marqueeSelectionRectangle));
					if (marqueeBehavior == BEHAVIOR_CONNECTIONS_TOUCHED) {
						included = ((Connection) figure).getPoints()
								.intersects(relMarqueeRect);
					} else if (marqueeBehavior == BEHAVIOR_CONNECTIONS_CONTAINED) {
						included = relMarqueeRect
								.contains(((Connection) figure).getPoints()
										.getBounds());
					}
				}
			}
		} else {
			// otherwise children will only be 'node' edit parts
			if (marqueeBehavior == BEHAVIOR_NODES_TOUCHED
					|| marqueeBehavior == BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS) {
				included = marqueeSelectionRectangle.intersects(r);
			} else if (marqueeBehavior == BEHAVIOR_NODES_CONTAINED
					|| marqueeBehavior == BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS) {
				included = marqueeSelectionRectangle.contains(r);
			}
		}
		return included;
	}

	/**
	 * Determines which edit parts are indirectly affected by the current
	 * marquee selection through those edit parts being directly affected. In
	 * case of {@link #BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS} or
	 * {@link #BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS} marquee behavior,
	 * this method will be used to calculate the related connections after all
	 * respective nodes have been identified as primary selected edit parts.
	 * 
	 * @param directlyMarqueeSelectedEditParts
	 *            A collection of {@link EditPart}s which are regarded to be
	 *            directly included in the current marquee selection.
	 * @param editPart
	 *            the {@link EditPart} of concern
	 * @return <code>true</code> if the {@link EditPart} should be regarded as
	 *         being included in the current marquee selection,
	 *         <code>false</code> otherwise.
	 * @since 3.7
	 */
	private boolean isSecondaryMarqueeSelectedEditPart(
			Collection directlyMarqueeSelectedEditParts, EditPart editPart) {
		boolean included = false;
		if (editPart instanceof ConnectionEditPart
				&& (marqueeBehavior == BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS || marqueeBehavior == BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS)) {
			// connections are included, if related nodes are included
			ConnectionEditPart connection = (ConnectionEditPart) editPart;
			GraphicalEditPart source = (GraphicalEditPart) connection
					.getSource();
			GraphicalEditPart target = (GraphicalEditPart) connection
					.getTarget();
			boolean sourceIncludedInMarqueeSelection = directlyMarqueeSelectedEditParts
					.contains(source);
			boolean targetIncludedInMarqueeSelection = directlyMarqueeSelectedEditParts
					.contains(target);

			if (mode == DEFAULT_MODE) {
				// in default mode, select connection if source and
				// target are included in marqee selection
				included = sourceIncludedInMarqueeSelection
						&& targetIncludedInMarqueeSelection;
			} else if (mode == APPEND_MODE) {
				// in append mode, the current viewer selection is of interest
				// as well, so select connection if not already selected and
				// source and target are already selected or will get selected
				included = connection.getSelected() == EditPart.SELECTED_NONE
						&& (getCurrentViewer().getSelectedEditParts().contains(
								source) || sourceIncludedInMarqueeSelection)
						&& (getCurrentViewer().getSelectedEditParts().contains(
								target) || targetIncludedInMarqueeSelection);
			} else if (mode == TOGGLE_MODE) {
				if (connection.getSelected() == EditPart.SELECTED_NONE) {
					// connection is currently deselected, include it in the
					// marquee selection, i.e. select it, if one of
					// source or target will become selected in the new viewer
					// selection
					included = ((source.getSelected() == EditPart.SELECTED_NONE && sourceIncludedInMarqueeSelection) || (source
							.getSelected() != EditPart.SELECTED_NONE && !sourceIncludedInMarqueeSelection))
							&& ((target.getSelected() == EditPart.SELECTED_NONE && targetIncludedInMarqueeSelection) || (target
									.getSelected() != EditPart.SELECTED_NONE && !targetIncludedInMarqueeSelection));
				} else {
					// connection is currently selected, include it in marquee
					// selection, i.e. deselect it, if one of source or target
					// will become deselected in the new viewer selection
					included = (source.getSelected() != EditPart.SELECTED_NONE && sourceIncludedInMarqueeSelection)
							|| (target.getSelected() != EditPart.SELECTED_NONE && targetIncludedInMarqueeSelection);
				}
			}
		}
		return included;
	}

	/**
	 * MarqueeSelectionTool is only interested in GraphicalViewers, not
	 * TreeViewers.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#isViewerImportant(org.eclipse.gef.EditPartViewer)
	 */
	protected boolean isViewerImportant(EditPartViewer viewer) {
		return isCurrentViewerGraphical();
	}

	private boolean isCurrentViewerGraphical() {
		return getCurrentViewer() instanceof GraphicalViewer;
	}

	/**
	 * Calculates and sets a new viewer selection based on the current marquee
	 * selection.
	 * 
	 * By default, this method delegates to
	 * {@link #calculateMarqueeSelectedEditParts()} to obtain the set of edit
	 * parts, which should be regarded as being affected by the current marquee
	 * selection. It then calculates a new viewer selection based on the current
	 * selection state of all affected edit parts and the current selection mode
	 * of the tool ( {@link #getCurrentSelectionMode()}), as well as the current
	 * selection of the viewer (in case of APPEND mode), which is then passed to
	 * the current viewer.
	 * 
	 * @since 3.7
	 */
	protected void performMarqueeSelect() {
		// determine which edit parts are affected by the current marquee
		// selection
		Collection marqueeSelectedEditParts = calculateMarqueeSelectedEditParts();

		// calculate nodes/connections that are to be selected/deselected,
		// dependent on the current mode of the tool
		Collection editPartsToSelect = new LinkedHashSet();
		Collection editPartsToDeselect = new HashSet();
		for (Iterator iterator = marqueeSelectedEditParts.iterator(); iterator
				.hasNext();) {
			EditPart affectedEditPart = (EditPart) iterator.next();
			if (affectedEditPart.getSelected() == EditPart.SELECTED_NONE
					|| getCurrentSelectionMode() != TOGGLE_MODE)
				editPartsToSelect.add(affectedEditPart);
			else
				editPartsToDeselect.add(affectedEditPart);
		}

		// include the current viewer selection, if not in DEFAULT mode.
		if (getCurrentSelectionMode() != DEFAULT_MODE) {
			editPartsToSelect.addAll(getCurrentViewer().getSelectedEditParts());
			editPartsToSelect.removeAll(editPartsToDeselect);
		}

		getCurrentViewer().setSelection(
				new StructuredSelection(editPartsToSelect.toArray()));
	}

	/**
	 * Sets the type of parts that this tool will select. This method should
	 * only be invoked once: when the tool is being initialized.
	 * 
	 * @param type
	 *            {@link #BEHAVIOR_CONNECTIONS_TOUCHED} or
	 *            {@link #BEHAVIOR_CONNECTIONS_CONTAINED}
	 *            {@link #BEHAVIOR_NODES_TOUCHED} or
	 *            {@link #BEHAVIOR_NODES_CONTAINED} or
	 *            {@link #BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS} or
	 *            {@link #BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS}
	 * @since 3.1
	 */
	public void setMarqueeBehavior(int type) {
		if (type != BEHAVIOR_CONNECTIONS_TOUCHED
				&& type != BEHAVIOR_CONNECTIONS_CONTAINED
				&& type != BEHAVIOR_NODES_TOUCHED
				&& type != BEHAVIOR_NODES_TOUCHED_AND_RELATED_CONNECTIONS
				&& type != BEHAVIOR_NODES_CONTAINED
				&& type != BEHAVIOR_NODES_CONTAINED_AND_RELATED_CONNECTIONS)
			throw new IllegalArgumentException(
					"Invalid marquee behaviour specified."); //$NON-NLS-1$
		marqueeBehavior = type;
	}

	private void setSelectionMode(int mode) {
		this.mode = mode;
	}

	/**
	 * @see org.eclipse.gef.Tool#setViewer(org.eclipse.gef.EditPartViewer)
	 */
	public void setViewer(EditPartViewer viewer) {
		if (viewer == getCurrentViewer())
			return;
		super.setViewer(viewer);
		if (viewer instanceof GraphicalViewer)
			setDefaultCursor(SharedCursors.CROSS);
		else
			setDefaultCursor(SharedCursors.NO);
	}

	private void showMarqueeFeedback() {
		Rectangle rect = getCurrentMarqueeSelectionRectangle().getCopy();
		IFigure marqueeFeedbackFigure = getMarqueeFeedbackFigure();
		marqueeFeedbackFigure.translateToRelative(rect);
		marqueeFeedbackFigure.setBounds(rect);
		marqueeFeedbackFigure.validate();
	}

	private void showTargetFeedback() {
		for (Iterator itr = selectedEditParts.iterator(); itr.hasNext();) {
			EditPart editPart = (EditPart) itr.next();
			editPart.showTargetFeedback(getTargetRequest());
		}
	}

}
