/*******************************************************************************
 * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * Anas Chakfeh - initial API and implementation
 * Eugen Neufeld - Refactoring
 * Alexandra Buzila - Refactoring
 * Johannes Faltermeier - integration with validation service
 * Christian W. Damus - bugs 543376, 545460, 527686, 548592, 552385
 ******************************************************************************/
package org.eclipse.emf.ecp.view.spi.treemasterdetail.ui.swt;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.inject.Inject;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecp.common.spi.ChildrenDescriptorCollector;
import org.eclipse.emf.ecp.edit.internal.swt.util.OverlayImageDescriptor;
import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.edit.spi.DeleteService;
import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.edit.spi.ReferenceService;
import org.eclipse.emf.ecp.ui.view.swt.ECPSWTViewRenderer;
import org.eclipse.emf.ecp.view.internal.swt.ContextMenuViewModelService;
import org.eclipse.emf.ecp.view.internal.treemasterdetail.ui.swt.Activator;
import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContextFactory;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeListener;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
import org.eclipse.emf.ecp.view.spi.model.VDiagnostic;
import org.eclipse.emf.ecp.view.spi.model.VView;
import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
import org.eclipse.emf.ecp.view.spi.swt.masterdetail.DetailViewCache;
import org.eclipse.emf.ecp.view.spi.swt.masterdetail.DetailViewManager;
import org.eclipse.emf.ecp.view.spi.swt.selection.IMasterDetailSelectionProvider;
import org.eclipse.emf.ecp.view.spi.swt.services.ECPSelectionProviderService;
import org.eclipse.emf.ecp.view.treemasterdetail.model.VTreeMasterDetail;
import org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.internal.RootObject;
import org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.internal.TreeMasterDetailSelectionManipulatorHelper;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.ui.action.ecp.CreateChildAction;
import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter;
import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.emfforms.common.Optional;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer;
import org.eclipse.emfforms.spi.swt.core.layout.GridDescriptionFactory;
import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription;
import org.eclipse.emfforms.spi.swt.core.ui.SWTValidationHelper;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.osgi.framework.FrameworkUtil;

/**
 * SWT Renderer for a {@link VTreeMasterDetail} element.
 *
 * @author Anas Chakfeh
 * @author Eugen Neufeld
 * @since 1.5
 *
 */
@SuppressWarnings("deprecation")
public class TreeMasterDetailSWTRenderer extends AbstractSWTRenderer<VTreeMasterDetail> {

	private static final String ENABLE_MULTI_EDIT = "enableMultiEdit"; //$NON-NLS-1$

	/**
	 * Default Constructor.
	 *
	 * @param vElement the view element to be rendered
	 * @param viewContext The view model context
	 * @param reportService the ReportService to use
	 * @since 1.6
	 */
	@Inject
	public TreeMasterDetailSWTRenderer(final VTreeMasterDetail vElement, final ViewModelContext viewContext,
		ReportService reportService) {

		super(vElement, viewContext, reportService);
	}

	/**
	 * The detail key passed to the view model context.
	 */
	public static final String DETAIL_KEY = DetailViewManager.DETAIL_PROPERTY;

	/**
	 * Menu separator ID for the group to which additional menu contributions are added in the
	 * tree's context menu.
	 */
	public static final String GLOBAL_ADDITIONS = "global_additions"; //$NON-NLS-1$

	/**
	 * Context key for the root.
	 */
	public static final String ROOT_KEY = "root"; //$NON-NLS-1$

	private SWTGridDescription rendererGridDescription;

	private Font detailsFont;
	private Color titleColor;
	private Font titleFont;
	private Color headerBgColor;
	private TreeViewer treeViewer;

	private ScrolledComposite rightPanel;

	private Composite container;

	private Composite rightPanelContainerComposite;

	private ModelChangeListener domainModelListener;
	private ViewModelContext childContext;
	private DetailViewManager detailManager;

	/**
	 * @author jfaltermeier
	 *
	 */
	private final class MasterTreeContextMenuListener implements IMenuListener {
		private final EditingDomain editingDomain;
		private final TreeViewer treeViewer;
		private final ChildrenDescriptorCollector childrenDescriptorCollector;
		private final List<MasterDetailAction> menuActions;

		/**
		 * @param editingDomain
		 * @param treeViewer
		 * @param childrenDescriptorCollector
		 * @param menuActions
		 */
		private MasterTreeContextMenuListener(EditingDomain editingDomain, TreeViewer treeViewer,
			ChildrenDescriptorCollector childrenDescriptorCollector, List<MasterDetailAction> menuActions) {
			this.editingDomain = editingDomain;
			this.treeViewer = treeViewer;
			this.childrenDescriptorCollector = childrenDescriptorCollector;
			this.menuActions = menuActions;
		}

		@Override
		public void menuAboutToShow(IMenuManager manager) {
			if (getVElement().isEffectivelyReadonly() || !getVElement().isEffectivelyEnabled()) {
				return;
			}
			if (treeViewer.getSelection().isEmpty()) {
				fillMenu(null, manager);
				return;
			}
			final EObject root = ((RootObject) treeViewer.getInput()).getRoot();

			if (treeViewer.getSelection() instanceof IStructuredSelection) {
				final IStructuredSelection selection = (IStructuredSelection) treeViewer.getSelection();

				if (selection.size() == 1 && EObject.class.isInstance(selection.getFirstElement())) {
					final EObject eObject = (EObject) selection.getFirstElement();
					final EditingDomain domain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
					if (domain == null) {
						return;
					}
					final Collection<?> descriptors = childrenDescriptorCollector.getDescriptors(eObject);
					fillContextMenu(manager, descriptors, editingDomain, eObject);
				}
				if (!selection.toList().contains(root)) {
					manager.add(new Separator(GLOBAL_ADDITIONS));
					addDeleteActionToContextMenu(editingDomain, manager, selection);
				}
				manager.add(new Separator());

				if (selection.getFirstElement() != null && EObject.class.isInstance(selection.getFirstElement())) {
					final EObject selectedObject = (EObject) selection.getFirstElement();

					fillMenu(selectedObject, manager);
				}
			}
		}

		private void fillMenu(final EObject selectedObject, IMenuManager manager) {
			for (final MasterDetailAction menuAction : menuActions) {
				if (menuAction.shouldShow(selectedObject)) {
					final Action newAction = new Action() {
						@Override
						public void run() {
							super.run();
							menuAction.execute(selectedObject);
						}
					};

					newAction.setImageDescriptor(ImageDescriptor.createFromURL(FrameworkUtil.getBundle(
						menuAction.getClass())
						.getResource(menuAction.getImagePath())));
					newAction.setText(menuAction.getLabel());

					manager.add(newAction);
				}
			}
		}
	}

	@Override
	protected void dispose() {
		rendererGridDescription = null;
		if (detailManager != null) {
			detailManager.dispose();
		}
		childContext = null;
		if (getViewModelContext() != null && domainModelListener != null) {
			getViewModelContext().unregisterDomainChangeListener(domainModelListener);
		}
		domainModelListener = null;
		if (treeViewer != null) {
			treeViewer.setInput(null);
		}
		super.dispose();
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#getGridDescription(SWTGridDescription)
	 */
	@Override
	public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) {
		if (rendererGridDescription == null) {
			rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 1, this);
		}
		return rendererGridDescription;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#renderControl(org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell,
	 *      org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control renderControl(SWTGridCell cell, Composite parent) throws NoRendererFoundException,
		NoPropertyDescriptorFoundExeption {

		/* The tree's composites */
		final Composite form = createMasterDetailForm(parent);

		createHeader(form);

		final SashForm sash = createSash(form);

		final Composite masterPanel = createMasterPanel(sash);

		createRightPanelContent(sash);

		sash.setWeights(new int[] { 1, 3 });

		createMasterTree(masterPanel);

		if (hasContextMenu()) {
			registerControlAsContextMenuReceiver();
		}
		form.layout(true);
		return form;
	}

	private void registerControlAsContextMenuReceiver() {
		if (!getViewModelContext().hasService(ContextMenuViewModelService.class)) {
			return;
		}
		final ContextMenuViewModelService service = getViewModelContext().getService(
			ContextMenuViewModelService.class);

		if (service != null) {
			service.setParentControl(treeViewer.getTree());
			service.registerContextMenu();
		}
	}

	/**
	 * Creates the sashform for the master detail colums.
	 *
	 * @param parent the parent
	 * @return the sash
	 */
	protected SashForm createSash(Composite parent) {
		/* THe contents of the composite */
		final Composite sashComposite = new Composite(parent, SWT.FILL);
		final GridLayout sashLayout = GridLayoutFactory.fillDefaults().create();
		sashLayout.marginWidth = 5;
		sashComposite.setLayout(sashLayout);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(sashComposite);

		final SashForm sash = new SashForm(sashComposite, SWT.HORIZONTAL);

		sash.setBackground(parent.getBackground());
		GridLayoutFactory.fillDefaults().numColumns(2).equalWidth(false).applyTo(sash);
		GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(sash);
		sash.setSashWidth(5);
		return sash;
	}

	/**
	 * Create the parent of the master detail form.
	 *
	 * @param parent the parent
	 * @return the composite
	 */
	protected Composite createMasterDetailForm(Composite parent) {
		final Composite form = new Composite(parent, SWT.BORDER);
		final GridLayout layout = GridLayoutFactory.fillDefaults().create();

		form.setLayout(layout);
		form.setBackgroundMode(SWT.INHERIT_FORCE);
		// form.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
		return form;
	}

	/**
	 * Creates the tree viewer for the master.
	 *
	 * @param masterPanel the parent
	 * @return the tree viewer
	 */
	protected TreeViewer createMasterTree(final Composite masterPanel) {
		final EObject modelElement = getViewModelContext().getDomainModel();
		final EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(modelElement);

		final ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(new AdapterFactory[] {
			new CustomReflectiveItemProviderAdapterFactory(),
			new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE) });

		final AdapterFactoryContentProvider adapterFactoryContentProvider = new AdapterFactoryContentProvider(
			adapterFactory) {

			@Override
			public Object[] getElements(Object object) {
				return new Object[] { ((RootObject) object).getRoot() };
			}
		};
		final AdapterFactoryLabelProvider labelProvider = new TreeMasterDetailLabelProvider(adapterFactory);

		treeViewer = new TreeViewer(masterPanel);

		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).hint(100, SWT.DEFAULT)
			.applyTo(treeViewer.getTree());

		treeViewer.setContentProvider(adapterFactoryContentProvider);
		treeViewer.setLabelProvider(getLabelProvider(labelProvider));
		treeViewer.setAutoExpandLevel(2); // top level element is expanded, but not the children
		treeViewer.setInput(new RootObject(modelElement));

		domainModelListener = new ModelChangeAddRemoveListener() {

			@Override
			public void notifyChange(ModelChangeNotification notification) {
				// nothing to do here
			}

			// workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=27480
			// the treeviewer doesn't autoexpand on refresh
			@Override
			public void notifyAdd(Notifier notifier) {
				if (isRenderingFinished()) {
					treeViewer.expandToLevel(notifier, 1);
				}
			}

			@Override
			public void notifyRemove(Notifier notifier) {
				// If an element is deleted, reset the selection to the root node
				if (childContext != null && notifier == childContext.getDomainModel()) {
					treeViewer.setSelection(new StructuredSelection(getViewModelContext().getDomainModel()));
				}
			}
		};
		getViewModelContext().registerDomainChangeListener(domainModelListener);

		// Drag and Drop
		if (hasDnDSupport()) {
			addDragAndDropSupport(modelElement, treeViewer, editingDomain);
		}

		// Selection Listener
		final TreeMasterViewSelectionListener treeMasterViewSelectionListener = new TreeMasterViewSelectionListener();
		treeViewer.addSelectionChangedListener(treeMasterViewSelectionListener);
		treeViewer.setSelection(new StructuredSelection(modelElement));
		if (hasContextMenu()) {
			fillContextMenu(treeViewer, editingDomain);
		}

		treeViewer.getTree().addDisposeListener(new DisposeListener() {

			@Override
			public void widgetDisposed(DisposeEvent event) {
				adapterFactoryContentProvider.dispose();
				labelProvider.dispose();
				adapterFactory.dispose();
				if (titleFont != null) {
					titleFont.dispose();
				}
				if (detailsFont != null) {
					detailsFont.dispose();
				}
				if (titleColor != null) {
					titleColor.dispose();
				}
				if (headerBgColor != null) {
					headerBgColor.dispose();
				}
				treeViewer.removeSelectionChangedListener(treeMasterViewSelectionListener);
			}
		});

		// Register my tree viewer as the selection provider for my element
		final ECPSelectionProviderService sps = getViewModelContext().getService(ECPSelectionProviderService.class);
		final IMasterDetailSelectionProvider mdSelectionProvider = sps.createMasterDetailSelectionProvider(treeViewer,
			() -> rightPanel);
		sps.registerSelectionProvider(getVElement(), mdSelectionProvider);

		return treeViewer;
	}

	/**
	 * Return true if a context menu should be shown in the tree.
	 *
	 * @return true if a context menu should be shown, false otherwise
	 */
	protected boolean hasContextMenu() {
		return !getVElement().isEffectivelyReadonly();
	}

	/**
	 * Return true if the tree should support DnD.
	 *
	 * @return true if DnD should be supported , false otherwise
	 */
	protected boolean hasDnDSupport() {
		return !getVElement().isEffectivelyReadonly();
	}

	/**
	 * Returns the label provider.
	 *
	 * @param adapterFactoryLabelProvider the adaper factory label provider
	 * @return the label provider to use for the tree
	 */
	protected ILabelProvider getLabelProvider(final AdapterFactoryLabelProvider adapterFactoryLabelProvider) {
		return adapterFactoryLabelProvider;
	}

	/**
	 * Creates the composite for the master panel.
	 *
	 * @param sash the parent
	 * @return the composite
	 */
	protected Composite createMasterPanel(final SashForm sash) {
		final Composite leftPanel = new Composite(sash, SWT.NONE);
		leftPanel.setLayout(GridLayoutFactory.fillDefaults().create());
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(leftPanel);
		// leftPanel.setBackground(sash.getBackground());
		leftPanel.setBackgroundMode(SWT.INHERIT_FORCE);
		return leftPanel;
	}

	/**
	 * Adds the header to a parent composite.
	 *
	 * @param parent the parent
	 */
	protected void createHeader(Composite parent) {
		final Composite headerComposite = new Composite(parent, SWT.NONE);
		final GridLayout headerLayout = GridLayoutFactory.fillDefaults().create();
		headerComposite.setLayout(headerLayout);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(headerComposite);
		headerBgColor = new Color(parent.getDisplay(), new RGB(220, 240, 247));
		headerComposite.setBackground(headerBgColor);

		final EObject modelElement = getViewModelContext().getDomainModel();
		final EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(modelElement);

		/* The header of the composite */
		if (modelElement.eContainer() == null && !DynamicEObjectImpl.class.isInstance(modelElement)) {

			final Composite header = getPageHeader(headerComposite);
			final List<Action> actions = readToolbarActions(modelElement, editingDomain);

			final ToolBar toolBar = new ToolBar(header, SWT.FLAT | SWT.RIGHT);
			final FormData formData = new FormData();
			formData.right = new FormAttachment(100, 0);
			toolBar.setLayoutData(formData);
			toolBar.layout();
			final ToolBarManager toolBarManager = new ToolBarManager(toolBar);

			/* Add actions to header */
			for (final Action action : actions) {
				toolBarManager.add(action);
			}
			toolBarManager.update(true);
			header.layout();

		}
	}

	private Composite getPageHeader(Composite parent) {
		final Composite header = new Composite(parent, SWT.FILL);
		final FormLayout layout = new FormLayout();
		layout.marginHeight = 5;
		layout.marginWidth = 5;
		header.setLayout(layout);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(header);

		header.setBackground(parent.getBackground());

		final Label titleImage = new Label(header, SWT.FILL);
		final ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(Activator.getDefault()
			.getBundle()
			.getResource("icons/view.png")); //$NON-NLS-1$
		titleImage.setImage(new Image(parent.getDisplay(), imageDescriptor.getImageData()));
		final FormData titleImageData = new FormData();
		final int imageOffset = -titleImage.computeSize(SWT.DEFAULT, SWT.DEFAULT).y / 2;
		titleImageData.top = new FormAttachment(50, imageOffset);
		titleImageData.left = new FormAttachment(0, 10);
		titleImage.setLayoutData(titleImageData);

		final Label title = new Label(header, SWT.WRAP);
		title.setText("View Editor"); //$NON-NLS-1$
		titleFont = new Font(title.getDisplay(), getDefaultFontName(title), 12, SWT.BOLD);
		title.setFont(titleFont);
		title.setForeground(getTitleColor(parent));
		final int titleHeight = title.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
		final FormData titleData = new FormData();
		titleData.left = new FormAttachment(titleImage, 5, SWT.DEFAULT);
		titleData.top = new FormAttachment(50, -titleHeight / 2);
		title.setLayoutData(titleData);

		return header;

	}

	private Color getTitleColor(Composite parent) {
		if (titleColor == null) {
			titleColor = new Color(parent.getDisplay(), new RGB(25, 76, 127));
		}
		return titleColor;
	}

	/**
	 * Creates the composite holding the details.
	 *
	 * @param parent the parent
	 * @return the right panel/detail composite
	 */
	protected ScrolledComposite createRightPanelContent(Composite parent) {
		rightPanel = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
		rightPanel.setShowFocusedControl(true);
		rightPanel.setExpandVertical(true);
		rightPanel.setExpandHorizontal(true);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(rightPanel);
		rightPanel.setLayout(GridLayoutFactory.fillDefaults().create());
		rightPanel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));

		container = new Composite(rightPanel, SWT.FILL);
		container.setLayout(GridLayoutFactory.fillDefaults().create());
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).applyTo(container);
		container.setBackground(rightPanel.getBackground());

		/* The header */
		final Composite header = new Composite(container, SWT.FILL);
		final GridLayout headerLayout = GridLayoutFactory.fillDefaults().create();
		header.setLayout(headerLayout);
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, false).applyTo(header);
		header.setBackground(rightPanel.getBackground());

		final Label label = new Label(header, SWT.WRAP);
		label.setText("Details"); //$NON-NLS-1$
		detailsFont = new Font(label.getDisplay(), getDefaultFontName(label), 10, SWT.BOLD);
		label.setFont(detailsFont);
		label.setForeground(getTitleColor(parent));
		label.setBackground(header.getBackground());

		rightPanelContainerComposite = new Composite(container, SWT.FILL);
		rightPanelContainerComposite.setLayout(GridLayoutFactory.fillDefaults().create());
		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).grab(true, true)
			.applyTo(rightPanelContainerComposite);
		rightPanelContainerComposite.setBackground(rightPanel.getBackground());

		rightPanel.setContent(container);

		rightPanel.layout();
		container.layout();

		final Point point = container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		rightPanel.setMinSize(point);

		detailManager = new DetailViewManager(rightPanelContainerComposite);
		detailManager.setCache(DetailViewCache.createCache(getViewModelContext()));
		detailManager.layoutDetailParent(rightPanelContainerComposite);

		return rightPanel;
	}

	@Override
	protected String getDefaultFontName(Control control) {
		return control.getDisplay().getSystemFont().getFontData()[0].getName();
	}

	private List<Action> readToolbarActions(EObject modelElement, final EditingDomain editingDomain) {
		final List<Action> actions = new ArrayList<Action>();
		final IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		if (extensionRegistry == null) {
			return actions;
		}
		if (!VView.class.isInstance(modelElement)) {
			return actions;
		}
		final VView view = (VView) modelElement;

		final IConfigurationElement[] controls = extensionRegistry
			.getConfigurationElementsFor("org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.masterDetailActions"); //$NON-NLS-1$
		for (final IConfigurationElement e : controls) {
			try {
				final String location = e.getAttribute("location"); //$NON-NLS-1$
				if (!location.equals("toolbar")) { //$NON-NLS-1$
					continue;
				}

				final String label = e.getAttribute("label"); //$NON-NLS-1$
				final String imagePath = e.getAttribute("imagePath"); //$NON-NLS-1$
				final MasterDetailAction command = (MasterDetailAction) e.createExecutableExtension("command"); //$NON-NLS-1$
				final Action newAction = new Action() {
					@Override
					public void run() {
						super.run();
						command.execute(view);
					}
				};

				newAction.setImageDescriptor(ImageDescriptor.createFromURL(FrameworkUtil.getBundle(command.getClass())
					.getResource(imagePath)));
				newAction.setText(label);
				actions.add(newAction);
			} catch (final CoreException e1) {
				e1.printStackTrace();
			}
		}
		return actions;
	}

	private void addDragAndDropSupport(final EObject modelElement, final TreeViewer treeViewer,
		EditingDomain editingDomain) {

		final int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
		final Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance() };
		treeViewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(treeViewer));
		final EditingDomainViewerDropAdapter editingDomainViewerDropAdapter = new EditingDomainViewerDropAdapter(
			editingDomain,
			treeViewer);
		treeViewer.addDropSupport(dndOperations, transfers, editingDomainViewerDropAdapter);
	}

	/**
	 * @param treeViewer
	 * @param editingDomain
	 */
	private void fillContextMenu(final TreeViewer treeViewer, final EditingDomain editingDomain) {
		final ChildrenDescriptorCollector childrenDescriptorCollector = new ChildrenDescriptorCollector();
		final List<MasterDetailAction> menuActions = readMasterDetailActions();
		final MenuManager menuMgr = new MenuManager();
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new MasterTreeContextMenuListener(editingDomain, treeViewer,
			childrenDescriptorCollector, menuActions));
		final Menu menu = menuMgr.createContextMenu(treeViewer.getControl());
		treeViewer.getControl().setMenu(menu);
	}

	/**
	 * Returns a list of all {@link MasterDetailAction MasterDetailActions} which shall be displayed in the context menu
	 * of the master treeviewer.
	 *
	 * @return the actions
	 */
	protected List<MasterDetailAction> readMasterDetailActions() {
		final List<MasterDetailAction> commands = new ArrayList<MasterDetailAction>();
		final IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
		if (extensionRegistry == null) {
			return commands;
		}

		final IConfigurationElement[] controls = extensionRegistry
			.getConfigurationElementsFor("org.eclipse.emf.ecp.view.treemasterdetail.ui.swt.masterDetailActions"); //$NON-NLS-1$
		for (final IConfigurationElement e : controls) {
			try {
				final String location = e.getAttribute("location"); //$NON-NLS-1$
				if (!location.equals("menu")) { //$NON-NLS-1$
					continue;
				}
				final String label = e.getAttribute("label"); //$NON-NLS-1$
				final String imagePath = e.getAttribute("imagePath"); //$NON-NLS-1$
				final MasterDetailAction command = (MasterDetailAction) e.createExecutableExtension("command"); //$NON-NLS-1$
				command.setLabel(label);
				command.setImagePath(imagePath);
				command.setTreeViewer(treeViewer);

				commands.add(command);

			} catch (final CoreException ex) {
				Activator.getDefault().getLog().log(
					new Status(IStatus.ERROR, Activator.getDefault().getBundle().getSymbolicName(),
						ex.getMessage(), ex));
			}
		}

		return commands;

	}

	/**
	 * @param manager The menu manager responsible for the context menu
	 * @param descriptors The menu items to be added
	 * @param domain The editing domain of the current EObject
	 * @param eObject The model element
	 */
	private void fillContextMenu(IMenuManager manager, Collection<?> descriptors, final EditingDomain domain,
		final EObject eObject) {
		for (final Object descriptor : descriptors) {

			final CommandParameter cp = (CommandParameter) descriptor;
			if (!CommandParameter.class.isInstance(descriptor)) {
				continue;
			}
			if (cp.getEReference() == null) {
				continue;
			}
			if (!cp.getEReference().isMany() && eObject.eIsSet(cp.getEStructuralFeature())) {
				continue;
			} else if (cp.getEReference().isMany() && cp.getEReference().getUpperBound() != -1
				&& cp.getEReference().getUpperBound() <= ((List<?>) eObject.eGet(cp.getEReference())).size()) {
				continue;
			}

			manager.add(new CreateChildAction(domain, new StructuredSelection(eObject), descriptor) {
				@Override
				public void run() {
					super.run();

					final EReference reference = ((CommandParameter) descriptor).getEReference();
					// if (!reference.isContainment()) {
					// domain.getCommandStack().execute(
					// AddCommand.create(domain, eObject.eContainer(), null, cp.getEValue()));
					// }

					domain.getCommandStack().execute(
						AddCommand.create(domain, eObject, reference, cp.getEValue()));
				}
			});
		}

	}

	/**
	 * @param editingDomain
	 * @param manager
	 * @param selection
	 */
	private void addDeleteActionToContextMenu(final EditingDomain editingDomain, final IMenuManager manager,
		final IStructuredSelection selection) {

		final Action deleteAction = new Action() {
			@SuppressWarnings("unchecked")
			@Override
			public void run() {
				super.run();
				DeleteService deleteService = getViewModelContext().getService(DeleteService.class);
				if (deleteService == null) {
					/*
					 * #getService(Class<?>) will report to the reportservice if it could not be found
					 * Use Default
					 */
					deleteService = new EMFDeleteServiceImpl();
				}
				deleteService.deleteElements(selection.toList());
			}
		};
		final String deleteImagePath = "icons/delete.png";//$NON-NLS-1$
		deleteAction.setImageDescriptor(ImageDescriptor.createFromURL(Activator.getDefault()
			.getBundle()
			.getResource(deleteImagePath)));
		deleteAction.setText("Delete"); //$NON-NLS-1$
		deleteAction.setEnabled(ConditionalDeleteService.getDeleteService(getViewModelContext()).canDelete(selection.toList()));
		manager.add(deleteAction);
	}

	/**
	 * Allows to manipulate the view context for the selected element that is about to be rendered.
	 *
	 * @param viewContext the view context.
	 */
	protected void manipulateViewContext(ViewModelContext viewContext) {
		// do nothing
	}

	/**
	 *
	 * @author Anas Chakfeh
	 *         This class is responsible for handling selection changed events which happen on the tree
	 *
	 */
	private class TreeMasterViewSelectionListener implements ISelectionChangedListener {

		/**
		 * Adapter which listens to changes and delegates the notification to other EObjects.
		 *
		 * @author Eugen Neufeld
		 *
		 */
		private final class MultiEditAdapter extends AdapterImpl {
			private final EObject dummy;
			private final Set<EObject> selectedEObjects;

			private MultiEditAdapter(EObject dummy, Set<EObject> selectedEObjects) {
				this.dummy = dummy;
				this.selectedEObjects = selectedEObjects;
			}

			@Override
			public void notifyChanged(Notification notification) {
				final EditingDomain editingDomain = AdapterFactoryEditingDomain
					.getEditingDomainFor(getViewModelContext().getDomainModel());
				if (dummy.eClass().getEAllAttributes().contains(notification.getFeature())) {
					final CompoundCommand cc = new CompoundCommand();
					for (final EObject selected : selectedEObjects) {
						Command command = null;
						switch (notification.getEventType()) {
						case Notification.SET:
							command = SetCommand.create(editingDomain, selected,
								notification.getFeature(), notification.getNewValue());
							break;
						case Notification.UNSET:
							command = SetCommand.create(editingDomain, selected,
								notification.getFeature(), SetCommand.UNSET_VALUE);
							break;
						case Notification.ADD:
						case Notification.ADD_MANY:
							command = AddCommand.create(editingDomain, selected,
								notification.getFeature(), notification.getNewValue());
							break;
						case Notification.REMOVE:
						case Notification.REMOVE_MANY:
							command = DeleteCommand.create(editingDomain, notification.getOldValue());
							break;
						default:
							continue;
						}
						cc.append(command);
					}
					editingDomain.getCommandStack().execute(cc);
				}
			}
		}

		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
			final Object treeSelected = getSelection(selection);

			detailManager.cacheCurrentDetail();
			cleanCustomOnSelectionChange();

			final Object selectedObject = treeSelected == null ? treeSelected : manipulateSelection(treeSelected);
			if (selectedObject instanceof EObject) {
				final EObject selected = (EObject) selectedObject;
				final Object root = manipulateSelection(((RootObject) ((TreeViewer) event.getSource()).getInput())
					.getRoot());

				final boolean rootSelected = selected == root;
				VView view = null;
				if (rootSelected) {
					view = getVElement().getDetailView();
				}
				if (view == null || view.getChildren().isEmpty()) {
					view = detailManager.getDetailView(getViewModelContext(), selected,
						properties -> {
							if (rootSelected) {
								properties.addNonInheritableProperty(ROOT_KEY, true);
							}
						});
				}

				if (detailManager.isCached(selected)) {
					detailManager.activate(selected);
				} else {
					final ReferenceService referenceService = getViewModelContext().getService(
						ReferenceService.class);
					// we have a multi selection, the multi edit is enabled and the multi selection is valid
					if (getViewModelContext().getContextValue(ENABLE_MULTI_EDIT) == Boolean.TRUE
						&& selection.size() > 1
						&& selected != getSelection(new StructuredSelection(selection.getFirstElement()))) {
						childContext = ViewModelContextFactory.INSTANCE.createViewModelContext(view, selected,
							new TreeMasterDetailReferenceService(referenceService));
					} else {
						childContext = getViewModelContext().getChildContext(selected, getVElement(), view,
							new TreeMasterDetailReferenceService(referenceService));
					}

					manipulateViewContext(childContext);

					detailManager.render(childContext, ECPSWTViewRenderer.INSTANCE::render);
				}

				detailManager.setDetailReadOnly(!getVElement().isEffectivelyEnabled()
					|| getVElement().isEffectivelyReadonly());
			} else {
				// No selection
				childContext = null;
			}

			relayoutDetail();
		}

		private Object getSelection(IStructuredSelection selection) {
			Object treeSelected = selection != null ? selection.getFirstElement() : null;
			if (getViewModelContext().getContextValue(ENABLE_MULTI_EDIT) == Boolean.TRUE
				&& treeSelected instanceof EObject && selection.size() > 1) {
				boolean allOfSameType = true;
				final EObject dummy = EcoreUtil.create(((EObject) treeSelected).eClass());

				final Iterator<?> iterator = selection.iterator();
				final Set<EObject> selectedEObjects = new LinkedHashSet<EObject>();
				while (iterator.hasNext()) {
					final EObject eObject = (EObject) iterator.next();
					allOfSameType &= eObject.eClass() == dummy.eClass();
					if (allOfSameType) {
						for (final EAttribute attribute : dummy.eClass().getEAllAttributes()) {
							if (eObject == treeSelected) {
								dummy.eSet(attribute, eObject.eGet(attribute));
							} else if (dummy.eGet(attribute) != null
								&& !dummy.eGet(attribute).equals(eObject.eGet(attribute))) {
								dummy.eUnset(attribute);
							}
						}
						selectedEObjects.add(eObject);
					} else {
						break;
					}
				}
				if (allOfSameType) {
					treeSelected = dummy;
					dummy.eAdapters().add(new MultiEditAdapter(dummy, selectedEObjects));
				}
			}
			return treeSelected;
		}
	}

	/**
	 * Returns the composite for the detail.
	 *
	 * @return the composite
	 */
	protected Composite getDetailContainer() {
		return rightPanelContainerComposite;
	}

	/**
	 * Allows to manipulate the selection by returning a specific child.
	 *
	 * @param treeSelected the selected element in the tree
	 * @return the object that should be used as a selection
	 */
	protected Object manipulateSelection(Object treeSelected) {
		return TreeMasterDetailSelectionManipulatorHelper.manipulateSelection(treeSelected);
	}

	/**
	 * Gets called after a detail composite was disposed. Allows for further cleanup.
	 */
	protected void cleanCustomOnSelectionChange() {
		// do nothing
	}

	/**
	 * Relayouts the detail composite.
	 */
	protected void relayoutDetail() {
		rightPanelContainerComposite.layout();
		final Point point = container.computeSize(SWT.DEFAULT, SWT.DEFAULT);
		rightPanel.setMinSize(point);
	}

	/**
	 * Reveal the given {@code object} in my tree.
	 *
	 * @param object an object to reveal
	 * @return whether I succeeded in revealing it
	 *
	 * @since 1.22
	 */
	public boolean reveal(Object object) {
		final TreePath treePath = getTreePathFor(object);
		return reveal(treePath);
	}

	/**
	 * Get a path to an {@object} in my tree.
	 *
	 * @param object an object in my tree
	 * @return a path to it
	 *
	 * @since 1.22
	 */
	public TreePath getTreePathFor(Object object) {
		final ITreeContentProvider content = (ITreeContentProvider) treeViewer.getContentProvider();
		final Collection<?> roots = Arrays.asList(content.getElements(treeViewer.getInput()));

		final List<Object> path = new LinkedList<Object>();
		path.add(object);
		for (Object parent = content.getParent(object); parent != null; parent = content.getParent(parent)) {
			path.add(0, parent);

			// Don't go above the root element
			if (roots.contains(parent)) {
				break;
			}
		}

		return new TreePath(path.toArray());
	}

	/**
	 * Reveal the given {@code path} in my tree.
	 *
	 * @param path a tree path to reveal
	 * @return whether I succeeded in revealing it
	 *
	 * @since 1.22
	 */
	public boolean reveal(TreePath path) {
		final ISelection newSelection = new TreeSelection(path);
		if (!newSelection.equals(treeViewer.getSelection())) {
			treeViewer.setSelection(new TreeSelection(path), true);
		}
		treeViewer.reveal(path);

		return treeViewer.getStructuredSelection().getFirstElement() == path.getLastSegment();
	}

	/**
	 * Query whether the given {@code path} exists in my tree.
	 *
	 * @param path a tree path
	 * @return whether the path locates an element that exists in my tree
	 *
	 * @since 1.22
	 */
	public boolean hasPath(TreePath path) {
		if (path.equals(TreePath.EMPTY)) {
			return true;
		}

		final TreePath parentPath = path.getParentPath();
		if (!hasPath(parentPath)) {
			return false;
		}

		final ITreeContentProvider content = (ITreeContentProvider) treeViewer.getContentProvider();
		Collection<?> children;
		if (parentPath.equals(TreePath.EMPTY)) {
			children = Arrays.asList(content.getElements(treeViewer.getInput()));
		} else if (content.hasChildren(parentPath.getLastSegment())) {
			children = Arrays.asList(content.getChildren(parentPath.getLastSegment()));
		} else {
			children = Collections.EMPTY_SET;
		}

		return children.contains(path.getLastSegment());
	}

	/**
	 * Obtain the current detail context, if any.
	 *
	 * @return the view-model context of the details currently being presented,
	 *         or {@code null} if none (usually because there is no selection in the tree)
	 *
	 * @since 1.22
	 */
	public ViewModelContext getDetailContext() {
		return childContext;
	}

	/**
	 * The label provider used for the detail tree.
	 *
	 * @author jfaltermeier
	 *
	 */
	private class TreeMasterDetailLabelProvider extends AdapterFactoryLabelProvider {

		TreeMasterDetailLabelProvider(AdapterFactory adapterFactory) {
			super(adapterFactory);
		}

		@Override
		public Image getImage(Object object) {
			final Image image = super.getImage(object);
			if (!EObject.class.isInstance(object)) {
				return image;
			}
			return getValidationOverlay(image, (EObject) object);
		}

		protected Image getValidationOverlay(Image image, final EObject object) {
			// final Integer severity = validationResultCacheTree.getCachedValue(object);
			final VDiagnostic vDiagnostic = getVElement().getDiagnostic();
			int highestSeverity = Diagnostic.OK;
			if (vDiagnostic != null) {
				for (final Diagnostic diagnostic : vDiagnostic.getDiagnostics(object)) {
					if (diagnostic.getSeverity() > highestSeverity) {
						highestSeverity = diagnostic.getSeverity();
					}
				}
			}
			final ImageDescriptor overlay = SWTValidationHelper.INSTANCE.getValidationOverlayDescriptor(highestSeverity,
				getVElement(), getViewModelContext());
			if (overlay == null) {
				return image;
			}
			final OverlayImageDescriptor imageDescriptor = new OverlayImageDescriptor(image, overlay,
				OverlayImageDescriptor.LOWER_RIGHT);
			final Image resultImage = imageDescriptor.createImage();
			return resultImage;
		}

	}

	@Override
	protected void applyEnable() {
		// Re-select the current selection to enforce re-rendering the detail.
		treeViewer.setSelection(new StructuredSelection(treeViewer.getStructuredSelection().getFirstElement()));
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.swt.core.AbstractSWTRenderer#applyValidation()
	 * @since 1.14
	 */
	@Override
	protected void applyValidation(final VDiagnostic oldDia, final VDiagnostic newDia) {
		super.applyValidation();

		if (treeViewer == null) {
			return;
		}
		Display.getDefault().asyncExec(new Runnable() {

			@Override
			public void run() {
				if (treeViewer.getTree().isDisposed()) {
					return;
				}
				updateTree(oldDia, newDia);
			}
		});
	}

	private void updateTree(VDiagnostic oldDia, VDiagnostic newDia) {
		final List<Object> diff = new ArrayList<Object>();
		if (newDia != null) {
			diff.addAll(newDia.getDiagnostics());
		}
		if (oldDia != null) {
			diff.removeAll(oldDia.getDiagnostics());
		}
		final List<Object> diff2 = new ArrayList<Object>();
		if (oldDia != null) {
			diff2.addAll(oldDia.getDiagnostics());
		}
		if (newDia != null) {
			diff2.removeAll(newDia.getDiagnostics());
		}
		diff.addAll(diff2);
		final Set<Object> toUpdate = new LinkedHashSet<Object>();
		final ITreeContentProvider provider = ITreeContentProvider.class.cast(treeViewer.getContentProvider());
		for (final Object o : diff) {
			final EObject toAdd = (EObject) Diagnostic.class.cast(o).getData().get(0);
			toUpdate.add(toAdd);

			Object parent = provider.getParent(toAdd);
			while (EObject.class.isInstance(parent)) {
				toUpdate.add(parent);
				parent = provider.getParent(parent);
			}
		}
		if (toUpdate.isEmpty() && !(oldDia.getDiagnostics().isEmpty() && newDia.getDiagnostics().isEmpty())) {
			treeViewer.refresh();
			return;
		}
		treeViewer.update(toUpdate.toArray(), null);
	}

	/**
	 * reference service for the detail pane of a tree master detail view.
	 * It delegates calls to a root reference service, but opens new element in the detail pane.
	 *
	 * @author Jonas
	 *
	 */
	private class TreeMasterDetailReferenceService implements ReferenceService {

		private final ReferenceService delegate;

		TreeMasterDetailReferenceService(ReferenceService delegate) {
			this.delegate = delegate;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#instantiate(org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
		 */
		@Override
		public void instantiate(ViewModelContext context) {
			// no op
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#dispose()
		 */
		@Override
		public void dispose() {
			// no op
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#getPriority()
		 */
		@Override
		public int getPriority() {
			if (delegate == null) {
				return 0;
			}
			return delegate.getPriority() - 1;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.edit.spi.ReferenceService#addNewModelElements(org.eclipse.emf.ecore.EObject,
		 *      org.eclipse.emf.ecore.EReference)
		 */
		@Override
		public void addNewModelElements(EObject eObject, EReference eReference) {
			addNewModelElements(eObject, eReference, true);
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.edit.spi.ReferenceService#addNewModelElements(org.eclipse.emf.ecore.EObject,
		 *      org.eclipse.emf.ecore.EReference)
		 */
		@Override
		public Optional<EObject> addNewModelElements(EObject eObject, EReference eReference, boolean openInNewContext) {
			if (delegate == null) {
				return Optional.empty();
			}
			return delegate.addNewModelElements(eObject, eReference, openInNewContext);
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.edit.spi.ReferenceService#addExistingModelElements(org.eclipse.emf.ecore.EObject,
		 *      org.eclipse.emf.ecore.EReference)
		 */
		@Override
		public void addExistingModelElements(EObject eObject, EReference eReference) {
			if (delegate == null) {
				return;
			}
			delegate.addExistingModelElements(eObject, eReference);
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.edit.spi.ReferenceService#openInNewContext(org.eclipse.emf.ecore.EObject)
		 */
		@Override
		public void openInNewContext(EObject eObject) {
			treeViewer.setSelection(new StructuredSelection(eObject), true);
			final ISelection selection = treeViewer.getSelection();
			if (!selection.isEmpty()) {
				return;
			}
			if (delegate == null) {
				return;
			}
			delegate.openInNewContext(eObject);
		}
	}

}
