/*******************************************************************************
 * Copyright (c) 2011-2020 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:
 * Eugen Neufeld - initial API and implementation
 * Johannes Faltermeier - refactorings
 * Christian W. Damus - bugs 544116, 544537, 545686, 530314, 547271, 547787, 548592, 552385, 559267
 ******************************************************************************/
package org.eclipse.emf.ecp.view.spi.table.swt;

import static org.eclipse.emfforms.spi.swt.table.ViewerRefreshManager.getRefreshRunnable;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;

import javax.inject.Inject;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.Observables;
import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.InternalEObject;
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.edit.spi.swt.table.ECPCellEditor;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditorComparator;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPCustomUpdateCellEditor;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPElementAwareCellEditor;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPFilterableCell;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPViewerAwareCellEditor;
import org.eclipse.emf.ecp.edit.spi.swt.util.ECPDialogExecutor;
import org.eclipse.emf.ecp.view.internal.table.swt.Activator;
import org.eclipse.emf.ecp.view.internal.table.swt.CellReadOnlyTesterHelper;
import org.eclipse.emf.ecp.view.internal.table.swt.MessageKeys;
import org.eclipse.emf.ecp.view.internal.table.swt.RunnableManager;
import org.eclipse.emf.ecp.view.internal.table.swt.TableConfigurationHelper;
import org.eclipse.emf.ecp.view.model.common.util.RendererUtil;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.core.swt.AbstractControlSWTRenderer;
import org.eclipse.emf.ecp.view.spi.core.swt.AbstractControlSWTRendererUtil;
import org.eclipse.emf.ecp.view.spi.model.DiagnosticMessageExtractor;
import org.eclipse.emf.ecp.view.spi.model.LabelAlignment;
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.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VElement;
import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
import org.eclipse.emf.ecp.view.spi.provider.ECPTooltipModifierHelper;
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.reporting.RenderingFailedReport;
import org.eclipse.emf.ecp.view.spi.table.model.VEnablementConfiguration;
import org.eclipse.emf.ecp.view.spi.table.model.VTableControl;
import org.eclipse.emf.ecp.view.spi.table.model.VTableDomainModelReference;
import org.eclipse.emf.ecp.view.spi.table.swt.action.AddRowAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.DuplicateRowAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.MoveRowDownAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.MoveRowUpAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.RemoveRowAction;
import org.eclipse.emf.ecp.view.spi.table.swt.action.TableActionIconButton;
import org.eclipse.emf.ecp.view.spi.table.swt.action.TableRendererActionBar;
import org.eclipse.emf.ecp.view.spi.table.swt.action.TableRendererViewerActionContext;
import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService;
import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
import org.eclipse.emf.ecp.view.template.style.background.model.VTBackgroundFactory;
import org.eclipse.emf.ecp.view.template.style.background.model.VTBackgroundStyleProperty;
import org.eclipse.emf.ecp.view.template.style.fontProperties.model.VTFontPropertiesFactory;
import org.eclipse.emf.ecp.view.template.style.fontProperties.model.VTFontPropertiesStyleProperty;
import org.eclipse.emf.ecp.view.template.style.keybinding.model.VTKeyBinding;
import org.eclipse.emf.ecp.view.template.style.keybinding.model.VTKeyBindings;
import org.eclipse.emf.ecp.view.template.style.tableStyleProperty.model.RenderMode;
import org.eclipse.emf.ecp.view.template.style.tableStyleProperty.model.VTTableStyleProperty;
import org.eclipse.emf.ecp.view.template.style.tableStyleProperty.model.VTTableStylePropertyFactory;
import org.eclipse.emf.ecp.view.template.style.tableValidation.model.VTTableValidationFactory;
import org.eclipse.emf.ecp.view.template.style.tableValidation.model.VTTableValidationStyleProperty;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.MoveCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
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.emfforms.common.Optional;
import org.eclipse.emfforms.spi.common.BundleResolver;
import org.eclipse.emfforms.spi.common.BundleResolver.NoBundleFoundException;
import org.eclipse.emfforms.spi.common.BundleResolverFactory;
import org.eclipse.emfforms.spi.common.report.AbstractReport;
import org.eclipse.emfforms.spi.common.report.ReportService;
import org.eclipse.emfforms.spi.common.sort.NumberAwareStringComparator;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedReport;
import org.eclipse.emfforms.spi.core.services.databinding.EMFFormsDatabinding;
import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
import org.eclipse.emfforms.spi.core.services.editsupport.EMFFormsEditSupport;
import org.eclipse.emfforms.spi.core.services.label.EMFFormsLabelProvider;
import org.eclipse.emfforms.spi.core.services.label.NoLabelFoundException;
import org.eclipse.emfforms.spi.localization.EMFFormsLocalizationService;
import org.eclipse.emfforms.spi.localization.LocalizationServiceHelper;
import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
import org.eclipse.emfforms.spi.swt.core.layout.EMFFormsSWTLayoutUtil;
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.SWTValidationUiService;
import org.eclipse.emfforms.spi.swt.table.AbstractTableViewerComposite;
import org.eclipse.emfforms.spi.swt.table.CellLabelProviderFactory;
import org.eclipse.emfforms.spi.swt.table.ColumnConfiguration;
import org.eclipse.emfforms.spi.swt.table.ColumnConfigurationBuilder;
import org.eclipse.emfforms.spi.swt.table.DNDProvider;
import org.eclipse.emfforms.spi.swt.table.EditingSupportCreator;
import org.eclipse.emfforms.spi.swt.table.TableConfiguration;
import org.eclipse.emfforms.spi.swt.table.TableConfigurationBuilder;
import org.eclipse.emfforms.spi.swt.table.TableControl;
import org.eclipse.emfforms.spi.swt.table.TableViewerComparator;
import org.eclipse.emfforms.spi.swt.table.TableViewerCompositeBuilder;
import org.eclipse.emfforms.spi.swt.table.TableViewerCreator;
import org.eclipse.emfforms.spi.swt.table.TableViewerFactory;
import org.eclipse.emfforms.spi.swt.table.TableViewerSWTBuilder;
import org.eclipse.emfforms.spi.swt.table.TableViewerSWTCustomization;
import org.eclipse.emfforms.spi.swt.table.ViewerRefreshManager;
import org.eclipse.emfforms.spi.swt.table.action.ActionBar;
import org.eclipse.emfforms.spi.swt.table.action.ActionConfiguration;
import org.eclipse.emfforms.spi.swt.table.action.ActionConfigurationBuilder;
import org.eclipse.emfforms.spi.swt.table.action.TableActionBar;
import org.eclipse.emfforms.spi.swt.table.action.ViewerActionContext;
import org.eclipse.emfforms.view.spi.multisegment.model.MultiSegmentUtil;
import org.eclipse.emfforms.view.spi.multisegment.model.VMultiDomainModelReferenceSegment;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.databinding.viewers.ObservableListContentProvider;
import org.eclipse.jface.databinding.viewers.ObservableMapCellLabelProvider;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogLabelKeys;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.AbstractTableViewer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationListener;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ColumnViewerEditorDeactivationEvent;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IColorProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Widget;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

/**
 * SWT Renderer for Table Control.
 *
 * @author Eugen Neufeld
 * @author Johannes Faltermeier
 *
 */
public class TableControlSWTRenderer extends AbstractControlSWTRenderer<VTableControl> {

	/**
	 * @since 1.10
	 */
	protected static final String FIXED_COLUMNS = "org.eclipse.rap.rwt.fixedColumns"; //$NON-NLS-1$
	/**
	 * @since 1.10
	 */
	protected static final String TABLE_CUSTOM_VARIANT = "org_eclipse_emf_ecp_control_table"; //$NON-NLS-1$
	/**
	 * @since 1.17
	 */
	protected static final Point VALIDATION_PREFERRED_SIZE = new Point(16, 17);

	private final Map<Integer, ECPCellEditorComparator> columnIndexToComparatorMap = new LinkedHashMap<Integer, ECPCellEditorComparator>();

	private final ImageRegistryService imageRegistryService;
	private final EMFDataBindingContext viewModelDBC;
	private final EMFFormsEditSupport emfFormsEditSupport;

	private SWTGridDescription rendererGridDescription;

	private AbstractTableViewer tableViewer;

	private Label validationIcon;
	private boolean showValidationSummaryTooltip;

	private Optional<Integer> minimumHeight;
	private Optional<Integer> maximumHeight;
	private Optional<Integer> visibleLines;
	private AbstractTableViewerComposite<? extends AbstractTableViewer> tableViewerComposite;
	private int regularColumnsStartIndex;
	private boolean isDisposing;
	private IObservableList<?> list;
	private final RunnableManager runnableManager = new RunnableManager(Display.getDefault());

	private TableViewerSWTCustomization<?> customization;

	/** The EReference describing the list shown by the table. */
	private EReference tableEReference;
	private EStructuralFeature[] columnFeatures;
	/** The feature of the column which is currently used for sorting. */
	private java.util.Optional<EStructuralFeature> sortColumnFeature = java.util.Optional.empty();
	private ModelChangeListener autoSortModelChangeListener;
	private final EMFFormsLocalizationService localizationService;
	private final BundleResolver bundleResolver = BundleResolverFactory.createBundleResolver();
	/** DO NOT USE DIRECTLY! Use {@link #getEnumeratorComparator()} instead. */
	private LocalizedEnumeratorComparator enumeratorComparator;

	private EMFFormsLocalizationService l10n;
	private String referenceDisplayName;

	/**
	 * Legacy constructor for backwards compatibility.
	 *
	 * @param vElement the view model element to be rendered
	 * @param viewContext the view context
	 * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
	 * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
	 * @param reportService The {@link ReportService}
	 * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
	 * @param imageRegistryService The {@link ImageRegistryService}
	 * @param emfFormsEditSupport The {@link EMFFormsEditSupport}
	 * @since 1.8
	 */
	@Deprecated
	// BEGIN COMPLEX CODE
	public TableControlSWTRenderer(
		VTableControl vElement,
		ViewModelContext viewContext,
		ReportService reportService,
		EMFFormsDatabindingEMF emfFormsDatabinding,
		EMFFormsLabelProvider emfFormsLabelProvider,
		VTViewTemplateProvider vtViewTemplateProvider,
		ImageRegistryService imageRegistryService,
		EMFFormsEditSupport emfFormsEditSupport) {
		// END COMPLEX CODE

		this(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider,
			imageRegistryService, emfFormsEditSupport, viewContext.getService(EMFFormsLocalizationService.class));
	}

	/**
	 * Default constructor.
	 *
	 * @param vElement the view model element to be rendered
	 * @param viewContext the view context
	 * @param emfFormsDatabinding The {@link EMFFormsDatabinding}
	 * @param emfFormsLabelProvider The {@link EMFFormsLabelProvider}
	 * @param reportService The {@link ReportService}
	 * @param vtViewTemplateProvider The {@link VTViewTemplateProvider}
	 * @param imageRegistryService The {@link ImageRegistryService}
	 * @param emfFormsEditSupport The {@link EMFFormsEditSupport}
	 * @param localizationService The {@link EMFFormsLocalizationService}
	 * @since 1.22
	 */
	@Inject
	// BEGIN COMPLEX CODE
	public TableControlSWTRenderer(
		VTableControl vElement,
		ViewModelContext viewContext,
		ReportService reportService,
		EMFFormsDatabindingEMF emfFormsDatabinding,
		EMFFormsLabelProvider emfFormsLabelProvider,
		VTViewTemplateProvider vtViewTemplateProvider,
		ImageRegistryService imageRegistryService,
		EMFFormsEditSupport emfFormsEditSupport,
		EMFFormsLocalizationService localizationService) {
		// END COMPLEX CODE

		super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider);
		this.imageRegistryService = imageRegistryService;
		this.emfFormsEditSupport = emfFormsEditSupport;
		this.localizationService = localizationService;
		viewModelDBC = new EMFDataBindingContext();
	}

	@Override
	public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) {
		if (rendererGridDescription == null) {
			if (getTableStyleProperty().getRenderMode() == RenderMode.COMPACT_VERTICALLY) {
				final boolean includeLabel = getVElement().getLabelAlignment() != LabelAlignment.NONE;
				if (getVElement().getLabelAlignment() == LabelAlignment.TOP) {
					Activator.getInstance().log(IStatus.WARNING, MessageFormat.format(
						Messages.TableControlSWTRenderer_LabelAlignmentTopNotSupportForRenderModeCompactVertically,
						getVElement().getName()));
				}
				rendererGridDescription = GridDescriptionFactory.INSTANCE.createCompactGrid(includeLabel, true, this);
			} else {
				rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 1, this);
			}

		}
		return rendererGridDescription;
	}

	@Override
	protected EMFFormsDatabindingEMF getEMFFormsDatabinding() {
		return (EMFFormsDatabindingEMF) super.getEMFFormsDatabinding();
	}

	@Override
	protected Control renderControl(SWTGridCell gridCell, final Composite parent) throws NoRendererFoundException,
		NoPropertyDescriptorFoundExeption {
		// compact label
		if (gridCell.getColumn() == 0 && rendererGridDescription.getColumns() == 3) {
			return createLabel(parent);
		}
		// compact validation
		if (gridCell.getColumn() == 0 && rendererGridDescription.getColumns() == 2
			|| gridCell.getColumn() == 1 && rendererGridDescription.getColumns() == 3) {
			validationIcon = createValidationIcon(parent);
			return validationIcon;
		}
		// Default
		return renderTableControl(gridCell, parent);
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Control createLabel(final Composite parent) {
		final VDomainModelReference dmrToCheck = getDMRToMultiReference();
		final IObservableValue<?> labelText = getLabelText(dmrToCheck);
		final IObservableValue<?> labelTooltipText = getLabelTooltipText(dmrToCheck);

		final Label titleLabel = new Label(parent, AbstractControlSWTRendererUtil
			.getLabelStyleBits(getVTViewTemplateProvider(), getVElement(), getViewModelContext()));
		titleLabel.setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_control_label"); //$NON-NLS-1$
		titleLabel.setBackground(parent.getBackground());

		viewModelDBC.bindValue(
			WidgetProperties.text().observe(titleLabel),
			labelText);
		viewModelDBC.bindValue(
			WidgetProperties.tooltipText().observe(titleLabel),
			labelTooltipText);

		return titleLabel;
	}

	/**
	 * Renders the Table Control.
	 *
	 * Renders the Table Control including title and validation when {@link RenderMode} is set to
	 * {@link RenderMode#DEFAULT}. Only renders the
	 * Table Control without title and validation when renderMode is set to {@link RenderMode#COMPACT_VERTICALLY}.
	 *
	 * @param gridCell the {@link SWTGridCell}.
	 * @param parent the {@link Composite}.
	 * @return the rendered {@link Control}.
	 * @throws NoRendererFoundException the {@link NoRendererFoundException}.
	 * @throws NoPropertyDescriptorFoundExeption the {@link NoPropertyDescriptorFoundExeption}.
	 * @since 1.14
	 */
	protected Control renderTableControl(SWTGridCell gridCell, final Composite parent)
		throws NoRendererFoundException,
		NoPropertyDescriptorFoundExeption {
		try {
			/* get the list-setting which is displayed */
			final VDomainModelReference dmrToCheck = getDMRToMultiReference();

			/* get the observable list */
			list = getEMFFormsDatabinding().getObservableList(dmrToCheck,
				getViewModelContext().getDomainModel());

			/* get the EReference describing the list shown by the table */
			tableEReference = (EReference) list.getElementType();

			final TableRendererViewerActionContext actionContext = createViewerActionContext();
			final ActionConfiguration actionConfiguration = configureActions(actionContext);
			final TableActionBar<? extends AbstractTableViewer> actionBar = createActionBar(actionContext,
				actionConfiguration);

			/* get the label text/tooltip */
			final IObservableValue<?> labelText = getLabelText(dmrToCheck);
			final IObservableValue<?> labelTooltipText = getLabelTooltipText(dmrToCheck);

			/* content provider */
			final ObservableListContentProvider cp = new ObservableListContentProvider();

			final TableControlComparator comparator = getVElement().isMoveUpDownDisabled()
				? createTableViewerComparator()
				: null;

			/* render */
			final TableViewerCompositeBuilder compositeBuilder = createTableViewerCompositeBuilder();

			final TableViewerSWTBuilder tableViewerSWTBuilder = createTableViewerSWTBuilder(parent, list, labelText,
				labelTooltipText, compositeBuilder, cp, comparator, actionBar);
			tableViewerSWTBuilder.customizeActionConfiguration(actionConfiguration);

			tableViewerSWTBuilder
				.configureTable(TableConfigurationBuilder.from(tableViewerSWTBuilder)
					.dataMapEntry(TableConfiguration.DMR, dmrToCheck)
					.dataMapEntry(ViewerRefreshManager.REFRESH_MANAGER,
						(ViewerRefreshManager) this::postRefresh)
					.build());

			regularColumnsStartIndex = 0;

			/* validation column */
			if (!getVElement().isEffectivelyReadonly()) {
				regularColumnsStartIndex++;
				createFixedValidationStatusColumn(tableViewerSWTBuilder);
			}
			regularColumnsStartIndex += addAdditionalColumns(tableViewerSWTBuilder);
			addColumns(tableViewerSWTBuilder, EReference.class.cast(list.getElementType()).getEReferenceType(), cp);

			initCompositeHeight();

			tableViewerComposite = tableViewerSWTBuilder.build();

			/* setup selection changes listener */
			tableViewerComposite.getTableViewer().addSelectionChangedListener(new ViewerSelectionChangedListener());
			tableViewerComposite.getTableViewer().addDoubleClickListener(new DoubleClickListener());

			/* setup sorting via column selection */
			if (getVElement().isMoveUpDownDisabled()) {
				setupSorting(comparator, regularColumnsStartIndex, tableViewerComposite);
			}

			/* get validation icon */
			setupValidation(tableViewerComposite);

			/* create the table viewer editor */
			setTableViewer(tableViewerComposite.getTableViewer());

			SWTDataElementIdHelper.setElementIdDataForVControl(tableViewerComposite, getVElement(),
				getViewModelContext());

			// FIXME doesn't work with table with panel
			// setLayoutData(compositeBuilder.getViewerComposite());
			GridData.class
				.cast(compositeBuilder.getViewerComposite().getLayoutData()).heightHint = getTableHeightHint();

			addRelayoutListenerIfNeeded(list, compositeBuilder.getViewerComposite());

			addResizeListener(tableViewerComposite.getTableViewer().getControl(), regularColumnsStartIndex);

			customization = tableViewerSWTBuilder.getCustomization();

			autoSortModelChangeListener = new AutoSortModelChangeListener();
			getViewModelContext().registerDomainChangeListener(autoSortModelChangeListener);

			return tableViewerComposite;

		} catch (final DatabindingFailedException ex) {
			getReportService().report(new RenderingFailedReport(ex));
			final Label errorLabel = new Label(parent, SWT.NONE);
			errorLabel.setText(ex.getMessage());
			return errorLabel;
		}
	}

	/**
	 * Creates a TableControlComparator.
	 *
	 * @return TableControlComparator
	 * @since 1.22
	 */
	protected TableControlComparator createTableViewerComparator() {
		return new ECPTableViewerComparator();
	}

	/**
	 * Create the {@link ViewerActionContext} for the table viewer.
	 *
	 * @return the {@link TableRendererViewerActionContext}
	 * @throws DatabindingFailedException
	 * @since 1.18
	 */
	protected TableRendererViewerActionContext createViewerActionContext() {
		return new TableRendererViewerActionContext() {

			@Override
			public VTableControl getVElement() {
				return TableControlSWTRenderer.this.getVElement();
			}

			@Override
			public Setting getSetting() {
				try {
					return getEMFFormsDatabinding().getSetting(
						getDMRToMultiReference(), getViewModelContext().getDomainModel());
				} catch (final DatabindingFailedException ex) {
					return null; // this should never happen
				}
			}

			@Override
			public EditingDomain getEditingDomain() {
				return TableControlSWTRenderer.this.getEditingDomain(getViewModelContext().getDomainModel());
			}

			@Override
			public AbstractTableViewer getViewer() {
				return TableControlSWTRenderer.this.getTableViewer();
			}
		};
	}

	/**
	 * Configure the actions applicable to this table viewer.
	 *
	 * @param actionContext the action context
	 * @return an {@link ActionConfigurationImpl} built using the {@link ActionConfigurationBuilder}
	 *
	 * @since 1.18
	 */
	protected ActionConfiguration configureActions(TableRendererViewerActionContext actionContext) {
		final ActionConfigurationBuilder actionConfigBuilder = //
			ActionConfigurationBuilder.usingDefaults();

		/**
		 * Note: EMF Forms distinguishes between read-only and enabled.
		 * Read-only is a declarative state defined by the view model and cannot
		 * be overwritten during runtime whereas the enabled state can.
		 * Therefore, if the view element is marked as read-only we must not configure any buttons.
		 *
		 * @see @{link TableRenderAction#isTableDisabled()}
		 */
		if (getVElement().isEffectivelyReadonly()) {
			return actionConfigBuilder.build();
		}

		final Setting setting = actionContext.getSetting();
		final EClass eClass = ((EReference) setting.getEStructuralFeature()).getEReferenceType();

		if (!getVElement().isMoveUpDownDisabled()) {
			final MoveRowUpAction moveRowUpAction = new MoveRowUpAction(actionContext);
			final MoveRowDownAction moveRowDownAction = new MoveRowDownAction(actionContext);

			actionConfigBuilder
				.addAction(moveRowUpAction)
				.addControlFor(moveRowUpAction, new TableActionIconButton(
					formatTooltipText(eClass, MessageKeys.TableControl_MoveUp), getImage("icons/move_up.png"))) //$NON-NLS-1$
				.addKeySequenceFor(moveRowUpAction,
					getKeyBindingsForAction(MoveRowUpAction.ACTION_ID))
				//
				.addAction(moveRowDownAction)
				.addControlFor(moveRowDownAction, new TableActionIconButton(
					formatTooltipText(eClass, MessageKeys.TableControl_MoveDown), getImage("icons/move_down.png"))) //$NON-NLS-1$
				.addKeySequenceFor(moveRowDownAction,
					getKeyBindingsForAction(MoveRowDownAction.ACTION_ID));
		}

		if (!getVElement().isAddRemoveDisabled()) {
			final AddRowAction addRowAction = new AddRowAction(actionContext) {
				@Override
				public void addRowLegacy(
					final EClass eClass, final EStructuralFeature eStructuralFeature, final EObject eObject) {
					addRow(eClass, eObject, eStructuralFeature);
				}
			};
			final RemoveRowAction removeRowAction = new RemoveRowAction(actionContext) {
				@Override
				public void removeRowLegacy(List<EObject> deletionList, EObject eObject,
					EStructuralFeature eStructuralFeature) {
					deleteRowUserConfirmDialog(deletionList, eObject, eStructuralFeature, getAddButton(),
						getRemoveButton());
				}

				@Override
				public boolean canExecute() {
					final Setting setting = getActionContext().getSetting();
					return super.canExecute() && ConditionalDeleteService.getDeleteService(getViewModelContext())
						.canRemove(setting.getEObject(), setting.getEStructuralFeature(),
							getActionContext().getViewer().getStructuredSelection().toList());
				}
			};

			actionConfigBuilder
				.addAction(addRowAction)
				.addControlFor(addRowAction, new TableActionIconButton(
					formatTooltipText(eClass, MessageKeys.TableControl_AddInstanceOf), getImage("icons/add.png"))) //$NON-NLS-1$
				.addKeySequenceFor(addRowAction,
					getKeyBindingsForAction(AddRowAction.ACTION_ID));
			actionConfigBuilder
				.addAction(removeRowAction)
				.addControlFor(removeRowAction, new TableActionIconButton(
					formatTooltipText(eClass, MessageKeys.TableControl_RemoveSelected), getImage("icons/delete.png"))) //$NON-NLS-1$
				.addKeySequenceFor(removeRowAction,
					getKeyBindingsForAction(RemoveRowAction.ACTION_ID));
		}

		if (!getVElement().isDuplicateDisabled()) {
			final DuplicateRowAction duplicateRow = new DuplicateRowAction(actionContext);

			actionConfigBuilder
				.addAction(duplicateRow)
				.addControlFor(duplicateRow, new TableActionIconButton(
					formatTooltipText(eClass, MessageKeys.TableControl_Duplicate), getImage("icons/duplicate.png"))) //$NON-NLS-1$
				.addKeySequenceFor(duplicateRow,
					getKeyBindingsForAction(DuplicateRowAction.ACTION_ID));
		}

		return actionConfigBuilder.build();
	}

	/**
	 * Helper to extract the configured key bindings form the view template model.
	 *
	 * @param actionId the ID of the action to extract the key bindings for
	 * @param defaultKeybindings the default key bindings to use in case there are no bindings configured
	 * @return an array of key bindings
	 *
	 * @since 1.18
	 */
	protected String[] getKeyBindingsForAction(String actionId, String... defaultKeybindings) {
		final VTKeyBindings bindings = getStyleProperty(VTKeyBindings.class);
		if (bindings == null) {
			return defaultKeybindings;
		}
		final Set<String> ret = new LinkedHashSet<String>();
		for (final VTKeyBinding binding : bindings.getBindings()) {
			if (actionId.equals(binding.getId()) && binding.getKeySequence() != null
				&& !binding.getKeySequence().isEmpty()) {
				ret.add(binding.getKeySequence());
			}
		}
		return ret.toArray(new String[] {});
	}

	/**
	 * Creates an action bar.
	 *
	 * @param actionContext the {@link ViewerActionContext} to use
	 * @param actionConfiguration the {@link ActionConfiguration} to use
	 * @return a action bar builder
	 *
	 * @since 1.18
	 */
	protected TableActionBar<? extends AbstractTableViewer> createActionBar(
		TableRendererViewerActionContext actionContext, ActionConfiguration actionConfiguration) {
		return new TableRendererActionBar(actionContext, actionConfiguration, getViewModelContext());
	}

	/**
	 * Creates the {@link TableViewerCompositeBuilder} used to get Composite hierarchy for this table renderer. This
	 * method can be overwritten by sub classes to customize the layout.
	 *
	 * @return The {@link TableViewerCompositeBuilder}
	 * @since 1.13
	 */
	protected TableViewerCompositeBuilder createTableViewerCompositeBuilder() {
		if (getTableStyleProperty().getRenderMode() == RenderMode.COMPACT_VERTICALLY) {
			return new CompactVerticallyTableControlSWTRendererCompositeBuilder(false, false);
		}
		return new TableControlSWTRendererCompositeBuilder();
	}

	/**
	 * Creates a new {@link TableViewerSWTBuilder}.
	 *
	 * @param parent the parent {@link Composite}
	 * @param list the input object
	 * @param labelText the title
	 * @param labelTooltipText the tooltip
	 * @param compositeBuilder the {@link TableViewerCompositeBuilder}
	 * @param cp the content provider
	 * @param comparator the {@link ViewerComparator}; has no effect if move up/down
	 *            functionality is enabled
	 * @param actionBar the {@link ActionBar}
	 * @return the {@link TableViewerSWTBuilder}
	 * @since 1.18
	 * @deprecated Please use
	 *             {@link #createTableViewerSWTBuilder(Composite, IObservableList, IObservableValue, IObservableValue, TableViewerCompositeBuilder, ObservableListContentProvider, ViewerComparator, TableActionBar)}
	 *             instead
	 */
	@Deprecated
	// CHECKSTYLE.OFF: ParameterNumber
	protected TableViewerSWTBuilder createTableViewerSWTBuilder(Composite parent,
		@SuppressWarnings("rawtypes") IObservableList list,
		@SuppressWarnings("rawtypes") IObservableValue labelText,
		@SuppressWarnings("rawtypes") IObservableValue labelTooltipText, TableViewerCompositeBuilder compositeBuilder,
		ObservableListContentProvider cp, ECPTableViewerComparator comparator,
		TableActionBar<? extends AbstractTableViewer> actionBar) {
		// CHECKSTYLE.ON: ParameterNumber

		return createTableViewerSWTBuilder(parent, list, labelText, labelTooltipText, compositeBuilder, cp,
			(ViewerComparator) comparator,
			actionBar);
	}

	/**
	 * Creates a new {@link TableViewerSWTBuilder}.
	 *
	 * @param parent the parent {@link Composite}
	 * @param list the input object
	 * @param labelText the title
	 * @param labelTooltipText the tooltip
	 * @param compositeBuilder the {@link TableViewerCompositeBuilder}
	 * @param cp the content provider
	 * @param comparator the {@link ViewerComparator}; has no effect if move up/down
	 *            functionality is enabled
	 * @param actionBar the {@link ActionBar}
	 * @return the {@link TableViewerSWTBuilder}
	 * @since 1.22
	 *
	 */
	// CHECKSTYLE.OFF: ParameterNumber
	protected TableViewerSWTBuilder createTableViewerSWTBuilder(Composite parent,
		@SuppressWarnings("rawtypes") IObservableList list,
		@SuppressWarnings("rawtypes") IObservableValue labelText,
		@SuppressWarnings("rawtypes") IObservableValue labelTooltipText, TableViewerCompositeBuilder compositeBuilder,
		ObservableListContentProvider cp, ViewerComparator comparator,
		TableActionBar<? extends AbstractTableViewer> actionBar) {
		// CHECKSTYLE.ON: ParameterNumber
		return TableViewerFactory.fillDefaults(parent, SWT.NONE, list, labelText, labelTooltipText)
			.customizeCompositeStructure(compositeBuilder)
			.customizeActionBar(actionBar)
			.customizeTableViewerCreation(getTableViewerCreator())
			.customizeContentProvider(cp)
			.customizeComparator(comparator)
			.customizeDragAndDrop(new TableControlSWTRendererDragAndDrop());

	}

	/**
	 * Creates a new instance of the {@link TableViewerCreator} to be used.
	 *
	 * @return the {@link TableViewerCreator}
	 * @since 1.10
	 */
	protected TableViewerCreator<? extends AbstractTableViewer> getTableViewerCreator() {
		return new TableControlSWTRendererTableViewerCreator();
	}

	/**
	 * Override this method to add additional static columns at the beginning of the table.
	 *
	 * @param tableViewerSWTBuilder the builder
	 * @return the number of columns added
	 * @since 1.9
	 */
	protected int addAdditionalColumns(TableViewerSWTBuilder tableViewerSWTBuilder) {
		return 0;
	}

	/**
	 * Returns the zero-relative index of the item which is currently selected in the receiver, or -1 if no item is
	 * selected.
	 *
	 * @return the index of the selected item
	 * @since 1.10
	 */
	protected int getSelectionIndex() {
		return ((TableViewer) tableViewer).getTable().getSelectionIndex();
	}

	/**
	 * Returns an array of {@link Item items} which are the columns in the table.
	 *
	 * @return the columns of the table
	 * @since 1.10
	 */
	protected Item[] getColumns() {
		return ((TableViewer) tableViewer).getTable().getColumns();
	}

	/**
	 * Returns the receiver's horizontal scroll bar if it has one, and null if it does not.
	 *
	 * @return the horizontal scroll bar (or null)
	 * @since 1.10
	 */
	protected ScrollBar getHorizontalBar() {
		return ((TableViewer) tableViewer).getTable().getHorizontalBar();
	}

	/**
	 * Returns the receiver's vertical scroll bar if it has one, and null if it does not.
	 *
	 * @return the vertical scroll bar (or null)
	 * @since 1.10
	 */
	protected ScrollBar getVerticalBar() {
		return ((TableViewer) tableViewer).getTable().getVerticalBar();
	}

	private void addResizeListener(final Control control, final int regularColumnsStartIndex) {
		final ControlAdapter controlAdapter = new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent e) {
				updateTableColumnWidths(control, regularColumnsStartIndex);
			}
		};
		control.addControlListener(controlAdapter);

		tableViewerComposite.addColumnListener(controlAdapter);
	}

	private void updateTableColumnWidths(Control table, int regularColumnsStartIndex) {
		if (isDisposing) {
			return;
		}
		final VTableControl tableControl = getVElement();
		final Widget[] allColumns = tableViewerComposite.getColumns();
		for (int i = regularColumnsStartIndex; i < allColumns.length; i++) {
			final Widget tableColumn = allColumns[i];
			final VDomainModelReference columnDMR = getColumnDomainModelReferences().get(i - regularColumnsStartIndex);
			TableConfigurationHelper.updateWidthConfiguration(tableControl, columnDMR, tableColumn);
		}
	}

	private void initCompositeHeight() {
		final VTTableStyleProperty styleProperty = getTableStyleProperty();
		minimumHeight = styleProperty.isSetMinimumHeight() ? Optional.of(styleProperty.getMinimumHeight())
			: Optional.<Integer> empty();
		maximumHeight = styleProperty.isSetMaximumHeight() ? Optional.of(styleProperty.getMaximumHeight())
			: Optional.<Integer> empty();
		visibleLines = styleProperty.isSetVisibleLines() ? Optional.of(styleProperty.getVisibleLines())
			: Optional.<Integer> empty();
	}

	private <T> void addRelayoutListenerIfNeeded(IObservableList<T> list, final Composite composite) {
		if (list == null) {
			return;
		}

		// relayout is only needed if min height != max height
		if (!minimumHeight.isPresent() && !maximumHeight.isPresent()) {
			return;
		}
		if (minimumHeight.isPresent() && maximumHeight.isPresent() && minimumHeight.get() == maximumHeight.get()) {
			return;
		}

		final GridData gridData = GridData.class.cast(composite.getLayoutData());
		list.addListChangeListener(new IListChangeListener<T>() {
			@Override
			public void handleListChange(ListChangeEvent<? extends T> event) {
				gridData.heightHint = getTableHeightHint();
				EMFFormsSWTLayoutUtil.adjustParentSize(composite);
			}
		});
	}

	/**
	 * Adds the table columns to the {@link TableViewerSWTBuilder}.
	 *
	 * @param tableViewerSWTBuilder the builder
	 * @param clazz the {@EClass} of the rendered object
	 * @param cp the content provider
	 * @param tableConfiguration
	 *
	 */
	private void addColumns(TableViewerSWTBuilder tableViewerSWTBuilder, EClass clazz,
		ObservableListContentProvider cp) {
		InternalEObject tempInstance = null;
		if (!clazz.isAbstract() && !clazz.isInterface()) {
			tempInstance = getInstanceOf(clazz);
		}

		final List<VDomainModelReference> columns = getColumnDomainModelReferences().stream().filter(Objects::nonNull)
			.collect(Collectors.toList());
		/* regular columns */
		columnFeatures = new EStructuralFeature[columns.size()];
		for (int i = 0; i < columns.size(); i++) {
			try {
				final VDomainModelReference dmr = columns.get(i);
				final IObservableValue<?> text = getLabelTextForColumn(dmr, clazz);
				final IObservableValue<?> tooltip = getLabelTooltipTextForColumn(dmr, clazz);

				// Use the same editing domain for the columns as for the view's domain object
				final EditingDomain editingDomain = getEditingDomain(getViewModelContext().getDomainModel());
				final IValueProperty<?, ?> valueProperty = getEMFFormsDatabinding().getValueProperty(dmr, clazz,
					editingDomain);
				final EStructuralFeature eStructuralFeature = (EStructuralFeature) valueProperty.getValueType();
				columnFeatures[i] = eStructuralFeature;

				@SuppressWarnings("unchecked")
				final IObservableMap<?, ?> observableMap = valueProperty.observeDetail(cp.getKnownElements());

				final TableControlEditingSupportAndLabelProvider labelProvider = new TableControlEditingSupportAndLabelProvider(
					tempInstance, eStructuralFeature, dmr, valueProperty, observableMap,
					getColumnDomainModelReferences().indexOf(dmr));
				final EditingSupportCreator editingSupportCreator = TableConfigurationHelper
					.isReadOnly(getVElement(), dmr) ? null : labelProvider;

				final Optional<Integer> weightConfig = TableConfigurationHelper.getColumnWeight(getVElement(), dmr);
				final Optional<Integer> widthConfig = TableConfigurationHelper.getColumnWidth(getVElement(), dmr);

				int weight;
				int minWidth;
				if (weightConfig.isPresent()) {
					minWidth = widthConfig.get();
					weight = weightConfig.get();
				} else {
					// TODO ugly: we need this temporary cell editor so early just to get size information
					final Shell tempShell = new Shell();
					final CellEditor tempCellEditor = createCellEditor(tempInstance, eStructuralFeature,
						new Table(tempShell, SWT.NONE));
					weight = ECPCellEditor.class.isInstance(tempCellEditor)
						? ECPCellEditor.class.cast(tempCellEditor).getColumnWidthWeight()
						: 100;
					minWidth = ECPCellEditor.class.isInstance(tempCellEditor)
						? ECPCellEditor.class.cast(tempCellEditor).getMinWidth()
						: 10;
					tempShell.dispose();
				}

				tableViewerSWTBuilder.addColumn(
					ColumnConfigurationBuilder.from(tableViewerSWTBuilder)
						.weight(weight)
						.minWidth(minWidth)
						.text(text)
						.tooltip(tooltip)
						.labelProviderFactory(labelProvider)
						.editingSupportCreator(editingSupportCreator)
						.dataMapEntry(ColumnConfiguration.DMR, dmr)
						.build());

			} catch (final DatabindingFailedException ex) {
				getReportService().report(new RenderingFailedReport(ex));
				continue;
			}
		}

	}

	private void setupValidation(
		final AbstractTableViewerComposite<? extends AbstractTableViewer> tableViewerComposite) {
		if (tableViewerComposite.getValidationControls().isPresent()) {
			final List<Control> validationControls = tableViewerComposite.getValidationControls().get();
			if (validationControls.size() == 1 && Label.class.isInstance(validationControls.get(0))) {
				validationIcon = (Label) validationControls.get(0);
			}

			final VTTableStyleProperty tableStyleProperty = getTableStyleProperty();
			showValidationSummaryTooltip = tableStyleProperty.isShowValidationSummaryTooltip();
		}
	}

	private void setupSorting(final TableViewerComparator comparator, int regularColumnsStartIndex,
		final AbstractTableViewerComposite<? extends AbstractTableViewer> tableViewerComposite) {

		final VTTableStyleProperty tableStyleProperty = getTableStyleProperty();
		if (!tableStyleProperty.isEnableSorting()) {
			return;
		}
		final int length = tableViewerComposite.getColumns().length;
		final List<Integer> sortableColumns = new ArrayList<Integer>();
		for (int i = 0; i < length; i++) {
			if (i >= regularColumnsStartIndex) {
				sortableColumns.add(i);
			}
		}
		tableViewerComposite.setComparator(comparator, sortableColumns);
	}

	private IObservableValue<?> getLabelText(VDomainModelReference dmrToCheck) {
		switch (getVElement().getLabelAlignment()) {
		case NONE:
			return Observables.constantObservableValue("", String.class); //$NON-NLS-1$
		default:
			try {
				return getEMFFormsLabelProvider().getDisplayName(dmrToCheck, getViewModelContext().getDomainModel());
			} catch (final NoLabelFoundException e) {
				// FIXME Expectation?
				getReportService().report(new RenderingFailedReport(e));
				return Observables.constantObservableValue(e.getMessage(), String.class);
			}
		}
	}

	private IObservableValue<?> getLabelTextForColumn(VDomainModelReference dmrToCheck, EClass dmrRootEClass) {
		try {
			// See whether the view model specifies a label for the column
			final Optional<VEnablementConfiguration> config = TableConfigurationHelper
				.findEnablementConfiguration(getVElement(), dmrToCheck);
			if (config.isPresent()) {
				final String label = config.get().getLabel();
				if (label != null && !label.isEmpty()) {
					@SuppressWarnings("unchecked")
					final IValueProperty<VElement, String> labelProperty = EMFProperties
						.value(VViewPackage.Literals.ELEMENT__LABEL);
					return labelProperty.observe(config.get());
				}
			}
			return getEMFFormsLabelProvider().getDisplayName(dmrToCheck, dmrRootEClass);
		} catch (final NoLabelFoundException e) {
			// FIXME Expectation?
			getReportService().report(new RenderingFailedReport(e));
			return Observables.constantObservableValue(e.getMessage(), String.class);
		}
	}

	private IObservableValue<?> getLabelTooltipText(VDomainModelReference dmrToCheck) {
		switch (getVElement().getLabelAlignment()) {
		case NONE:
			return Observables.constantObservableValue("", String.class); //$NON-NLS-1$
		default:
			try {
				return getEMFFormsLabelProvider().getDescription(dmrToCheck, getViewModelContext().getDomainModel());
			} catch (final NoLabelFoundException e) {
				// FIXME Expectation?
				getReportService().report(new RenderingFailedReport(e));
				return Observables.constantObservableValue(e.toString(), String.class);
			}
		}
	}

	private IObservableValue<?> getLabelTooltipTextForColumn(VDomainModelReference dmrToCheck, EClass dmrRootEClass) {
		try {
			return getEMFFormsLabelProvider().getDescription(dmrToCheck, dmrRootEClass);
		} catch (final NoLabelFoundException e) {
			// FIXME Expectation?
			getReportService().report(new RenderingFailedReport(e));
			return Observables.constantObservableValue(e.toString(), String.class);
		}
	}

	/**
	 * @return the {@link VDomainModelReference} which ends at the table setting
	 * @since 1.11
	 */
	protected VDomainModelReference getDMRToMultiReference() {
		// A segment based view model uses the plain dmr
		if (getVElement().getDomainModelReference().eClass() == VViewPackage.Literals.DOMAIN_MODEL_REFERENCE) {
			return getVElement().getDomainModelReference();
		}

		final VTableDomainModelReference tableDomainModelReference = (VTableDomainModelReference) getVElement()
			.getDomainModelReference();
		final VDomainModelReference dmrToCheck = tableDomainModelReference.getDomainModelReference() == null
			? tableDomainModelReference
			: tableDomainModelReference.getDomainModelReference();
		return dmrToCheck;
	}

	/**
	 * Allows to add additional buttons to the button bar of the table control.
	 * <p>
	 * The default implementation does not add additional buttons.
	 * </p>
	 *
	 * @param buttonComposite the composite where the buttons are added
	 * @return the total number of buttons added
	 */
	protected int addButtonsToButtonBar(Composite buttonComposite) {
		return 0;
	}

	/**
	 * Creates and returns the composite which will be the parent for the table viewer.
	 *
	 * @param composite the parent composite including the title/button bar
	 * @return the parent for the table viewer
	 */
	protected Composite createControlComposite(Composite composite) {
		final Composite controlComposite = new Composite(composite, SWT.NONE);
		GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).hint(1, getTableHeightHint())
			.applyTo(controlComposite);
		GridLayoutFactory.fillDefaults().numColumns(1).applyTo(controlComposite);
		return controlComposite;
	}

	/**
	 * Returns the preferred height for the table. This will be passed to the layoutdata.
	 *
	 * @return the height in px
	 */
	// BEGIN COMPLEX CODE
	protected int getTableHeightHint() {
		/* if neither min nor max is set we use a fixed height */
		if (!minimumHeight.isPresent() && !maximumHeight.isPresent() && !visibleLines.isPresent()) {
			return 200;
		}
		// if the visible lines attribute is present, it takes precedence over the minimum & maximum height hints
		if (visibleLines.isPresent()) {
			return computeRequiredHeight(visibleLines.get());
		}
		if (minimumHeight.isPresent() && maximumHeight.isPresent() && minimumHeight.get() == maximumHeight.get()) {
			return minimumHeight.get();
		}

		final int requiredHeight = computeRequiredHeight(null);

		if (minimumHeight.isPresent() && !maximumHeight.isPresent()) {
			return requiredHeight < minimumHeight.get() ? minimumHeight.get() : requiredHeight;
		}

		if (!minimumHeight.isPresent() && maximumHeight.isPresent()) {
			return requiredHeight > maximumHeight.get() ? maximumHeight.get() : requiredHeight;
		}

		if (requiredHeight < minimumHeight.get()) {
			return minimumHeight.get();
		}

		if (requiredHeight > maximumHeight.get()) {
			return maximumHeight.get();
		}

		return requiredHeight;
	}
	// END COMPLEX CODE

	/**
	 * Returns the height in pixels required to display the given number of table items. If the visible items are not
	 * specified, the height required to display all the table items is returned.
	 *
	 * @param visibleLines the number of visible table items
	 * @return the required height
	 * @since 1.13
	 */
	protected int computeRequiredHeight(Integer visibleLines) {
		if (tableViewer == null) {
			return SWT.DEFAULT;
		}
		final TableControl table = tableViewerComposite.getTableControl();
		if (table == null) {
			return SWT.DEFAULT;
		}
		if (table.isDisposed()) {
			return SWT.DEFAULT;
		}
		final int itemHeight = table.getItemHeight();
		// show one empty row if table does not contain any items or visibleLines < 1
		int itemCount;
		if (visibleLines != null) {
			itemCount = Math.max(visibleLines, 1);
		} else {
			itemCount = Math.max(table.getItemCount(), 1);
		}
		final int headerHeight = table.getHeaderVisible() ? table.getHeaderHeight() : 0;
		// 4px needed as a buffer to avoid scrollbars
		final int tableHeight = itemHeight * itemCount + headerHeight + 4;
		return tableHeight;
	}

	/**
	 * Returns the table viewer.
	 *
	 * @return the viewer
	 * @since 1.10
	 */
	protected AbstractTableViewer getTableViewer() {
		return tableViewer;
	}

	/**
	 * Returns the {@link AbstractTableViewerComposite}.
	 *
	 * @return the table viewer composite
	 * @since 1.13
	 */
	@SuppressWarnings("rawtypes")
	protected AbstractTableViewerComposite getTableViewerComposite() {
		return tableViewerComposite;
	}

	/**
	 * Sets the table viewer.
	 *
	 * @param tableViewer the viewer
	 * @since 1.10
	 */
	protected void setTableViewer(AbstractTableViewer tableViewer) {
		this.tableViewer = tableViewer;
	}

	/**
	 * This method gets called when the selection on the {@link TableViewer} (see {@link #getTableViewer()}) has
	 * changed.
	 * <p>
	 * If you override this method make sure to call super.
	 * </p>
	 *
	 * @param event the {@link SelectionChangedEvent}
	 */
	protected void viewerSelectionChanged(SelectionChangedEvent event) {
		// The default implementation does not need to do anything
	}

	private void createFixedValidationStatusColumn(TableViewerSWTBuilder tableViewerSWTBuilder) {
		final VTTableValidationStyleProperty tableValidationStyleProperty = getTableValidationStyleProperty();
		final int columnWidth = tableValidationStyleProperty.getColumnWidth();
		final String columnName = tableValidationStyleProperty.getColumnName();
		final String imagePath = tableValidationStyleProperty.getImagePath();
		Image image = null;
		if (imagePath != null && !imagePath.isEmpty()) {
			try {
				image = getImage(new URL(imagePath));
			} catch (final MalformedURLException ex) {
				getReportService().report(new AbstractReport(ex));
			}
		}

		tableViewerSWTBuilder.addColumn(
			ColumnConfigurationBuilder.usingDefaults()
				.minWidth(columnWidth)
				.text(columnName)
				.tooltip(columnName)
				.labelProvider(new ValidationStatusCellLabelProvider(getVElement()))
				.image(image)
				.build());

	}

	/**
	 * Retrieve images from the {@link ImageRegistryService} using an {@link URL}.
	 *
	 * @param url The {@link URL} pointing to the image
	 * @return The retrieved Image
	 * @since 1.6
	 */
	protected Image getImage(URL url) {
		return imageRegistryService.getImage(url);
	}

	/**
	 * Retrieve images from the {@link ImageRegistryService} using a bundle relative path.
	 *
	 * @param path The bundle relative path pointing to the image
	 * @return The retrieved Image
	 * @since 1.6
	 */
	protected Image getImage(String path) {
		Image result = imageRegistryService.getImage(FrameworkUtil.getBundle(getClass()), path);
		if (result == null && getClass() != TableControlSWTRenderer.class) {
			result = imageRegistryService.getImage(FrameworkUtil.getBundle(TableControlSWTRenderer.class), path);
		}
		return result;
	}

	/**
	 * Returns the {@link VTTableValidationStyleProperty}.
	 *
	 * @return the {@link VTTableValidationStyleProperty}
	 * @since 1.14
	 */
	protected VTTableValidationStyleProperty getTableValidationStyleProperty() {
		VTTableValidationStyleProperty tableValidationStyleProperties = getStyleProperty(
			VTTableValidationStyleProperty.class);
		if (tableValidationStyleProperties == null) {
			tableValidationStyleProperties = createDefaultTableValidationStyleProperty();
		}
		return tableValidationStyleProperties;
	}

	/**
	 * Creates the default {@link VTTableValidationStyleProperty}.
	 *
	 * @return the default {@link VTTableValidationStyleProperty}
	 * @since 1.14
	 */
	protected VTTableValidationStyleProperty createDefaultTableValidationStyleProperty() {
		final VTTableValidationStyleProperty tableValidationProp = VTTableValidationFactory.eINSTANCE
			.createTableValidationStyleProperty();
		tableValidationProp.setColumnWidth(80);
		tableValidationProp.setColumnName(LocalizationServiceHelper.getString(TableControlSWTRenderer.class,
			MessageKeys.TableControl_ValidationStatusColumn));
		tableValidationProp.setImagePath(null);
		return tableValidationProp;
	}

	/**
	 * Returns the {@link VTBackgroundStyleProperty}.
	 *
	 * @return the {@link VTBackgroundStyleProperty}
	 *
	 * @since 1.10
	 */
	protected VTBackgroundStyleProperty getBackgroundStyleProperty() {
		VTBackgroundStyleProperty styleProperty = getStyleProperty(VTBackgroundStyleProperty.class);
		if (styleProperty == null) {
			styleProperty = createDefaultBackgroundStyleProperty();
		}
		return styleProperty;
	}

	/**
	 * Creates the default {@link VTBackgroundStyleProperty}.
	 *
	 * @return the default {@link VTBackgroundStyleProperty}
	 * @since 1.14
	 */
	protected VTBackgroundStyleProperty createDefaultBackgroundStyleProperty() {
		return VTBackgroundFactory.eINSTANCE.createBackgroundStyleProperty();
	}

	/**
	 * Returns the {@link VTTableStyleProperty}.
	 *
	 * @return the {@link VTTableStyleProperty}
	 * @since 1.14
	 */
	protected VTTableStyleProperty getTableStyleProperty() {
		VTTableStyleProperty styleProperty = getStyleProperty(VTTableStyleProperty.class);
		if (styleProperty == null) {
			styleProperty = createDefaultTableStyleProperty();
		}
		return styleProperty;
	}

	/**
	 * Creates the default {@link VTTableStyleProperty}.
	 *
	 * @return the default {@link VTTableStyleProperty}
	 * @since 1.14
	 */
	protected VTTableStyleProperty createDefaultTableStyleProperty() {
		final VTTableStyleProperty tableStyleProperty = VTTableStylePropertyFactory.eINSTANCE
			.createTableStyleProperty();
		tableStyleProperty.setMaximumHeight(200);
		if (!getVElement().isEffectivelyReadonly()) {
			tableStyleProperty.setMinimumHeight(200);
		}
		return tableStyleProperty;
	}

	/**
	 * Returns the {@link VTFontPropertiesStyleProperty}.
	 *
	 * @return the {@link VTFontPropertiesStyleProperty}
	 * @since 1.10
	 */
	protected VTFontPropertiesStyleProperty getFontPropertiesStyleProperty() {
		VTFontPropertiesStyleProperty styleProperty = getStyleProperty(VTFontPropertiesStyleProperty.class);
		if (styleProperty == null) {
			styleProperty = createDefaultFontPropertiesStyleProperty();
		}
		return styleProperty;
	}

	/**
	 * Creates the default {@link VTFontPropertiesStyleProperty}.
	 *
	 * @return the default {@link VTFontPropertiesStyleProperty}
	 * @since 1.14
	 */
	protected VTFontPropertiesStyleProperty createDefaultFontPropertiesStyleProperty() {
		final VTFontPropertiesStyleProperty property = VTFontPropertiesFactory.eINSTANCE
			.createFontPropertiesStyleProperty();
		property.setColorHEX("000000"); //$NON-NLS-1$
		return property;
	}

	private <SP extends VTStyleProperty> SP getStyleProperty(Class<SP> stylePropertyClass) {
		return RendererUtil.getStyleProperty(getVTViewTemplateProvider(), getVElement(), getViewModelContext(),
			stylePropertyClass);
	}

	/**
	 * Returns the {@link Color} specified by the provided String.
	 *
	 * @param colorHex the Hex String describing the color
	 * @return the {@link Color}
	 * @since 1.10
	 *
	 */
	protected Color getSWTColor(String colorHex) {
		final String redString = colorHex.substring(0, 2);
		final String greenString = colorHex.substring(2, 4);
		final String blueString = colorHex.substring(4, 6);
		final int red = Integer.parseInt(redString, 16);
		final int green = Integer.parseInt(greenString, 16);
		final int blue = Integer.parseInt(blueString, 16);
		return new Color(Display.getDefault(), red, green, blue);
	}

	/**
	 * Retrieves this table's column DMRs from the table DMR.
	 *
	 * @return The domain model references defining the columns of this table.
	 * @since 1.19
	 */
	protected EList<VDomainModelReference> getColumnDomainModelReferences() {
		final VDomainModelReference dmr = getVElement().getDomainModelReference();
		final java.util.Optional<VMultiDomainModelReferenceSegment> multiSegment = MultiSegmentUtil
			.getMultiSegment(dmr);
		if (multiSegment.isPresent()) {
			return multiSegment.get().getChildDomainModelReferences();
		}
		return VTableDomainModelReference.class.cast(dmr).getColumnDomainModelReferences();
	}

	/**
	 * This is called in order to setup the editing support for a table column.
	 *
	 * @param tempInstance the temporary input instance of the table
	 * @param feature the feature of the column
	 * @param table the table/parent
	 * @return the cell editor
	 * @since 1.10
	 */
	protected CellEditor createCellEditor(final EObject tempInstance, final EStructuralFeature feature,
		Composite table) {
		return CellEditorFactory.INSTANCE.getCellEditor(feature,
			tempInstance, table, getViewModelContext());
	}

	private InternalEObject getInstanceOf(EClass clazz) {
		return InternalEObject.class.cast(clazz.getEPackage().getEFactoryInstance().create(clazz));
	}

	/**
	 * This method shows a user confirmation dialog when the user attempts to delete a row in the table.
	 *
	 * @deprecated this method will be moved to {@link RemoveRowAction} in the future
	 * @param deletionList the list of selected EObjects to delete
	 * @param eObject The containment reference {@link EObject}
	 * @param structuralFeature The containment reference {@link EStructuralFeature}
	 * @param addButton the add button
	 * @param removeButton the remove button
	 * @since 1.6
	 */
	@Deprecated
	protected void deleteRowUserConfirmDialog(final List<EObject> deletionList, final EObject eObject,
		final EStructuralFeature structuralFeature, final Button addButton, final Button removeButton) {
		final MessageDialog dialog = new MessageDialog(addButton.getShell(),
			LocalizationServiceHelper.getString(TableControlSWTRenderer.class, MessageKeys.TableControl_Delete), null,
			LocalizationServiceHelper.getString(TableControlSWTRenderer.class,
				MessageKeys.TableControl_DeleteAreYouSure),
			MessageDialog.CONFIRM, new String[] {
				JFaceResources.getString(IDialogLabelKeys.YES_LABEL_KEY),
				JFaceResources.getString(IDialogLabelKeys.NO_LABEL_KEY) },
			0);

		new ECPDialogExecutor(dialog) {

			@Override
			public void handleResult(int codeResult) {
				if (codeResult == IDialogConstants.CANCEL_ID
					|| codeResult == SWT.DEFAULT) { // SWT.DEFAULT is return by closing a message dialog
					return;
				}

				deleteRows(deletionList, eObject, structuralFeature);

				final List<?> containments = (List<?>) eObject.eGet(structuralFeature, true);
				if (containments.size() < structuralFeature.getUpperBound()) {
					addButton.setEnabled(true);
				}
				if (containments.size() <= structuralFeature.getLowerBound()) {
					removeButton.setEnabled(false);
				}
			}
		}.execute();
	}

	/**
	 * This is called by {@link #deleteRowUserConfirmDialog(List)} after the user confirmed to delete the selected
	 * elements.
	 *
	 * @deprecated this method will be moved to {@link RemoveRowAction} in the future
	 * @param deletionList the list of {@link EObject EObjects} to delete
	 * @param eObject The containment reference {@link EObject}
	 * @param structuralFeature The containment reference {@link EStructuralFeature}
	 * @since 1.6
	 */
	@Deprecated
	protected void deleteRows(List<EObject> deletionList, final EObject eObject,
		final EStructuralFeature structuralFeature) {

		final EditingDomain editingDomain = getEditingDomain(eObject);

		/* assured by #isApplicable */
		final EReference reference = EReference.class.cast(structuralFeature);
		final List<Object> toDelete = new ArrayList<Object>(deletionList);
		if (reference.isContainment()) {
			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(toDelete);
		} else {
			removeElements(editingDomain, eObject, reference, toDelete);
		}
	}

	private void removeElements(EditingDomain editingDomain, Object source, EStructuralFeature feature,
		Collection<Object> toRemove) {
		final Command removeCommand = RemoveCommand.create(editingDomain, source, feature, toRemove);
		if (removeCommand.canExecute()) {
			if (editingDomain.getCommandStack() == null) {
				removeCommand.execute();
			} else {
				editingDomain.getCommandStack().execute(removeCommand);
			}
		}
	}

	/**
	 * This method is called to add a new entry in the domain model and thus to create a new row in the table. The
	 * element to create is defined by the provided class.
	 * You can override this method but you have to call super nonetheless.
	 *
	 * @deprecated this method will be move to {@link AddRowAction} in the future
	 * @param clazz the {@link EClass} defining the EObject to create
	 * @param eObject The containment reference {@link EObject}
	 * @param structuralFeature The containment reference {@link EStructuralFeature}
	 * @since 1.6
	 */
	@Deprecated
	protected void addRow(EClass clazz, EObject eObject, EStructuralFeature structuralFeature) {
		Optional<EObject> eObjectToAdd = null;

		/* table service available => use specific behavior to create row */
		if (getViewModelContext().hasService(TableControlService.class)) {
			final TableControlService tableService = getViewModelContext()
				.getService(TableControlService.class);
			eObjectToAdd = tableService.createNewElement(clazz, eObject, structuralFeature);
		}
		/* no table service available, fall back to default */
		if (eObjectToAdd == null) {
			final ReferenceService referenceService = getViewModelContext().getService(ReferenceService.class);
			eObjectToAdd = referenceService.addNewModelElements(eObject, EReference.class.cast(structuralFeature),
				false);
		}

		if (!eObjectToAdd.isPresent()) {
			return;
		}

		final EObject instance = eObjectToAdd.get();
		final EditingDomain editingDomain = getEditingDomain(eObject);
		if (editingDomain == null) {
			return;
		}
		editingDomain.getCommandStack().execute(
			AddCommand.create(editingDomain, eObject, structuralFeature, instance));
		tableViewer.setSelection(new StructuredSelection(eObjectToAdd.get()), true);

	}

	@Override
	protected void applyValidation(VDiagnostic oldDiagnostic, VDiagnostic newDiagnostic) {
		getRunnableManager().executeAsync(new ComputeValidationUpdate(oldDiagnostic, newDiagnostic));
	}

	@Override
	protected void applyValidation() {
		if (!getRunnableManager().isRunning()) {
			getRunnableManager().executeAsync(new ApplyValidationRunnable());
		}
	}

	/**
	 * Obtain my runnable manager (visible for testability).
	 *
	 * @return my runnable manager
	 */
	final RunnableManager getRunnableManager() {
		return runnableManager;
	}

	/**
	 * Post a request to refresh my {@linkplain #getTableViewer() viewer} on the
	 * asynchronous refresh manager.
	 *
	 * @since 1.21
	 * @see #getTableViewer()
	 * @see ViewerRefreshManager
	 */
	protected void postRefresh() {
		postRefresh(getRefreshRunnable(getTableViewer()));
	}

	/**
	 * Post a refresh request on the asynchronous refresh manager.
	 *
	 * @param refreshRunnable the refresh operation to execute
	 * @since 1.21
	 * @see ViewerRefreshManager
	 */
	protected void postRefresh(Runnable refreshRunnable) {
		final Viewer viewer = getTableViewer();
		if (viewer != null && !viewer.getControl().isDisposed()) {
			getRunnableManager().executeAsync(refreshRunnable);
		}
	}

	/**
	 * Returns the add button created by the framework.
	 *
	 * @deprecated use {@link #getControlForAction(String)} instead
	 * @return the addButton
	 * @since 1.6
	 */
	@Deprecated
	protected Button getAddButton() {
		final Optional<Control> control = getControlForAction(AddRowAction.ACTION_ID);
		if (control.isPresent()) {
			return (Button) control.get();
		}
		return null; // happens when add/remove has been disabled in the view model
	}

	/**
	 * Returns the remove button created by the framework.
	 *
	 * @deprecated use {@link #getControlForAction(String)} instead
	 * @return the removeButton
	 * @since 1.6
	 */
	@Deprecated
	protected Button getRemoveButton() {
		final Optional<Control> control = getControlForAction(RemoveRowAction.ACTION_ID);
		if (control.isPresent()) {
			return (Button) control.get();
		}
		return null; // happens when add/remove has been disabled in the view model
	}

	/**
	 * Returns the control created to trigger a certain action.
	 *
	 * @param actionId the action ID of the action that is bound to the control
	 * @return an optional for the control of the given action ID
	 * @since 1.18
	 */
	public Optional<Control> getControlForAction(String actionId) {
		if (tableViewerComposite.getActionBar().isPresent()) {
			return tableViewerComposite.getActionBar().get().getControlById(actionId);
		}
		return Optional.empty();
	}

	/**
	 * Helper method which uses an EMFForms observable value to get the setting for the given
	 * {@link VDomainModelReference}.
	 *
	 * @param dmr the {@link VDomainModelReference}
	 * @param eObject the {@link EObject} to get the setting for
	 * @return an Optional<Setting>
	 *
	 * @since 1.17
	 */
	protected Optional<Setting> getSettingFromObservable(VDomainModelReference dmr, EObject eObject) {
		@SuppressWarnings("rawtypes")
		IObservableValue observableValue = null;
		try {
			observableValue = getEMFFormsDatabinding().getObservableValue(dmr, eObject);

			final EStructuralFeature feature = (EStructuralFeature) observableValue.getValueType();
			final EObject observed = (EObject) ((IObserving) observableValue).getObserved();

			// Given EClass has no such feature
			if (observed == null || observed.eClass().getFeatureID(feature) == -1) {
				return Optional.empty();
			}

			return Optional.of(((InternalEObject) observed).eSetting(feature));

		} catch (final DatabindingFailedException ex) {
			getReportService().report(new DatabindingFailedReport(ex));
			return Optional.empty();
		} finally {
			if (observableValue != null) {
				observableValue.dispose();
			}
		}

	}

	@Override
	protected void applyEnable() {
		updateActionBar();
	}

	@Override
	protected void applyReadOnly() {
		updateActionBar();
	}

	@Override
	protected void applyUnchangeableFeature() {
		getVElement().setAddRemoveDisabled(true);
		getVElement().setDuplicateDisabled(true);
		getVElement().setMoveUpDownDisabled(true);
		updateActionBar();
	}

	/**
	 * Update this table control's action bar if it is present.
	 *
	 * @since 1.20
	 */
	protected void updateActionBar() {
		if (tableViewerComposite != null && tableViewerComposite.getActionBar().isPresent()) {
			tableViewerComposite.getActionBar().get().updateActionBar();
		}
	}

	@Override
	protected void dispose() {
		isDisposing = true;
		rendererGridDescription = null;
		viewModelDBC.dispose();
		if (list != null) {
			list.dispose();
		}
		if (columnIndexToComparatorMap != null) {
			for (final ECPCellEditorComparator value : columnIndexToComparatorMap.values()) {
				if (value instanceof CellEditor) {
					((CellEditor) value).dispose();
				}
			}
			columnIndexToComparatorMap.clear();
		}
		if (tableViewerComposite != null) {
			tableViewerComposite.dispose();
			tableViewerComposite = null;
		}
		if (tableViewer != null) {
			tableViewer.getControl().dispose();
			tableViewer = null;
		}

		if (customization != null) {
			for (final ColumnConfiguration columnConfig : customization.getColumnConfigurations()) {
				columnConfig.visible().dispose();
				columnConfig.dispose();
			}
			customization.getTableConfiguration().dispose();
		}

		if (autoSortModelChangeListener != null) {
			getViewModelContext().unregisterDomainChangeListener(autoSortModelChangeListener);
			autoSortModelChangeListener = null;
		}
		super.dispose();
	}

	/**
	 * Get called by the {@link ECPTableViewerComparator} in order to compare the given objects.
	 *
	 * @param viewer the table viewer
	 * @param left the first object of the comparison
	 * @param right the second object of the comparison
	 * @param propertyIndex index of the selection column. the index is aligned with the index of the associated column
	 *            domain model reference
	 * @param direction 0 (no sorting = insertion order := {@link SWT#NONE}), 1 (ascending := {@link SWT#DOWN}) or 2
	 *            (descending := {@link SWT#UP}) according to the indication displayed at
	 *            the table column.
	 * @return a negative number if the first element is less than the
	 *         second element; the value <code>0</code> if the first element is
	 *         equal to the second element; and a positive number if the first
	 *         element is greater than the second element
	 * @since 1.8
	 */
	// BEGIN COMPLEX CODE
	@SuppressWarnings("unchecked")
	protected int compare(Viewer viewer, Object left, Object right, int direction, int propertyIndex) {
		if (direction == 0) {
			return 0;
		}

		// We might have ignored columns at the beginning
		propertyIndex = propertyIndex - regularColumnsStartIndex;
		if (propertyIndex < 0) {
			return 0;
		}
		int rc = 0;

		final VDomainModelReference dmr = getColumnDomainModelReferences().get(propertyIndex);

		final Optional<Setting> leftSetting = getSettingFromObservable(dmr, (EObject) left);
		final Optional<Setting> rightSetting = getSettingFromObservable(dmr, (EObject) right);

		final Object leftValue = leftSetting.isPresent() ? leftSetting.get().get(true) : null;
		final Object rightValue = rightSetting.isPresent() ? rightSetting.get().get(true) : null;

		if (columnIndexToComparatorMap.containsKey(propertyIndex)) {
			return columnIndexToComparatorMap.get(propertyIndex).compare(leftValue, rightValue, direction);
		}

		if (leftValue == null) {
			if (rightValue == null) {
				rc = 0;
			} else {
				rc = 1;
			}
		} else if (rightValue == null) {
			rc = -1;
		} else {
			if (leftValue instanceof Enumerator) {
				final EStructuralFeature feature = leftSetting.get().getEStructuralFeature();
				rc = getEnumeratorComparator().compare(feature, (Enumerator) leftValue, (Enumerator) rightValue);
			} else if (!(leftValue instanceof String) && leftValue instanceof Comparable
				&& leftValue.getClass().isInstance(rightValue)) {
				rc = Comparable.class.cast(leftValue).compareTo(rightValue);
			} else {
				rc = NumberAwareStringComparator.getInstance().compare(leftValue.toString(), rightValue.toString());
			}
		}
		// If descending order, flip the direction
		if (direction == 2) {
			rc = -rc;
		}
		return rc;
	}
	// END COMPLEX CODE

	@Override
	protected void rootDomainModelChanged() throws DatabindingFailedException {

		final IObservableList<?> oldList = (IObservableList<?>) getTableViewer().getInput();
		oldList.dispose();

		final EObject domainModel = getViewModelContext().getDomainModel();
		final IObservableList<?> list = getEMFFormsDatabinding().getObservableList(getDMRToMultiReference(),
			domainModel);
		getTableViewer().setInput(list);

		if (tableViewerComposite.getActionBar().isPresent()) {
			tableViewerComposite.getActionBar().get().updateActionBar();
		}
	}

	/**
	 * Checks whether an element is editable or not.
	 *
	 * @param element The list entry to be checked
	 * @return True if the element can be edited, false otherwise
	 *
	 * @since 1.11
	 */
	protected boolean canEditObject(Object element) {
		return true;
	}

	/**
	 * Defined whether a cell editor should be created or not.
	 *
	 * @param element The table entry to be checked
	 * @return True if a CellEditor should be created, false otherwise
	 * @since 1.12
	 */
	protected boolean shouldCreateCellEditor(Object element) {
		final boolean isObjectEditable = canEditObject(element);
		if (!isObjectEditable) {
			return false;
		}
		final boolean editable = getVElement().isEffectivelyEnabled()
			&& !getVElement().isEffectivelyReadonly();
		return editable;
	}

	private boolean isDisabled(EObject eObject, VDomainModelReference columnDmr) {

		final Optional<VEnablementConfiguration> enablmentConf = TableConfigurationHelper
			.findEnablementConfiguration(getVElement(), columnDmr);

		if (enablmentConf.isPresent()) {
			return !enablmentConf.get().isEnabled();
		}

		return false;
	}

	/**
	 * Called by the {@link TableControlEditingSupportAndLabelProvider}.
	 *
	 * @param feature the feature of the column
	 * @param cellEditor the cell editor for the column
	 * @param attributeMap the attribute map displayed in the table
	 * @param vTableControl the table view model element
	 * @param dmr the domain model reference of the column
	 * @param table the table control
	 * @return the {@link CellLabelProvider} of the column
	 * @since 1.12
	 */
	protected CellLabelProvider createCellLabelProvider(
		EStructuralFeature feature,
		CellEditor cellEditor,
		@SuppressWarnings("rawtypes") IObservableMap attributeMap,
		VTableControl vTableControl,
		VDomainModelReference dmr,
		Control table) {
		return new ECPCellLabelProvider(
			feature,
			cellEditor,
			attributeMap,
			getVElement(),
			dmr,
			table);
	}

	/**
	 * @return The {@link FeatureAwareComparator} used to compare {@link Enumerator enum values} when sorting the table
	 * @since 1.22
	 */
	protected FeatureAwareComparator<Enumerator> getEnumeratorComparator() {
		if (enumeratorComparator == null) {
			enumeratorComparator = new LocalizedEnumeratorComparator(localizationService, bundleResolver,
				getReportService());
		}
		return enumeratorComparator;
	}

	/**
	 * Reeveal the given {@code object} in my table.
	 *
	 * @param object an object to reveal
	 * @return whether I succeeded in revealing it
	 *
	 * @since 1.22
	 */
	public boolean reveal(Object object) {
		final AbstractTableViewer viewer = getTableViewer();
		final IObservableList<?> list = (IObservableList<?>) viewer.getInput();
		final boolean result = list.contains(object);

		if (result) {
			final IStructuredSelection selection = new StructuredSelection(object);
			if (!selection.equals(viewer.getSelection())) {
				viewer.setSelection(selection, true);
			}
		} else {
			viewer.reveal(object);
		}

		return result;
	}

	/**
	 * The {@link DNDProvider} for this renderer.
	 *
	 * @author Johannes Faltermeier
	 *
	 */
	private final class TableControlSWTRendererDragAndDrop implements DNDProvider {

		/**
		 * The drop adapter.
		 */
		private final class TableControlDropAdapter extends EditingDomainViewerDropAdapter {

			private EObject eObject;
			private EStructuralFeature eStructuralFeature;
			private List<Object> list;

			@SuppressWarnings("unchecked")
			TableControlDropAdapter(EditingDomain domain, Viewer viewer, AbstractTableViewer tableViewer) {
				super(domain, viewer);
				try {
					final Setting setting = getEMFFormsDatabinding().getSetting(getDMRToMultiReference(),
						getViewModelContext().getDomainModel());
					eObject = setting.getEObject();
					eStructuralFeature = setting.getEStructuralFeature();
					list = (List<Object>) setting.get(true);
				} catch (final DatabindingFailedException ex) {
					getReportService().report(new AbstractReport(ex));
				}
			}

			@Override
			protected void helper(DropTargetEvent event) {
				final Object target = extractDropTarget(event.item);
				final Collection<?> dragSource = getDragSource(event);

				if (dragSource == null) {
					/* possible on non-win32 platforms */
					/* in this case we will just wait until the data is available without setting a detail */
					return;
				}

				if (target == null || dragSource.contains(target)) {
					event.detail = DND.DROP_NONE;
					return;
				}

				event.detail = DND.DROP_MOVE;
			}

			@Override
			public void drop(DropTargetEvent event) {

				final Collection<?> dragSource = getDragSource(event);
				final Object target = extractDropTarget(event.item);
				final float location = getLocation(event);

				final List<Command> commands = new ArrayList<Command>();
				final boolean insertAfter = location >= 0.5;

				for (final Object toMove : dragSource) {
					final int indexTarget = list.indexOf(target);
					final int indexToMove = list.indexOf(toMove);

					if (indexTarget == -1 || indexToMove == -1) {
						return;
					}

					final boolean moveIsLocatedBeforeTarget = indexToMove < indexTarget;

					int index;
					if (insertAfter) {
						if (moveIsLocatedBeforeTarget) {
							index = indexTarget;
						} else {
							index = indexTarget + 1;
						}
					} else {
						/* insert Before Target */
						if (moveIsLocatedBeforeTarget) {
							index = indexTarget - 1;
						} else {
							index = indexTarget;
						}
					}

					commands.add(MoveCommand.create(domain, eObject, eStructuralFeature, toMove, index));
				}

				final Command command = new CompoundCommand(commands);

				if (!command.canExecute()) {
					return;
				}
				domain.getCommandStack().execute(command);

				postRefresh();
			}
		}

		@Override
		public int getDragOperations() {
			return getDNDOperations();
		}

		@Override
		public Transfer[] getDragTransferTypes() {
			return getDNDTransferTypes();
		}

		@Override
		public DragSourceListener getDragListener(AbstractTableViewer tableViewer) {
			return new ViewerDragAdapter(tableViewer);
		}

		@Override
		public int getDropOperations() {
			return getDNDOperations();
		}

		@Override
		public Transfer[] getDropTransferTypes() {
			return getDNDTransferTypes();
		}

		@Override
		public DropTargetListener getDropListener(final AbstractTableViewer tableViewer) {
			return new TableControlDropAdapter(getEditingDomain(getViewModelContext().getDomainModel()), tableViewer,
				tableViewer);
		}

		private int getDNDOperations() {
			return DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
		}

		private Transfer[] getDNDTransferTypes() {
			return new Transfer[] { LocalTransfer.getInstance() };
		}

		@Override
		public boolean hasDND() {
			return true;
		}
	}

	/**
	 * Double click listener.
	 *
	 */
	private final class DoubleClickListener implements IDoubleClickListener {
		@Override
		public void doubleClick(DoubleClickEvent event) {
			if (!getViewModelContext().hasService(TableControlService.class)) {
				return;
			}
			final ISelection selection = event.getSelection();
			if (!StructuredSelection.class.isInstance(selection)) {
				return;
			}
			final TableControlService tableService = getViewModelContext()
				.getService(TableControlService.class);
			tableService.doubleClick(getVElement(),
				(EObject) StructuredSelection.class.cast(selection).getFirstElement());
		}
	}

	/**
	 * The Listener which is set on the table viewer to inform the renderer about selection changes.
	 *
	 */
	private final class ViewerSelectionChangedListener implements ISelectionChangedListener {
		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			viewerSelectionChanged(event);
		}
	}

	/**
	 * A two-stage asynchronous task that first, in the background, computes the objects
	 * that have actually seen validation changes and then post the viewer update
	 * on the UI thread.
	 */
	private final class ComputeValidationUpdate implements Runnable, RunnableManager.BackgroundStage {
		private final Set<Diagnostic> oldDiagnostics;
		private final Set<Diagnostic> newDiagnostics;

		private Runnable update;

		/**
		 * Initializes me with the old and new diagnostics from which to compute the objects
		 * that need to be updated in my viewer.
		 *
		 * @param oldDiagnostic the old validation state
		 * @param newDiagnostic the new validation state
		 */
		ComputeValidationUpdate(VDiagnostic oldDiagnostic, VDiagnostic newDiagnostic) {
			super();

			// These have to be extracted on the calling thread because the ELists
			// are not thread-safe
			oldDiagnostics = getDiagnostics(oldDiagnostic);
			newDiagnostics = getDiagnostics(newDiagnostic);
		}

		@Override
		public Runnable getNextStage() {
			return update;
		}

		@Override
		public void run() {
			// Compute the difference between the diagnostics to find what actually
			// are the logical changes in validation that will need updates in the UI
			final Set<Diagnostic> difference = difference(oldDiagnostics, newDiagnostics);
			final Set<Object> updates = difference.stream().map(this::getSubject).filter(Objects::nonNull)
				.collect(Collectors.toSet());
			if (!updates.isEmpty()) {
				update = new ApplyValidationRunnable(updates);
			} // Otherwise we don't need the UI update stage
		}

		private Set<Diagnostic> getDiagnostics(VDiagnostic container) {
			return container == null ? Collections.emptySet()
				: container.getDiagnostics().stream()
					.filter(Diagnostic.class::isInstance).map(Diagnostic.class::cast)
					.collect(Collectors.toSet());
		}

		private Object getSubject(Diagnostic diagnostic) {
			final List<?> data = diagnostic.getData();
			return data.isEmpty() ? null : data.get(0);
		}

		private Set<Diagnostic> difference(Set<Diagnostic> set1, Set<Diagnostic> set2) {
			// Diagnostics do not implement equals(), so we have to do it for them.
			// Most straightforward approach is to use a tree set, which uses the
			// comparator's zero result to test equality
			final SortedSet<Diagnostic> sorted1 = new TreeSet<>(this::compare);
			sorted1.addAll(set1);
			final SortedSet<Diagnostic> sorted2 = new TreeSet<>(this::compare);
			sorted2.addAll(set2);

			// Difference each side
			sorted1.removeAll(set2);
			sorted2.removeAll(set1);

			// And the union of that
			sorted1.addAll(sorted2);

			return sorted1;
		}

		private int compare(Diagnostic d1, Diagnostic d2) {
			int result = d1.getSeverity() - d2.getSeverity();
			if (result != 0) {
				return result;
			}

			result = d1.getCode() - d2.getCode();
			if (result != 0) {
				return result;
			}

			result = compare(d1.getSource(), d2.getSource());
			if (result != 0) {
				return result;
			}

			result = compare(d1.getMessage(), d2.getMessage());
			if (result != 0) {
				return result;
			}

			result = compare(d1.getData(), d2.getData());

			// The diagnostics from validation should not have exceptions and
			// the children are immaterial because we've already flattened them

			return result;
		}

		private int compare(String s1, String s2) {
			if (s1 == null) {
				return s2 == null ? 0 : -1;
			}
			if (s2 == null) {
				return +1;
			}
			return s1.compareTo(s2);
		}

		private int compare(List<?> s1, List<?> s2) {
			if (s1 == null) {
				return s2 == null ? 0 : -1;
			}
			if (s2 == null) {
				return +1;
			}

			final int size = s1.size();
			int result = size - s2.size();
			if (result != 0) {
				return result;
			}

			int i = 0;
			for (i = 0; i < size; i++) {
				final Object e1 = s1.get(i);
				final Object e2 = s2.get(i);
				if (e1 != e2) {
					// Arbitrary but stable order
					result = System.identityHashCode(e1) - System.identityHashCode(e2);
					break;
				}
			}

			return result;
		}
	}

	/**
	 * Runnable which is called by {@link TableControlSWTRenderer#applyValidation() applyValidation}.
	 *
	 */
	private final class ApplyValidationRunnable implements Runnable {
		private Collection<?> updates;

		ApplyValidationRunnable() {
			super();
		}

		ApplyValidationRunnable(Collection<?> updates) {
			super();

			this.updates = updates;
		}

		@Override
		public void run() {
			if (isDisposing) {
				return;
			}
			// triggered due to another validation rule before this control is rendered
			// validation rule triggered after the control was disposed
			if (validationIcon == null || validationIcon.isDisposed()) {
				return;
			}

			// no diagnostic set
			if (getVElement().getDiagnostic() == null) {
				return;
			}

			final VDomainModelReference dmr = getDMRToMultiReference();
			final Optional<Setting> setting = getSettingFromObservable(dmr, getViewModelContext().getDomainModel());

			if (!setting.isPresent()) {
				return;
			}

			validationIcon.setImage(getValidationIcon());
			showValidationSummaryTooltip(setting.get(), showValidationSummaryTooltip);

			if (updates != null) {
				// Update these specific objects
				getTableViewer().update(updates.toArray(), null);
			} else {
				// Just refresh everything. We are already in the RunnableManager
				// context, so don't post but do it directly
				getTableViewer().refresh();
			}
		}

		// extracted in order to avoid checkstyle complexity warning
		private void showValidationSummaryTooltip(Setting tableSetting, boolean doShow) {
			if (doShow) {
				validationIcon.setToolTipText(ECPTooltipModifierHelper.modifyString(getVElement().getDiagnostic()
					.getMessage(), null));
				return;
			}

			// Even if the display of a validation summary tooltip is disabled, we still show validation errors directly
			// related to the table feature (e.g. multiplicity errors)
			final StringBuilder builder = new StringBuilder();
			final List<Diagnostic> tableDiagnostics = getVElement().getDiagnostic()
				.getDiagnostic(tableSetting.getEObject(), tableSetting.getEStructuralFeature());
			for (final Diagnostic diagnostic : tableDiagnostics) {
				builder.append(diagnostic.getMessage());
				builder.append("\n"); //$NON-NLS-1$
			}
			final String toolTipText = ECPTooltipModifierHelper.modifyString(builder.toString().trim(), null);
			validationIcon.setToolTipText(toolTipText);
		}
	}

	/**
	 * Implements {@link EditingSupportCreator} and {@link CellLabelProviderFactory} for the table control swt renderer.
	 *
	 * This allows us to access the actual cell editor from the cell label provider.
	 *
	 * @author Johannes Faltermeier
	 *
	 */
	protected final class TableControlEditingSupportAndLabelProvider
		implements EditingSupportCreator, CellLabelProviderFactory {
		private final InternalEObject tempInstance;
		private final EStructuralFeature eStructuralFeature;
		private final VDomainModelReference dmr;
		private final IValueProperty<?, ?> valueProperty;
		private final IObservableMap<?, ?> observableMap;

		private CellEditor cellEditor;
		private ECPTableEditingSupport observableSupport;

		private boolean initialized;
		private final int indexOfColumn;

		private TableControlEditingSupportAndLabelProvider(InternalEObject tempInstance,
			EStructuralFeature eStructuralFeature, VDomainModelReference dmr,
			IValueProperty<?, ?> valueProperty, IObservableMap<?, ?> observableMap, int indexOfColumn) {
			this.tempInstance = tempInstance;
			this.eStructuralFeature = eStructuralFeature;
			this.dmr = dmr;
			this.valueProperty = valueProperty;
			this.observableMap = observableMap;
			this.indexOfColumn = indexOfColumn;
		}

		@Override
		public EditingSupport createEditingSupport(AbstractTableViewer tableViewer) {
			if (!initialized) {
				init(tableViewer);
			}
			return observableSupport;
		}

		private void init(AbstractTableViewer tableViewer) {
			cellEditor = createCellEditor(tempInstance, eStructuralFeature,
				(Composite) tableViewer.getControl());
			if (cellEditor instanceof ECPViewerAwareCellEditor) {
				((ECPViewerAwareCellEditor) cellEditor).setTableViewer(tableViewer);
				((ECPViewerAwareCellEditor) cellEditor).setTableFeature((EReference) list.getElementType());
			}
			tableViewer.getControl().addDisposeListener(new DisposeListener() {

				@Override
				public void widgetDisposed(DisposeEvent arg0) {
					cellEditor.dispose();
				}
			});
			if (ECPCellEditorComparator.class.isInstance(cellEditor)) {
				columnIndexToComparatorMap.put(indexOfColumn, ECPCellEditorComparator.class.cast(cellEditor));
			}
			observableSupport = new ECPTableEditingSupport(tableViewer, cellEditor, dmr, valueProperty);
			initialized = true;
		}

		@Override
		public CellLabelProvider createCellLabelProvider(AbstractTableViewer table) {
			if (!initialized) {
				init(table);
			}
			return TableControlSWTRenderer.this.createCellLabelProvider(eStructuralFeature, cellEditor, observableMap,
				getVElement(), dmr, table.getControl());
		}
	}

	/**
	 * {@link TableViewerCreator} for the table control swt renderer. It will create a GridTableViewer with the expected
	 * custom variant data and the correct style properties as defined in the template model.
	 *
	 * @since 1.10
	 *
	 */
	protected class TableControlSWTRendererTableViewerCreator implements TableViewerCreator<TableViewer> {

		@Override
		public TableViewer createTableViewer(Composite parent) {
			final TableViewer tableViewer = new TableViewer(parent,
				SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
			tableViewer.getTable().setData(CUSTOM_VARIANT, TABLE_CUSTOM_VARIANT);
			tableViewer.getTable().setHeaderVisible(true);
			tableViewer.getTable().setLinesVisible(true);

			/* Set background color */
			final VTBackgroundStyleProperty backgroundStyleProperty = getBackgroundStyleProperty();
			if (backgroundStyleProperty.getColor() != null) {
				tableViewer.getTable().setBackground(getSWTColor(backgroundStyleProperty.getColor()));
			}

			/* Set foreground color */
			final VTFontPropertiesStyleProperty fontPropertiesStyleProperty = getFontPropertiesStyleProperty();
			if (fontPropertiesStyleProperty.getColorHEX() != null) {
				tableViewer.getTable()
					.setForeground(getSWTColor(fontPropertiesStyleProperty.getColorHEX()));
			}

			tableViewer.getTable().setData(FIXED_COLUMNS, new Integer(1));

			/* manage editing support activation */
			createTableViewerEditor(tableViewer);
			return tableViewer;
		}

		/**
		 * This method creates and initialises a {@link TableViewerEditor} for the given {@link TableViewer}.
		 *
		 * @param tableViewer the table viewer
		 */
		protected void createTableViewerEditor(final TableViewer tableViewer) {
			final TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer,
				new org.eclipse.emf.ecp.edit.internal.swt.controls.ECPFocusCellDrawHighlighter(tableViewer));
			final ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
				tableViewer) {
				@Override
				protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
					return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
						|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_CLICK_SELECTION
						|| event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED && event.keyCode == SWT.CR
						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
				}
			};
			TableViewerEditor.create(
				tableViewer,
				focusCellManager,
				actSupport,
				ColumnViewerEditor.TABBING_HORIZONTAL | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
					| ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
		}
	}

	/**
	 * {@link org.eclipse.emfforms.spi.swt.table.TableViewerCompositeBuilder TableViewerCompositeBuilder} which calls
	 * the existing template method to create the validation label.
	 *
	 * @since 1.13
	 *
	 */
	protected class TableControlSWTRendererCompositeBuilder
		extends org.eclipse.emfforms.spi.swt.table.DefaultTableViewerCompositeBuilder {
		@Override
		protected Label createValidationLabel(Composite topComposite) {
			final Label validationLabel = createValidationIcon(topComposite);
			GridDataFactory.fillDefaults().hint(16, 17).grab(false, false).applyTo(validationLabel);
			return validationLabel;
		}

		@Override
		protected Composite createViewerComposite(Composite composite) {
			return createControlComposite(composite);
		}
	}

	/**
	 * {@link org.eclipse.emfforms.spi.swt.table.TableViewerCompositeBuilder TableViewerCompositeBuilder} which calls
	 * the existing template method to create the validation label.
	 *
	 * @since 1.14
	 *
	 */
	protected class CompactVerticallyTableControlSWTRendererCompositeBuilder
		extends org.eclipse.emfforms.spi.swt.table.CompactVerticallyTableViewerCompositeBuilder {
		/**
		 * Constructor.
		 *
		 * @param createTitleLabel indicates whether to create a title label.
		 * @param createValidationLabel indicates whether to create a validation label.
		 */
		public CompactVerticallyTableControlSWTRendererCompositeBuilder(
			boolean createTitleLabel, boolean createValidationLabel) {
			super(createTitleLabel, createValidationLabel);
		}

		@Override
		protected Label createValidationLabel(Composite composite) {
			final Label validationLabel = createValidationIcon(composite);
			GridDataFactory.fillDefaults().hint(16, 17).grab(false, false).applyTo(validationLabel);
			return validationLabel;
		}

		@Override
		protected Composite createViewerComposite(Composite composite) {
			return createControlComposite(composite);
		}
	}

	/**
	 * This class combines the {@link ViewerComparator} with the {@link TableViewerComparator}.
	 * This is needed to allow customizations.
	 *
	 * @author Eugen Neufeld
	 * @since 1.22
	 */
	protected abstract class TableControlComparator extends ViewerComparator implements TableViewerComparator {
	}

	/**
	 * The {@link ViewerComparator} for this table which allows 3 states for sort order:
	 * none, up and down.
	 *
	 * @author Eugen Neufeld
	 * @since 1.10
	 *
	 */
	protected class ECPTableViewerComparator extends TableControlComparator {
		private int propertyIndex;
		private static final int NONE = 0;
		private int direction = NONE;

		/** Constructs a new instance. */
		ECPTableViewerComparator() {
			propertyIndex = 0;
			direction = NONE;
		}

		@Override
		public int getDirection() {
			switch (direction) {
			case 0:
				return SWT.NONE;
			case 1:
				return SWT.DOWN; // ascending
			case 2:
				return SWT.UP; // descending
			default:
				return SWT.NONE;
			}

		}

		@Override
		public void setColumn(int column) {
			if (column == propertyIndex) {
				// Same column as last sort; toggle the direction
				direction = (direction + 1) % 3;
			} else {
				// New column; do an ascending sort
				propertyIndex = column;
				direction = 1;
			}
			// No sorting is the same as no column being selected for sorting
			if (direction == NONE) {
				setSortColumnFeature(null);
			} else {
				// columnFeatures starts at index 0 with the first regular column
				setSortColumnFeature(getColumnFeature(propertyIndex));
			}
		}

		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			return TableControlSWTRenderer.this.compare(viewer, e1, e2, direction, propertyIndex);
		}
	}

	/**
	 * Domain model change listener that re-sorts the table and reveals the added resp. changed object.
	 *
	 * @since 1.20
	 */
	protected class AutoSortModelChangeListener implements ModelChangeListener {

		@Override
		public void notifyChange(ModelChangeNotification notification) {
			final int event = notification.getRawNotification().getEventType();
			if (notification.getStructuralFeature() == tableEReference
				&& getSortColumnFeature().isPresent()
				&& (event == Notification.ADD || event == Notification.ADD_MANY)) {
				sortAndReveal(notification.getNewEObjects());
			} else if (getSortColumnFeature().isPresent()
				&& notification.getStructuralFeature() == getSortColumnFeature().get()) {
				sortAndReveal(notification.getNotifier());
			}
		}

		private void sortAndReveal(Object toReveal) {
			final AbstractTableViewer viewer = getTableViewer();
			postRefresh(() -> {
				viewer.refresh();
				viewer.reveal(toReveal);
			});
		}
	}

	/**
	 * ECP specific cell label provider that does also implement {@link IColorProvider} in
	 * order to correctly.
	 *
	 * @author emueller
	 *
	 */
	public class ECPCellLabelProvider extends ObservableMapCellLabelProvider implements IColorProvider, IAdaptable {

		private final EStructuralFeature feature;
		private final CellEditor cellEditor;
		private final VTableControl vTableControl;
		private final VDomainModelReference dmr;
		private final Control table;

		/**
		 * Constructor.
		 *
		 * @param feature
		 *            the {@link EStructuralFeature} the cell is bound to
		 * @param cellEditor
		 *            the {@link CellEditor} instance
		 * @param attributeMap
		 *            an {@link IObservableMap} instance that is passed to the {@link ObservableMapCellLabelProvider}
		 * @param vTableControl the {@link VTableControl}
		 * @param dmr the {@link VDomainModelReference} for this cell
		 * @param table the swt table
		 * @since 1.10
		 */
		public ECPCellLabelProvider(EStructuralFeature feature, CellEditor cellEditor,
			@SuppressWarnings("rawtypes") IObservableMap attributeMap,
			VTableControl vTableControl, VDomainModelReference dmr, Control table) {
			super(attributeMap);
			this.vTableControl = vTableControl;
			this.feature = feature;
			this.cellEditor = cellEditor;
			this.dmr = dmr;
			this.table = table;
		}

		@Override
		public String getToolTipText(Object element) {
			final EObject domainObject = (EObject) element;

			final Optional<Setting> setting = getSettingFromObservable(dmr, domainObject);
			if (!setting.isPresent()) {
				return null;
			}

			final VDiagnostic vDiagnostic = vTableControl.getDiagnostic();
			if (vDiagnostic != null) {
				final String message = DiagnosticMessageExtractor.getMessage(vDiagnostic.getDiagnostic(domainObject,
					feature));
				if (message != null && !message.isEmpty()) {
					return ECPTooltipModifierHelper.modifyString(message, setting.get());
				}
			}
			final Object value = setting.get().get(true);
			if (value == null) {
				return null;
			}
			final String tooltip = ECPTooltipModifierHelper.modifyString(String.valueOf(value), setting.get());
			if (tooltip == null || tooltip.isEmpty()) {
				return null;
			}
			return tooltip;

		}

		@Override
		public void update(ViewerCell cell) {
			final EObject element = (EObject) cell.getElement();
			final Object value = getValue(element);
			if (ECPCustomUpdateCellEditor.class.isInstance(cellEditor)) {
				((ECPCustomUpdateCellEditor) cellEditor).updateCell(cell, value);
			} else {
				String text;
				Image image = null;

				if (ECPCellEditor.class.isInstance(cellEditor)) {
					final ECPCellEditor ecpCellEditor = (ECPCellEditor) cellEditor;
					text = Objects.toString(ecpCellEditor.getFormatedString(value), ""); //$NON-NLS-1$
					image = ecpCellEditor.getImage(value);
				} else {
					text = Objects.toString(value, ""); //$NON-NLS-1$
					cell.getControl().setData(CUSTOM_VARIANT, "org_eclipse_emf_ecp_edit_cellEditor_string"); //$NON-NLS-1$
				}

				if (!Objects.equals(text, cell.getText())) {
					cell.setText(text);
				}

				// Don't try to compare images
				if (image != null || cell.getImage() != null) {
					cell.setImage(image);
				}
			}

			final Color foreground = getForeground(element);
			if (!Objects.equals(cell.getForeground(), foreground)) {
				cell.setForeground(foreground);
			}
			final Color background = getBackground(element);
			if (!Objects.equals(cell.getBackground(), background)) {
				cell.setBackground(background);
			}
		}

		/**
		 * Get the value for an {@code object} from my observable map.
		 *
		 * @param object an object to look up the value for
		 * @return its value
		 */
		Object getValue(Object object) {
			return attributeMaps[0].get(object);
		}

		@Override
		public Color getForeground(Object element) {
			return table.getForeground();
		}

		@Override
		public Color getBackground(Object element) {
			final VDiagnostic vDiagnostic = vTableControl.getDiagnostic();
			final SWTValidationUiService validationUiService = getViewModelContext()
				.getService(SWTValidationUiService.class);
			if (vDiagnostic == null) {
				return validationUiService.getValidationBackgroundColor(Diagnostic.OK_INSTANCE, vTableControl,
					getViewModelContext());
			}
			final List<Diagnostic> diagnostic = vDiagnostic.getDiagnostic((EObject) element, feature);
			final Diagnostic iconDiagnostic = diagnostic.size() == 0 ? Diagnostic.OK_INSTANCE : diagnostic.get(0);
			return validationUiService.getValidationBackgroundColor(iconDiagnostic, vTableControl,
				getViewModelContext());
		}

		/**
		 * @return the cellEditor
		 */
		protected CellEditor getCellEditor() {
			return cellEditor;
		}

		/**
		 * @return the feature
		 */
		protected EStructuralFeature getFeature() {
			return feature;
		}

		/**
		 * @return the dmr
		 */
		protected VDomainModelReference getDmr() {
			return dmr;
		}

		@Override
		public <T> T getAdapter(Class<T> adapter) {
			T result = null;

			// For custom cell update, we must ask the cell editor to render a string for filtering
			if (adapter == ECPFilterableCell.class && !(cellEditor instanceof ECPCustomUpdateCellEditor)) {
				ECPFilterableCell filterable = null;

				if (cellEditor instanceof ECPCellEditor) {
					final ECPCellEditor ecpCellEditor = (ECPCellEditor) cellEditor;
					filterable = object -> ecpCellEditor.getFormatedString(getValue(object));
				} else {
					filterable = object -> Objects.toString(object, ""); //$NON-NLS-1$
				}

				result = adapter.cast(filterable);
			} else {
				result = Platform.getAdapterManager().getAdapter(this, adapter);
			}

			return result;
		}

	}

	/**
	 * Implementation of the {@link EditingSupport} for the generic ECP Table.
	 *
	 * @author Eugen Neufeld
	 *
	 */
	class ECPTableEditingSupport extends EditingSupport {

		private final CellEditor cellEditor;

		@SuppressWarnings("rawtypes")
		private final IValueProperty valueProperty;

		private final VDomainModelReference domainModelReference;

		/**
		 * Initializes me.
		 *
		 * @param viewer the viewer to edit
		 * @param cellEditor the cell editor used to edit the {@code viewer}
		 * @param domainModelReference the model reference that populates the {@code viewer}
		 * @param valueProperty the value property that supplies the {@code viewer}
		 */
		ECPTableEditingSupport(ColumnViewer viewer, CellEditor cellEditor, VDomainModelReference domainModelReference,
			IValueProperty<?, ?> valueProperty) {
			super(viewer);
			this.cellEditor = cellEditor;
			this.valueProperty = valueProperty;
			this.domainModelReference = domainModelReference;
		}

		private EditingState editingState;

		private final ColumnViewerEditorActivationListenerHelper activationListener = new ColumnViewerEditorActivationListenerHelper();

		/**
		 * Default implementation always returns <code>true</code>.
		 *
		 * @see org.eclipse.jface.viewers.EditingSupport#canEdit(java.lang.Object)
		 */
		@Override
		protected boolean canEdit(Object element) {
			if (!shouldCreateCellEditor(element)) {
				return false;
			}

			// TODO: use getSettingFromObservable(dmr, eObject) instead?
			@SuppressWarnings("unchecked")
			final IObservableValue<?> observableValue = valueProperty.observe(element);
			final EObject eObject = (EObject) ((IObserving) observableValue).getObserved();

			final EStructuralFeature structuralFeature = (EStructuralFeature) observableValue.getValueType();

			// Given EClass has no such feature
			if (eObject == null || eObject.eClass().getFeatureID(structuralFeature) == -1) {
				return false;
			}

			final Setting setting = ((InternalEObject) eObject).eSetting(structuralFeature);

			if (isDisabled(eObject, domainModelReference)
				|| CellReadOnlyTesterHelper.getInstance().isReadOnly(getVElement(), setting)) {
				return false;
			}

			final boolean editable = emfFormsEditSupport.canSetProperty(domainModelReference, (EObject) element);

			if (ECPCellEditor.class.isInstance(cellEditor)) {
				ECPCellEditor.class.cast(cellEditor).setEditable(editable);
				return true;
			}
			return editable;
		}

		/**
		 * Default implementation always returns <code>null</code> as this will be
		 * handled by the Binding.
		 *
		 * @see org.eclipse.jface.viewers.EditingSupport#getValue(java.lang.Object)
		 */
		@Override
		protected Object getValue(Object element) {
			// no op
			return null;
		}

		/**
		 * Default implementation does nothing as this will be handled by the
		 * Binding.
		 *
		 * @see org.eclipse.jface.viewers.EditingSupport#setValue(java.lang.Object, java.lang.Object)
		 */
		@Override
		protected void setValue(Object element, Object value) {
			// no op
		}

		/**
		 * Creates a {@link Binding} between the editor and the element to be
		 * edited. Invokes {@link #doCreateCellEditorObservable(CellEditor)},
		 * {@link #doCreateElementObservable(Object, ViewerCell)}, and then
		 * {@link #createBinding(IObservableValue, IObservableValue)}.
		 */
		@Override
		protected void initializeCellEditorValue(CellEditor cellEditor, ViewerCell cell) {

			if (ECPElementAwareCellEditor.class.isInstance(cellEditor)) {
				ECPElementAwareCellEditor.class.cast(cellEditor).updateRowElement(cell.getElement());
			}

			final IObservableValue<?> target = doCreateCellEditorObservable(cellEditor);
			Assert.isNotNull(target, "doCreateCellEditorObservable(...) did not return an observable"); //$NON-NLS-1$

			@SuppressWarnings("unchecked")
			final IObservableValue<?> model = valueProperty.observe(cell.getElement());
			Assert.isNotNull(model, "The databinding service did not return an observable"); //$NON-NLS-1$

			final Binding binding = createBinding(target, model);

			Assert.isNotNull(binding, "createBinding(...) did not return a binding"); //$NON-NLS-1$

			editingState = new EditingState(binding, target, model);

			getViewer().getColumnViewerEditor().addEditorActivationListener(activationListener);
		}

		@Override
		protected CellEditor getCellEditor(Object element) {
			return cellEditor;
		}

		/**
		 * Bind a {@code model} value to a {@code target} value.
		 *
		 * @param target the binding target
		 * @param model the binding source
		 * @return the binding
		 */
		@SuppressWarnings({ "rawtypes", "unchecked" })
		protected Binding createBinding(IObservableValue target, IObservableValue model) {
			if (ECPCellEditor.class.isInstance(cellEditor)) {
				return getDataBindingContext().bindValue(target, model,
					((ECPCellEditor) cellEditor).getTargetToModelStrategy(getDataBindingContext()),
					((ECPCellEditor) cellEditor).getModelToTargetStrategy(getDataBindingContext()));
			}
			return getDataBindingContext().bindValue(target, model);
		}

		/**
		 * Create an observable value to supply the cells edited by a cell editor.
		 *
		 * @param cellEditor a cell editor
		 * @return the observable value to supply it with data to edit
		 */
		@SuppressWarnings({ "rawtypes", "unchecked" })
		protected IObservableValue doCreateCellEditorObservable(CellEditor cellEditor) {
			if (ECPCellEditor.class.isInstance(cellEditor)) {
				return ((ECPCellEditor) cellEditor).getValueProperty().observe(cellEditor);
			}
			return WidgetProperties.text(SWT.FocusOut).observe(cellEditor.getControl());
		}

		@Override
		protected final void saveCellEditorValue(CellEditor cellEditor, ViewerCell cell) {
			if (editingState.isUpdateNeeded()) {
				editingState.binding.updateTargetToModel();
			}
		}

		/**
		 * A ColumnViewerEditorActivationListener to reset the cells after focus lost.
		 *
		 * @author Eugen Neufeld
		 *
		 */
		private class ColumnViewerEditorActivationListenerHelper extends ColumnViewerEditorActivationListener {

			@Override
			public void afterEditorActivated(ColumnViewerEditorActivationEvent event) {
				// set colors for cell editor
				final Control control = cellEditor.getControl();
				if (control == null || control.isDisposed()) {
					return;
				}
				control.setBackground(getViewer().getControl().getBackground());
				control.setForeground(getViewer().getControl().getForeground());
			}

			@Override
			public void afterEditorDeactivated(ColumnViewerEditorDeactivationEvent event) {
				editingState.dispose();
				editingState = null;

				getViewer().getColumnViewerEditor().removeEditorActivationListener(this);
				final ViewerCell focusCell = getViewer().getColumnViewerEditor().getFocusCell();
				if (focusCell != null) {
					getViewer().update(focusCell.getElement(), null);
				}
			}

			@Override
			public void beforeEditorActivated(ColumnViewerEditorActivationEvent event) {
				// do nothing
			}

			@Override
			public void beforeEditorDeactivated(ColumnViewerEditorDeactivationEvent event) {
				// do nothing
			}
		}

		/**
		 * Maintains references to objects that only live for the length of the edit
		 * cycle.
		 */
		class EditingState {

			private final IObservableValue<?> target;
			private final IObservableValue<?> model;
			private final Binding binding;

			/**
			 * Initializes me with the data binding details involved in editing.
			 *
			 * @param binding the data binding
			 * @param target the bound target value
			 * @param model the bound model value
			 */
			EditingState(Binding binding, IObservableValue<?> target, IObservableValue<?> model) {
				this.binding = binding;
				this.target = target;
				this.model = model;
			}

			/**
			 * Dispose the data binding that I maintain.
			 */
			void dispose() {
				binding.dispose();
				target.dispose();
				model.dispose();
			}

			/**
			 * Checks if an update is really needed.
			 *
			 * @return <code>true</code> if update is really needed, <code>false</code> otherwise.
			 */
			boolean isUpdateNeeded() {
				final Object targetValue = target.getValue();
				final Object modelValue = model.getValue();

				if (targetValue == null) {
					return modelValue != null;
				}
				return !targetValue.equals(modelValue);
			}
		}
	}

	/**
	 * The {@link CellLabelProvider} to update the validation status on the cells.
	 *
	 * @author Eugen Neufeld
	 *
	 */
	private class ValidationStatusCellLabelProvider extends CellLabelProvider {
		private final VTableControl vTableControl;

		ValidationStatusCellLabelProvider(
			VTableControl vTableControl) {
			this.vTableControl = vTableControl;
		}

		@Override
		public void update(ViewerCell cell) {
			final VDiagnostic vDiagnostic = vTableControl.getDiagnostic();
			if (vDiagnostic == null) {
				return;
			}
			final List<Diagnostic> diagnostics = vDiagnostic.getDiagnostics((EObject) cell.getElement());
			Diagnostic cellDiagnostic;
			if (diagnostics.size() != 0) {
				cellDiagnostic = diagnostics.get(0);
			} else {
				// If there is no diagnostic, we assume everything is ok
				cellDiagnostic = Diagnostic.OK_INSTANCE;
			}
			final Image validationIcon = getViewModelContext().getService(SWTValidationUiService.class)
				.getValidationIcon(cellDiagnostic, getVElement(), getViewModelContext());
			cell.setImage(validationIcon);
		}

		@Override
		public String getToolTipText(Object element) {
			final VDiagnostic vDiagnostic = vTableControl.getDiagnostic();
			if (vDiagnostic == null) {
				return null;
			}
			final String message = DiagnosticMessageExtractor.getMessage(vDiagnostic.getDiagnostics((EObject) element));
			return ECPTooltipModifierHelper.modifyString(message, null);
		}
	}

	/**
	 * Localize the message.
	 *
	 * @param eClass The EClass of the table setting.
	 * @param messageKey key of the string
	 * @return tooltip.
	 * @since 1.26
	 */
	protected String formatTooltipText(EClass eClass, String messageKey) {
		final String instanceName = getReferenceDisplayName(eClass);
		return String.format(LocalizationServiceHelper.getString(
			TableControlSWTRenderer.class, messageKey),
			instanceName);
	}

	/**
	 * Returns the current sort column feature.
	 *
	 * @return an {@link java.util.Optional} containing the feature used for sorting
	 * @since 1.22
	 */
	protected java.util.Optional<EStructuralFeature> getSortColumnFeature() {
		return sortColumnFeature;
	}

	/**
	 * Set the column to use for sorting.
	 *
	 * @param sortColumnFeature an optional containing the feature to use for sorting
	 * @since 1.22
	 */
	protected void setSortColumnFeature(EStructuralFeature sortColumnFeature) {
		this.sortColumnFeature = java.util.Optional.ofNullable(sortColumnFeature);
	}

	/**
	 * Find the feature for a specific index.
	 *
	 * @param propertyIndex The index to find the feature for
	 * @return The {@link EStructuralFeature} for the provided index
	 * @since 1.22
	 */
	protected EStructuralFeature getColumnFeature(int propertyIndex) {
		return columnFeatures[propertyIndex - regularColumnsStartIndex];
	}

	/**
	 * Obtains a user-presentable name for the reference that I edit, to be used for example
	 * in button tool-tips.
	 *
	 * @return the reference display name
	 * @since 1.25
	 */
	protected String getReferenceDisplayName(EClassifier type) {
		if (referenceDisplayName == null) {
			if (l10n == null) {
				// Maybe the view-model context has one
				l10n = getViewModelContext().getService(EMFFormsLocalizationService.class);
			}

			if (type != null && l10n != null) {
				try {
					final Bundle editBundle = bundleResolver.getEditBundle(type);
					referenceDisplayName = l10n.getString(editBundle, String.format("_UI_%s_type", type.getName())); //$NON-NLS-1$
				} catch (final NoBundleFoundException ex) {
					referenceDisplayName = type.getName();
				}
			}

			if (referenceDisplayName == null) {
				referenceDisplayName = LocalizationServiceHelper.getString(TableControlSWTRenderer.class,
					MessageKeys.TableControlSWTRenderer_defaultReferenceDisplayName);
			}
		}

		return referenceDisplayName;
	}
}
