/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2005, 2018 SAP AG.
 * 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:
 *    SAP AG - initial API, implementation and documentation
 *    mwenz - Bug 331715: Support for rectangular grids in diagrams
 *    mwenz - Bug 332964: Enable setting selection for non-EMF domain models and
 *                        when embedded into a multi-page editor
 *    mwenz - Bug 336075 - DiagramEditor accepts URIEditorInput
 *    mwenz - Bug 329523 - Add notification of DiagramTypeProvider after saving a diagram
 *    jpasch - Bug 323025 ActionBarContributor cleanup
 *    mwenz - Bug 345347 - There should be a way to not allow other plugins to contribute to the diagram context menu
 *    mwenz - Bug 346932 - Navigation history broken
 *    mwenz - Bug 356828 - Escaped diagram name is used as editor title
 *    mwenz - Bug 356218 - Added hasDoneChanges updates to update diagram feature
 *                         and called features via editor command stack to check it
 *    Felix Velasco (mwenz) - Bug 323351 - Enable to suppress/reactivate the speed buttons
 *    Bug 336488 - DiagramEditor API
 *    mwenz - Bug 367204 - Correctly return the added PE inAbstractFeatureProvider's addIfPossible method
 *    mwenz - Bug 324556 - Prevent invisible shapes to be selected to avoid IllegalArgumentException
 *    mwenz - Bug 372753 - save shouldn't (necessarily) flush the command stack
 *    mwenz - Bug 376008 - Iterating through navigation history causes exceptions
 *    Felix Velasco - mwenz - Bug 379788 - Memory leak in DefaultMarkerBehavior
 *    mwenz - Bug 387971 - Features cant't be invoked from contextMenu
 *    fvelasco - Bug 323349 - Enable external invocation of features
 *    mwenz - Bug 393113 - Auto-focus does not work for connections
 *    mwenz - Bug 396893 - Enable the registration of the drop target listeners configurable
 *    pjpaulin - Bug 352120 - Main implementation of DiagramEditor - API BREAKAGE HERE
 *    pjpaulin - Bug 352120 - Renamed from DiagramEditorImpl so that classes extending DiagramEditor do not break
 *    mwenz - Bug 394315 - Enable injecting behavior objects in DiagramEditor
 *    pjpaulin - Bug 405314 - Should be able to override DefaultBehavior implementation without configuration
 *    mwenz - Bug 430687 - UpdateBehaviour createEditingDomain should be able to access diagram input (sphinx compatibility)
 *    Hernan Gonzales (mwenz) - Bug 436601 - Race condition on save
 *    mwenz - Bug 407894 - Luna: After DiagramsInViews change graphical viewer is configured and initialized only by a workaround
 *    mwenz - Bug 531207 - Prepare removal of deprecated CommandStackListener GEF interface
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.graphiti.ui.editor;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.ui.URIEditorInput;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackEvent;
import org.eclipse.gef.commands.CommandStackEventListener;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.GraphicalEditor;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.SelectionSynchronizer;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.tb.IToolBehaviorProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.navigator.CommonNavigator;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

/**
 * This is the main class for the Graphiti diagram editor. It represents the
 * editor to Eclipse and therefore implements {@link IEditorPart}. The
 * implementation is based upon a GEF editor implementation (
 * {@link GraphicalEditorWithFlyoutPalette}) and enhances it with
 * Graphiti-specific stuff.<br>
 * This editor is registered as an Eclipse editor using the extension point
 * org.eclipse.ui.editors. Therefore the Eclipse standard methods can be used to
 * open a new diagram editor. The associated {@link IEditorInput} object is a
 * subclass of {@link DiagramEditorInput}, but using another type of input is
 * also ok as long as it can be adapted to an IFile that can be reolved within
 * the workspace of is a {@link URIEditorInput}. These types of input objects
 * will be converted to a corresponding {@link DiagramEditorInput} when the
 * editor is initialized (see {@link #init(IEditorSite, IEditorInput)}).<br>
 * Any clients extending this class should also contribute their editor to the
 * Eclipse editor extension point to gain full advantage of the Eclipse editor
 * integration of Graphiti.<br>
 * There are a lot of aspects this class needs to deal with; the larger aspects
 * are separated into other classes which share the lifecycle with the
 * {@link DiagramEditor} instance. This means they are instantiated when a
 * new diagram editor is created and exist until the editor is closed again.
 * There are default implementations for all of these aspects, see the
 * Default*Behavior classes in this package. The following aspects are
 * separated:
 * <ul>
 * <li>Markers: Handles everything about markers in the editor. See
 * {@link DefaultMarkerBehavior} for the default implementation. Override
 * {@link #createMarkerBehavior()} to change the default behavior.</li>
 * <li>Palette: Handles everything about the palette in the editor. See
 * {@link DefaultPaletteBehavior} for the default implementation. Override
 * {@link #createPaletteBehaviour()} to change the default behavior.</li>
 * <li>Persistence: Handles everything about loading, saving and the dirty state
 * in the editor. See {@link DefaultPersistencyBehavior} for the default
 * implementation. Override {@link #createPersistencyBehavior()} to change the
 * default behavior.</li>
 * <li>Refreshing: Handles everything about refreshing the editor (refreshing
 * means that the editor shows what's defined in the pictogram model). See
 * {@link DefaultRefreshBehavior} for the default implementation. Override
 * {@link #createRefreshBehavior()} to change the default behavior.</li>
 * <li>Update: Handles everything about updating the editor (updating means that
 * the pictogram model is updated to reflect any changes done to the domain
 * model - your business objects - or to the way objects shall be visualized).
 * See {@link DefaultMarkerBehavior} for the default implementation. Override
 * {@link #createMarkerBehavior()} to change the default behavior.</li>
 * </ul>
 * All the other aspects are dealt with directly within this class. One of the
 * larger aspects implemented here is selection handling, which would have been
 * awkward if separated out.
 * 
 * @since 0.10
 * 
 */
public class DiagramEditor extends GraphicalEditorWithFlyoutPalette implements IDiagramContainerUI,
		ITabbedPropertySheetPageContributor, IEditingDomainProvider, CommandStackEventListener {

	private String contributorId;
	private DiagramBehavior diagramBehavior;

	/**
	 * The ID of the {@link DiagramEditor} as it is registered with the
	 * org.eclipse.ui.editors extension point.
	 */
	public static final String DIAGRAM_EDITOR_ID = "org.eclipse.graphiti.ui.editor.DiagramEditor"; //$NON-NLS-1$

	/**
	 * Creates a new diagram editor and cares about the creation of the
	 * different behavior extensions by delegating to the various
	 * create*Behavior() methods.
	 */
	public DiagramEditor() {
		super();
	}

	/**
	 * Returns the associated {@link DiagramSupport} instance to this editor.
	 * 
	 * @return The associated {@link DiagramSupport} instance
	 * 
	 * @since 0.10
	 */
	public DiagramBehavior getDiagramBehavior() {
		return diagramBehavior;
	}

	// ------------------ Initializazion ---------------------------------------

	/**
	 * Does the initialization of the editor. The default implementation cares
	 * about:
	 * <ol>
	 * <li>converting the passed {@link IEditorInput} to a
	 * {@link DiagramEditorInput}. In case this fails, a
	 * {@link PartInitException} is thrown.</li>
	 * <li>creating the editing domain by delegating to the update behavior
	 * extension, see
	 * {@link DefaultUpdateBehavior#createEditingDomain(IDiagramEditorInput)}
	 * for details</li>
	 * <li>initializing the underlying GEF editor by delegating to super</li>
	 * <li>initializing the update behavior extension (the order is important
	 * here as this must happen after initializing the GEF editor!)</li>
	 * <li>triggering the migration of diagram data if necessary</li>
	 * </ol>
	 * Any clients overriding this method have to make sure that they they
	 * always call <code>super.init(site, input)</code>.
	 * 
	 * @see org.eclipse.ui.IEditorPart#init(IEditorSite, IEditorInput)
	 * @param site
	 *            the Eclipse {@link IEditorSite} that will host this editor
	 * @param input
	 *            the editor input that shall be used. Note that this method
	 *            will exchange the input instance in case it is no
	 *            {@link DiagramEditorInput}.
	 * 
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		diagramBehavior = createDiagramBehavior();
		diagramBehavior.setParentPart(this);
		diagramBehavior.initDefaultBehaviors();

		IDiagramEditorInput diagramEditorInput;
		if (input instanceof IDiagramEditorInput) {
			diagramEditorInput = (IDiagramEditorInput) input;
		} else {
			// Eclipse may call us with other inputs when a file is to be
			// opened. Try to convert this to a valid diagram input.
			diagramEditorInput = convertToDiagramEditorInput(input);
			if (diagramEditorInput == null) {
				throw new PartInitException(
						"No DiagramEditorInput instance is available but it is required. The method convertToDiagramEditorInput illegally returned null."); //$NON-NLS-1$
			}
		}

		diagramBehavior.getUpdateBehavior().createEditingDomain(diagramEditorInput);

		// The GEF GraphicalEditor init(...) functionality, adapted to provide a
		// nice error message to the user in case of an error when opening an
		// editor with e.g. an invalid diagram, see Bug 376008
		setSite(site);
		setInput((IEditorInput) diagramEditorInput);
		if (diagramBehavior.getEditorInitializationError() != null) {
			// In case of error simply show an primitive editor with a label
			return;
		}
		getCommandStack().addCommandStackEventListener(this);
		getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
		initializeActionRegistry();
		// ... End of GEF functionality taken over

		diagramBehavior.getUpdateBehavior().init();

		diagramBehavior.migrateDiagramModelIfNecessary();
		IContextService contextService = (IContextService) getSite().getService(IContextService.class);
		contextService.activateContext(getDiagramTypeProvider().getContextId());
	}

	/**
	 * Creates the behavior object that cares about the common (behavioral)
	 * coding shared between editors, views and other composites. See
	 * {@link DiagramBehavior} for details and the default implementation.
	 * Override to change the behavior.
	 * 
	 * @return a new instance of {@link DiagramBehavior}
	 * @since 0.10
	 */
	protected DiagramBehavior createDiagramBehavior() {
		return new DiagramBehavior(this);
	}

	/**
	 * Is called by the {@link #init(IEditorSite, IEditorInput)} method in case
	 * the {@link IEditorInput} instance passed is no {@link DiagramEditorInput}
	 * . This method should try to convert the passed input object to a
	 * {@link DiagramEditorInput} or throw an {@link PartInitException} in case
	 * the conversion can (or should) not be done for any reason. The default
	 * implementation uses the
	 * {@link EditorInputAdapter#adaptToDiagramEditorInput(IEditorInput)} method
	 * to do the conversion. Clients may adapt to do additional conversions or
	 * to prohibit any conversion by simply throwing a {@link PartInitException}
	 * .
	 * 
	 * @param input
	 *            the original input
	 * @return a {@link DiagramEditorInput} corresponding to the passed input
	 *         instance in case a conversion is possible. This method must not
	 *         return <code>null</code>, otherwise the editor initialization
	 *         will fail.
	 * @throws PartInitException
	 *             in case the passed input object cannot or should not be
	 *             converted to a {@link DiagramEditorInput} instance.
	 * 
	 * @since 0.9
	 */
	protected DiagramEditorInput convertToDiagramEditorInput(IEditorInput input) throws PartInitException {
		IEditorInput newInput = EditorInputAdapter.adaptToDiagramEditorInput(input);
		if (!(newInput instanceof IDiagramEditorInput)) {
			throw new PartInitException("Unknown editor input: " + input); //$NON-NLS-1$
		}
		return (DiagramEditorInput) newInput;
	}

	/**
	 * Sets the given {@link IEditorInput} object as the input for this editor.
	 * It must be of type {@link DiagramEditorInput} otherwise an
	 * {@link IllegalArgumentException} is thrown.<br>
	 * The default implementation here cares about loading the diagram from the
	 * EMF {@link Resource} the input points to, sets the ID of the
	 * {@link IDiagramTypeProvider} for the diagram given in the input,
	 * registers listeners (by delegating to
	 * {@link #registerDiagramResourceSetListener()} and
	 * {@link #registerBusinessObjectsListener()}) and does the refreshing of
	 * the editor UI.
	 * 
	 * @param input
	 *            the {@link DiagramEditorInput} instance to use within this
	 *            editor.
	 */
	protected void setInput(IEditorInput input) {
		super.setInput(input);
		if (!(input instanceof IDiagramEditorInput)) {
			throw new IllegalArgumentException("The IEditorInput has the wrong type: " + input.getClass()); //$NON-NLS-1$
		}
		diagramBehavior.setInput((IDiagramEditorInput) input);
	}

	/**
	 * Creates the UI of the editor by delegating to the
	 * <code>super.createPartControl</code> method. The default implementation
	 * here also registers the command stack listener to correctly reflect the
	 * dirty state of the editor.
	 */
	public void createPartControl(Composite parent) {
		if (diagramBehavior.getEditorInitializationError() != null) {
			diagramBehavior.createErrorPartControl(parent);
		} else {
			super.createPartControl(parent);
			diagramBehavior.addGefListeners();
		}
	}

	/**
	 * Creates the GraphicalViewer on the specified {@link Composite} and
	 * initializes it. This method needs to be implemented here to fulfill the
	 * interface of the underlying GEF editor but only delegates to
	 * {@link DiagramSupport#createGraphicalViewer(Composite)}.
	 * 
	 * @param parent
	 *            The parent composite
	 */
	protected void createGraphicalViewer(Composite parent) {
		diagramBehavior.createGraphicalViewer(parent);
	}

	/**
	 * Called to initialize the editor with its content. Here everything is
	 * done, which is dependent of the IConfigurationProviderInternal.
	 * 
	 * @see org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette#initializeGraphicalViewer()
	 * @since 0.10
	 */
	public void initializeGraphicalViewer() {

		super.initializeGraphicalViewer();
		diagramBehavior.initializeGraphicalViewer();

		// this will cause the ActionBarContributor to refresh with the
		// new actions (there is no specific refresh-action).
		if (getEditorSite().getActionBarContributor() != null)
			getEditorSite().getActionBarContributor().setActiveEditor(this);
	}

	/**
	 * Called to configure the editor, before it receives its content. The
	 * default-implementation is for example doing the following: configure the
	 * ZoomManager, registering Actions... Here everything is done, which is
	 * independent of the IConfigurationProviderInternal.
	 * 
	 * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
	 * @since 0.12
	 */
	public void configureGraphicalViewer() {
		super.configureGraphicalViewer();
		diagramBehavior.configureGraphicalViewer();
	}

	// ------------------- Dirty state -----------------------------------------

	/**
	 * Updates the UI to correctly reflect the dirty state of the editor. The
	 * default implementation does this by firing a
	 * {@link IEditorPart#PROP_DIRTY} property change.
	 * 
	 * @since 0.9
	 */
	public void updateDirtyState() {
		firePropertyChange(IEditorPart.PROP_DIRTY);
	}

	/**
	 * Called to perform the saving of the editor. The default implementation
	 * delegates via {@link DiagramSupport} to
	 * {@link DefaultPersistencyBehavior#saveDiagram(IProgressMonitor)}.
	 * 
	 * @param monitor
	 *            the Eclipse progress monitor to report progress with.
	 */
	public void doSave(IProgressMonitor monitor) {
		diagramBehavior.getPersistencyBehavior().saveDiagram(monitor);
		diagramBehavior.getUpdateBehavior().setResourceChanged(false);
	}

	/**
	 * Returns if the editor is currently dirty and needs to be saved or not.
	 * The default implementation delegates to {@link DiagramSupport#isDirty()}.
	 * 
	 * @return <code>true</code> in case the editor is dirty, <code>false</code>
	 *         otherwise.
	 */
	public boolean isDirty() {
		return diagramBehavior.isDirty();
	}

	// ---------------------- Palette --------------------------------------- //

	/**
	 * Delegates to the method (or the method in a subclass of)
	 * {@link DefaultPaletteBehavior#createPaletteViewerProvider()
	 * #createPaletteViewerProvider()} to create the
	 * {@link PaletteViewerProvider} used inside the GEF editor.
	 * 
	 * @return the {@link PaletteViewerProvider} to use
	 */
	protected final PaletteViewerProvider createPaletteViewerProvider() {
		return diagramBehavior.createPaletteViewerProvider();
	}

	/**
	 * Delegates to the method (or the method in a subclass of)
	 * {@link DefaultPaletteBehavior#getPalettePreferences()}. To change the
	 * palette override the behavior there.
	 * 
	 * @return the {@link PaletteViewerProvider} preferences to use.
	 */
	protected final FlyoutPreferences getPalettePreferences() {
		return diagramBehavior.getPalettePreferences();
	}

	/**
	 * Returns the {@link PaletteRoot} to use in the GEF editor by delegating to
	 * {@link DefaultPaletteBehavior#getPaletteRoot()}.
	 * 
	 * @return the {@link PaletteRoot} to use
	 */
	protected final PaletteRoot getPaletteRoot() {
		return diagramBehavior.getPaletteRoot();
	}

	// ---------------------- Refresh --------------------------------------- //

	/**
	 * Refreshes the editor title to show the name of the diagram
	 * 
	 * @since 0.9
	 */
	public void refreshTitle() {
		String name = getDiagramTypeProvider().getDiagramTitle();
		if (name == null || name.length() == 0) {
			name = getConfigurationElement().getAttribute("name"); //$NON-NLS-1$
		}
		if (name == null || name.length() == 0) {
			name = URI.decode(getDiagramTypeProvider().getDiagram().eResource().getURI().lastSegment());
		}
		setPartName(name);
	}

	/**
	 * Refreshes the tooltip displayed for the editor title tab according to
	 * what is returned in {@link #getTitleToolTip()}.
	 * 
	 * @since 0.9
	 */
	public void refreshTitleToolTip() {
		setTitleToolTip(getTitleToolTip());
	}

	// ====================== standard behavior ==============================

	/**
	 * Implements the Eclipse {@link IAdaptable} interface. This implementation
	 * first delegates to the {@link IToolBehaviorProvider#getAdapter(Class)}
	 * method and checks if something is returned. In case the return value is
	 * <code>null</code> it returns adapters for ZoomManager,
	 * IPropertySheetPage, Diagram, KeyHandler, SelectionSynchronizer and
	 * IContextButtonManager. It also delegates to the super implementation in
	 * {@link GraphicalEditorWithFlyoutPalette#getAdapter(Class)}.
	 * 
	 * @param type
	 *            the type to which shall be adapted
	 * @return the adapter instance
	 */
	public Object getAdapter(@SuppressWarnings("rawtypes") Class type) {
		Object returnObj = diagramBehavior.getAdapter(type);
		if (returnObj != null) {
			return returnObj;
		}
		if (type == SelectionSynchronizer.class) {
			return getSelectionSynchronizer();
		}
		return super.getAdapter(type);
	}

	/**
	 * Disposes this {@link DiagramEditor} instance and frees all used resources
	 * and clears all references. Also delegates to all the behavior extensions
	 * to also free their resources (e.g. and most important is the
	 * {@link TransactionalEditingDomain} held by the
	 * {@link DefaultPersistencyBehavior}. Always delegate to
	 * <code>super.dispose()</code> in case you override this method!
	 */
	public void dispose() {
		if (diagramBehavior != null) {
			diagramBehavior.disposeBeforeGefDispose();
		}

		RuntimeException exc = null;
		if (getEditDomain() != null) {
			// Avoid exception in case an error during editor initialization
			// happened
			try {
				super.dispose();
			} catch (RuntimeException e) {
				exc = e;
			}
		}

		if (diagramBehavior != null) {
			diagramBehavior.disposeAfterGefDispose();
		}

		if (exc != null) {
			throw exc;
		}
	}

	/**
	 * Sets the focus by delegating to the super class implementation in the GEF
	 * editor and additionally triggers a update of the diagram by delegating to
	 * {@link DefaultUpdateBehavior#handleActivate()}.
	 */
	public void setFocus() {
		if (getGraphicalViewer() == null) {
			return;
		}

		super.setFocus();
		diagramBehavior.getUpdateBehavior().handleActivate();
	}

	// ---------------------- Selection ------------------------------------- //

	/**
	 * Returns the {@link PictogramElement}s that are currently selected in the
	 * diagram editor.
	 * 
	 * @return an array of {@link PictogramElement}s.
	 * 
	 * @since 0.9
	 */
	public PictogramElement[] getSelectedPictogramElements() {
		return diagramBehavior.getSelectedPictogramElements();
	}

	/**
	 * Handles a selection changed event that is triggered by any selection
	 * source, e.g. a browser with "Link to Editor" enabled.<br>
	 * Checks if the currently active editor is a {@link MultiPageEditorPart}
	 * with an opened diagram editor inside, tries to find any
	 * {@link PictogramElement} for the objects in the selection and selects
	 * them in the diagram.<br>
	 * Note that in case of the {@link CommonNavigator} as event source, its
	 * editor linking mechanism must be enabled.
	 * 
	 * @param part
	 *            the source {@link IWorkbenchPart} that triggered the event
	 * @param selection
	 *            the new selection (mostly a {@link IStructuredSelection}
	 *            instance.
	 * 
	 * @since 0.9
	 */
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		// If not the active editor, ignore selection changed.
		boolean editorIsActive = getSite().getPage().isPartVisible(this);
		if (!editorIsActive) {
			// Check if we are a page of the active multi page editor
			IEditorPart activeEditor = getSite().getPage().getActiveEditor();
			if (activeEditor != null) {
				if (activeEditor instanceof MultiPageEditorPart) {
					Object selectedPage = ((MultiPageEditorPart) activeEditor).getAdapter(getClass());
					if (selectedPage instanceof DiagramEditor) {
						// Editor is active and diagram sub editor is its active
						// page
						editorIsActive = true;
					}
				}
			}
		}
		if (editorIsActive) {
			// long start = System.nanoTime();
			// this is where we should check the selection source (part)
			// * for CNF view the link flag must be obeyed
			// this would however require a dependency to
			// org.eclipse.ui.navigator
			if (part instanceof CommonNavigator) {
				if (!((CommonNavigator) part).isLinkingEnabled()) {
					return;
				}
			}
			// useful selection ??
			if (selection instanceof IStructuredSelection) {
				IStructuredSelection structuredSelection = (IStructuredSelection) selection;
				List<PictogramElement> peList = new ArrayList<PictogramElement>();
				// Collect all Pictogram Elements for all selected domain
				// objects into one list
				for (Iterator<?> iterator = structuredSelection.iterator(); iterator.hasNext();) {
					Object object = iterator.next();
					if (object instanceof EObject) {
						// Find the Pictogram Elements for the given domain
						// object via the standard link service
						List<PictogramElement> referencingPes = Graphiti.getLinkService().getPictogramElements(
								getDiagramTypeProvider().getDiagram(), (EObject) object);
						if (referencingPes.size() > 0) {
							peList.addAll(referencingPes);
						}
					} else {
						// For non-EMF domain objects use the registered
						// notification service for finding
						PictogramElement[] relatedPictogramElements = getDiagramTypeProvider().getNotificationService()
								.calculateRelatedPictogramElements(new Object[] { object });
						for (int i = 0; i < relatedPictogramElements.length; i++) {
							peList.add(relatedPictogramElements[i]);
						}
					}
				}

				// Do the selection in the diagram (in case there is something
				// to select)
				PictogramElement[] pes = null;
				if (peList.size() > 0) {
					pes = peList.toArray(new PictogramElement[peList.size()]);
				}
				if (pes != null && pes.length > 0) {
					selectPictogramElements(pes);
				}
			}
			/*
			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=387971: When
			 * embedding a diagram editor inside a multi page editor the
			 * registered actions were not updated. The fix was simply not to
			 * delegate to super.selectionChange where a check for the editor
			 * being active only checks for the main editor (GEF editor is not
			 * embeddable inside another editor) but to trigger the action
			 * update ourself when our checks say the diagram editor is active.
			 */
			updateActions(getSelectionActions());
		}

	}

	/**
	 * Selects the given {@link PictogramElement}s in the diagram.
	 * 
	 * @param pictogramElements
	 *            an array of {@link PictogramElement}s to select.
	 * @since 0.9
	 */
	public void selectPictogramElements(PictogramElement[] pictogramElements) {
		diagramBehavior.selectPictogramElements(pictogramElements);
	}

	/**
	 * Sets one {@link PictogramElement} for later selection.
	 * <p>
	 * The methods {@link #getPictogramElementsForSelection()},
	 * {@link #setPictogramElementForSelection(PictogramElement)},
	 * {@link #setPictogramElementsForSelection(PictogramElement[])} and
	 * {@link DiagramSupport#selectBufferedPictogramElements()} offer the
	 * possibility to use a deferred selection mechanism: via the setters,
	 * {@link PictogramElement}s can be stored for a selection operation that is
	 * triggered lateron during a general refresh via the method
	 * {@link DiagramSupport#selectBufferedPictogramElements()}. This mechanism
	 * is used e.g. in the Graphiti framework in direct editing to restore the
	 * previous selection, but can also be used by clients.
	 * 
	 * @param pictogramElement
	 *            the {@link PictogramElement} that shall be stored for later
	 *            selection
	 * @since 0.9
	 */
	public void setPictogramElementForSelection(PictogramElement pictogramElement) {
		diagramBehavior.setPictogramElementForSelection(pictogramElement);
	}

	/**
	 * Sets {@link PictogramElement}s for later selection.
	 * <p>
	 * The methods {@link #getPictogramElementsForSelection()},
	 * {@link #setPictogramElementForSelection(PictogramElement)},
	 * {@link #setPictogramElementsForSelection(PictogramElement[])} and
	 * {@link DiagramSupport#selectBufferedPictogramElements()} offer the
	 * possibility to use a deferred selection mechanism: via the setters,
	 * {@link PictogramElement}s can be stored for a selection operation that is
	 * triggered lateron during a general refresh via the method
	 * {@link DiagramSupport#selectBufferedPictogramElements()}. This mechanism
	 * is used e.g. in the Graphiti framework in direct editing to restore the
	 * previous selection, but can also be used by clients.
	 * 
	 * @param pictogramElements
	 *            the {@link PictogramElement}s that shall be stored for later
	 *            selection
	 * @since 0.9
	 */
	public void setPictogramElementsForSelection(PictogramElement pictogramElements[]) {
		diagramBehavior.setPictogramElementsForSelection(pictogramElements);
	}

	// ---------------------- Other ----------------------------------------- //

	/**
	 * Returns the ID for contributions in the tabbed property sheets by
	 * delegating to the method {@link IToolBehaviorProvider#getContributorId()}
	 * .
	 * 
	 * @return the contributor id as a {@link String}
	 * @since 0.9
	 */
	public String getContributorId() {

		if (contributorId == null) {
			IToolBehaviorProvider tbp = getToolBehaviorProvider();
			if (tbp != null) {
				contributorId = tbp.getContributorId();
			}
		}
		return contributorId;
	}

	/**
	 * Returns the {@link IDiagramTypeProvider} instance associated with this
	 * {@link DiagramEditor}. There is always a 1:1 relation between the editor
	 * and the provider.
	 * <p>
	 * Note that this is a pure delegation method. Overrides should happen in
	 * {@link DiagramBehavior}.
	 * 
	 * @return the associated {@link IDiagramTypeProvider} instance.
	 * 
	 * @since 0.9
	 */
	public IDiagramTypeProvider getDiagramTypeProvider() {
		return diagramBehavior.getDiagramTypeProvider();
	}

	/**
	 * Returns the GEF edit domain as needed for some of the feature
	 * functionality in Graphiti; simply a public rewrite of the GEF editor
	 * super method.
	 * 
	 * @return the {@link DefaultEditDomain} used in this editor
	 * @see GraphicalEditor#getEditDomain()
	 * 
	 * @since 0.9
	 */
	public DefaultEditDomain getEditDomain() {
		return super.getEditDomain();
	}

	/**
	 * Returns the GEF {@link GraphicalViewer} as it is needed in some Graphiti
	 * feature implementations. This is simply a public rewrite of the according
	 * super method.
	 * 
	 * @return the {@link GraphicalViewer} used within this editor instance
	 * @see GraphicalEditor#getGraphicalViewer()
	 */
	public GraphicalViewer getGraphicalViewer() {
		return super.getGraphicalViewer();
	}

	/**
	 * Returns the tooltip that shall be displayed when hovering over the editor
	 * title tab.
	 * 
	 * @return the tooltip as a {@link String}
	 */
	public String getTitleToolTip() {
		if (getDiagramTypeProvider() != null && getDiagramTypeProvider().getCurrentToolBehaviorProvider() != null) {
			IToolBehaviorProvider tbp = getDiagramTypeProvider().getCurrentToolBehaviorProvider();
			String titleToolTip = tbp.getTitleToolTip();
			if (titleToolTip != null) {
				return titleToolTip;
			}
		}
		return super.getTitleToolTip();
	}

	private IToolBehaviorProvider getToolBehaviorProvider() {
		IDiagramTypeProvider dtp = getDiagramTypeProvider();
		if (dtp != null) {
			return dtp.getCurrentToolBehaviorProvider();
		}
		return null;
	}

	/**
	 * Returns the EMF {@link TransactionalEditingDomain} used within this
	 * editor by delegating to the update behavior extension, by default
	 * {@link DefaultUpdateBehavior#getEditingDomain()}.
	 * 
	 * @return the {@link TransactionalEditingDomain} instance used in the
	 *         editor
	 * 
	 * @since 0.9
	 */
	public TransactionalEditingDomain getEditingDomain() {
		if (diagramBehavior != null) {
			return diagramBehavior.getEditingDomain();
		} else {
			return null;
		}
	}

	/**
	 * @since 0.10
	 */
	public IDiagramEditorInput getDiagramEditorInput() {
		return diagramBehavior.getInput();
	}

	/**
	 * Returns the {@link IWorkbenchPart} for this container. Since this editor
	 * itself is already a part the default implementation simply returns this.
	 * 
	 * @return This part
	 * @since 0.10
	 */
	public IWorkbenchPart getWorkbenchPart() {
		return this;
	}

	/**
	 * @since 0.10
	 */
	public void close() {
		getSite().getPage().closeEditor(this, false);
	}

	/* GEF methods that need to be part of the IGEFDiagramContainer interface. */

	/**
	 * @since 0.10
	 */
	public void setEditDomain(DefaultEditDomain editDomain) {
		super.setEditDomain(editDomain);
	}

	public ActionRegistry getActionRegistry() {
		return super.getActionRegistry();
	}

	@SuppressWarnings("rawtypes")
	public List getSelectionActions() {
		return super.getSelectionActions();
	}

	@Override
	public void commandStackChanged(EventObject event) {
		super.commandStackChanged(event);
	}

	/**
	 * @since 0.15
	 */
	@Override
	public void stackChanged(CommandStackEvent event) {
		if ((event.getDetail() & CommandStack.POST_MASK) != 0) {
			commandStackChanged(event);
		}
	}

	public void setGraphicalViewer(GraphicalViewer viewer) {
		super.setGraphicalViewer(viewer);
	}

	public void hookGraphicalViewer() {
		super.hookGraphicalViewer();
	}
}
