Bug 500167 - Copy Paste Behavior for Grid Table

* Add generic copy & paste support for grid table

Change-Id: I965617a61b41cac027ab804ecb916f2af5e5485b
Signed-off-by: Mathias Schaefer <mschaefer@eclipsesource.com>
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/META-INF/MANIFEST.MF b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/META-INF/MANIFEST.MF
index 8166fe5..52bfc57 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/META-INF/MANIFEST.MF
@@ -25,8 +25,11 @@
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Import-Package: javax.inject;version="1.0.0",
+ org.eclipse.emf.ecp.view.spi.table.model;version="1.10.0",
+ org.eclipse.emf.ecp.view.spi.table.swt;version="1.10.0",
  org.eclipse.emfforms.spi.common.report;version="[1.10.0,2.0.0)",
  org.eclipse.emfforms.spi.core.services.databinding.emf;version="[1.10.0,2.0.0)",
+ org.eclipse.emfforms.spi.swt.core.di;version="1.10.0",
  org.eclipse.jface.databinding.swt;version="0.0.0",
  org.eclipse.jface.databinding.viewers;version="0.0.0",
  org.eclipse.jface.dialogs;version="0.0.0",
@@ -40,8 +43,9 @@
  org.eclipse.swt.events;version="0.0.0",
  org.eclipse.swt.graphics;version="0.0.0",
  org.eclipse.swt.layout;version="0.0.0",
- org.eclipse.swt.widgets;version="0.0.0"
-Export-Package: org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid;version="1.10.0";x-internal:=true,
+ org.eclipse.swt.widgets;version="0.0.0",
+ org.osgi.service.component.annotations;version="1.2.0";resolution:=optional
+Export-Package: org.eclipse.emf.ecp.view.internal.table.nebula.grid;version="1.10.0",
  org.eclipse.emf.ecp.view.spi.table.nebula.grid;version="1.10.0"
 Service-Component: OSGI-INF/GridControlSWTRendererService.xml
 
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/OSGI-INF/org.eclipse.emfforms.internal.common.converter.DefaultValueConverterImpl.xml b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/OSGI-INF/org.eclipse.emfforms.internal.common.converter.DefaultValueConverterImpl.xml
new file mode 100644
index 0000000..3644c1e
--- /dev/null
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/OSGI-INF/org.eclipse.emfforms.internal.common.converter.DefaultValueConverterImpl.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.emfforms.internal.common.converter.DefaultValueConverterImpl">
+   <service>
+      <provide interface="org.eclipse.emfforms.spi.common.converter.ValueConverter"/>
+   </service>
+   <implementation class="org.eclipse.emfforms.internal.common.converter.DefaultValueConverterImpl"/>
+</scr:component>
\ No newline at end of file
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridControlSWTRendererService.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridControlSWTRendererService.java
similarity index 95%
rename from bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridControlSWTRendererService.java
rename to bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridControlSWTRendererService.java
index c7b8613..4c1bf58 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridControlSWTRendererService.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridControlSWTRendererService.java
@@ -9,7 +9,7 @@
  * Contributors:
  * Alexandra Buzila - initial API and implementation
  ******************************************************************************/
-package org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid;
+package org.eclipse.emf.ecp.view.internal.table.nebula.grid;
 
 import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
 import org.eclipse.emf.ecp.view.spi.model.VElement;
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridCopyKeyListener.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridCopyKeyListener.java
similarity index 95%
rename from bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridCopyKeyListener.java
rename to bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridCopyKeyListener.java
index 0801f4b..dd0f867 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridCopyKeyListener.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridCopyKeyListener.java
@@ -9,7 +9,7 @@
  * Contributors:
  * Alexandra Buzila - initial API and implementation
  ******************************************************************************/
-package org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid;
+package org.eclipse.emf.ecp.view.internal.table.nebula.grid;
 
 import org.eclipse.nebula.widgets.grid.Grid;
 import org.eclipse.swt.SWT;
@@ -57,6 +57,10 @@
 			final TextTransfer[] dataTypes = { TextTransfer.getInstance() };
 
 			clipboard.setContents(data, dataTypes);
+
+			// System.out.println("---");
+			// System.out.println(Arrays.toString(data));
+			// System.out.println("---");
 		}
 	}
 
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridPasteKeyListener.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridPasteKeyListener.java
new file mode 100644
index 0000000..caa3a83
--- /dev/null
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/internal/table/nebula/grid/GridPasteKeyListener.java
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2011-2016 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandra Buzila - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.ecp.view.internal.table.nebula.grid;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
+import org.eclipse.emfforms.spi.common.converter.EStructuralFeatureValueConverterService;
+import org.eclipse.emfforms.spi.core.services.databinding.emf.EMFFormsDatabindingEMF;
+import org.eclipse.emfforms.spi.swt.table.AbstractTableViewerComposite;
+import org.eclipse.nebula.widgets.grid.Grid;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * {@link KeyListener} for the paste action on a {@link Grid} control.
+ *
+ * @author Alexandra Buzila
+ * @author Mathias Schaefer
+ * @since 1.10
+ *
+ */
+public class GridPasteKeyListener implements KeyListener {
+
+	private final Clipboard clipboard;
+	private final EMFFormsDatabindingEMF dataBinding;
+	private final EStructuralFeatureValueConverterService converterService;
+
+	private boolean selectPastedCells = true;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param display the {@link Display} on which to allocate this command's {@link Clipboard}.
+	 */
+	public GridPasteKeyListener(Display display, EMFFormsDatabindingEMF dataBinding,
+		EStructuralFeatureValueConverterService converterService, boolean selectPastedCells) {
+		clipboard = new Clipboard(display);
+		this.dataBinding = dataBinding;
+		this.converterService = converterService;
+		this.selectPastedCells = selectPastedCells;
+	}
+
+	@Override
+	public void keyPressed(KeyEvent e) {
+		// do nothing
+	}
+
+	@Override
+	public void keyReleased(KeyEvent e) {
+		if ((e.stateMask & SWT.CTRL) != 0 && e.keyCode == 'v') {
+			final Grid grid = (Grid) e.widget;
+			final Object contents = clipboard.getContents(TextTransfer.getInstance());
+			if (contents instanceof String) {
+				pasteSelection(grid, (String) contents);
+			}
+		}
+	}
+
+	/**
+	 * Pastes the given contents in the grid.
+	 *
+	 * @param grid the target {@link Grid}
+	 * @param contents the contents to paste
+	 */
+	public void pasteSelection(Grid grid, String contents) {
+
+		// ignore if no selection
+		if (grid.getCellSelection().length == 0) {
+			return;
+		}
+
+		final List<Point> pastedCells = new ArrayList<Point>();
+		if (grid.getCellSelection().length > 1
+			&& new StringTokenizer(contents, "\n\t", false).countTokens() == 1) { //$NON-NLS-1$
+
+			// fill selection
+			for (final Point startItem : grid.getCellSelection()) {
+				pastedCells.addAll(pasteContents(startItem, grid, contents));
+			}
+
+		} else {
+
+			// expand selection
+			final Point startItem = grid.getCellSelection()[0];
+			pastedCells.addAll(pasteContents(startItem, grid, contents));
+		}
+
+		if (selectPastedCells && !pastedCells.isEmpty() && grid.isCellSelectionEnabled()) {
+			grid.setCellSelection(pastedCells.toArray(new Point[] {}));
+		}
+
+	}
+
+	public List<Point> pasteContents(Point startItem, Grid grid, String contents) {
+		final int startColumn = startItem.x;
+		final int startRow = startItem.y;
+
+		final List<Point> pastedCells = new ArrayList<Point>();
+		final List<Object> pastedValues = new ArrayList<Object>();
+
+		int relativeRow = 0;
+		final StringTokenizer rowTokenizer = new StringTokenizer(contents, "\n", true); //$NON-NLS-1$
+		while (rowTokenizer.hasMoreTokens()) {
+
+			final String columnValue = rowTokenizer.nextToken();
+			if (columnValue.equals("\n")) { //$NON-NLS-1$
+				relativeRow++;
+				continue;
+			}
+
+			int relativeColumn = 0;
+			final StringTokenizer columnTokenizer = new StringTokenizer(columnValue, "\t", true); //$NON-NLS-1$
+			while (columnTokenizer.hasMoreTokens()) {
+
+				final String cellValue = columnTokenizer.nextToken();
+				if (cellValue.equals("\t")) { //$NON-NLS-1$
+					relativeColumn++;
+					continue;
+				}
+
+				final int insertionColumnIndex = startColumn + relativeColumn;
+				final int insertionRowIndex = startRow + relativeRow;
+
+				@SuppressWarnings("unchecked")
+				final VDomainModelReference dmr = (VDomainModelReference) grid.getColumn(insertionColumnIndex)
+					.getData(AbstractTableViewerComposite.DMR);
+
+				if (insertionRowIndex < grid.getItemCount()) {
+
+					final EObject eObject = (EObject) grid.getItem(insertionRowIndex).getData();
+
+					IObservableValue value = null;
+					try {
+
+						value = dataBinding.getObservableValue(dmr, eObject);
+						final Object convertedValue = converterService
+							.convertToModelValue(eObject, (EStructuralFeature) value.getValueType(), cellValue);
+						if (convertedValue != null) {
+							value.setValue(convertedValue);
+							pastedValues.add(value);
+						}
+
+						pastedCells.add(new Point(insertionColumnIndex, insertionRowIndex));
+
+					} catch (final Exception ex) {
+						// silently ignore this
+					} finally {
+						if (value != null) {
+							value.dispose();
+						}
+					}
+
+				}
+			}
+		}
+
+		return pastedCells;
+	}
+
+}
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridPasteKeyListener.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridPasteKeyListener.java
deleted file mode 100644
index a2256f4..0000000
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/internal/nebula/grid/GridPasteKeyListener.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011-2016 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 v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandra Buzila - initial API and implementation
- ******************************************************************************/
-package org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid;
-
-import java.util.StringTokenizer;
-
-import org.eclipse.nebula.widgets.grid.Grid;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.widgets.Display;
-
-/**
- * {@link KeyListener} for the paste action on a {@link Grid} control.
- *
- * @author Alexandra Buzila
- * @since 1.10
- *
- */
-public class GridPasteKeyListener implements KeyListener {
-
-	private final Clipboard clipboard;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param display the {@link Display} on which to allocate this command's {@link Clipboard}.
-	 */
-	public GridPasteKeyListener(Display display) {
-		clipboard = new Clipboard(display);
-	}
-
-	@Override
-	public void keyPressed(KeyEvent e) {
-		// do nothing
-	}
-
-	@Override
-	public void keyReleased(KeyEvent e) {
-		if ((e.stateMask & SWT.CTRL) != 0 && e.keyCode == 'v') {
-			final Grid grid = (Grid) e.widget;
-			final Object contents = clipboard.getContents(TextTransfer.getInstance());
-			if (contents instanceof String) {
-				pasteSelection(grid, (String) contents);
-			}
-		}
-	}
-
-	/**
-	 * Pastes the given contents in the grid.
-	 * 
-	 * @param grid the target {@link Grid}
-	 * @param contents the contents to paste
-	 */
-	public void pasteSelection(Grid grid, String contents) {
-		// ignore if no selection
-		if (grid.getCellSelection().length == 0) {
-			return;
-		}
-		// if multiple items are selected, we take the first one
-		final Point startItem = grid.getCellSelection()[0];
-		final int startColumn = startItem.x;
-		final int startRow = startItem.y;
-
-		int relativeRow = -1;
-		int relativeColumn = -1;
-		final StringTokenizer rowTokenizer = new StringTokenizer(contents, "\n", true); //$NON-NLS-1$
-		while (rowTokenizer.hasMoreTokens()) {
-			relativeRow++;
-			String columnString = rowTokenizer.nextToken();
-			boolean rowUpdate = false;
-			while (rowTokenizer.hasMoreTokens() && columnString.equals("\n")) { //$NON-NLS-1$
-				relativeRow++;
-				columnString = rowTokenizer.nextToken();
-				rowUpdate = true;
-			}
-			if (rowUpdate) {
-				relativeRow--;
-			}
-			final StringTokenizer columnTokenizer = new StringTokenizer(columnString, "\t", true); //$NON-NLS-1$
-			relativeColumn = -1;
-			while (columnTokenizer.hasMoreTokens()) {
-				relativeColumn++;
-				String text = columnTokenizer.nextToken();
-				while (columnTokenizer.hasMoreTokens() && text.equals("\t")) { //$NON-NLS-1$
-					relativeColumn++;
-					text = columnTokenizer.nextToken();
-				}
-				if (!text.equals("\t")) { //$NON-NLS-1$
-					final int insertionIndex = startRow + relativeRow;
-					if (insertionIndex < grid.getItemCount()) {
-						grid.getItem(startRow + relativeRow).setText(startColumn + relativeColumn, text);
-					}
-				}
-			}
-		}
-	}
-}
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridControlSWTRenderer.java
index d110143..be65d76 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridControlSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridControlSWTRenderer.java
@@ -11,20 +11,30 @@
  ******************************************************************************/
 package org.eclipse.emf.ecp.view.spi.table.nebula.grid;
 
+import java.util.Arrays;
+
 import javax.inject.Inject;
 
 import org.eclipse.core.databinding.observable.list.IObservableList;
 import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.ecore.EClass;
+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.ecp.view.internal.table.nebula.grid.GridCopyKeyListener;
+import org.eclipse.emf.ecp.view.internal.table.nebula.grid.GridNewLineKeyListener;
+import org.eclipse.emf.ecp.view.internal.table.nebula.grid.GridPasteKeyListener;
 import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
-import org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid.GridCopyKeyListener;
-import org.eclipse.emf.ecp.view.spi.table.internal.nebula.grid.GridPasteKeyListener;
 import org.eclipse.emf.ecp.view.spi.table.model.VTableControl;
 import org.eclipse.emf.ecp.view.spi.table.swt.TableControlSWTRenderer;
 import org.eclipse.emf.ecp.view.spi.util.swt.ImageRegistryService;
 import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
 import org.eclipse.emf.ecp.view.template.style.background.model.VTBackgroundStyleProperty;
 import org.eclipse.emf.ecp.view.template.style.fontProperties.model.VTFontPropertiesStyleProperty;
+import org.eclipse.emfforms.spi.common.converter.EStructuralFeatureValueConverterService;
 import org.eclipse.emfforms.spi.common.report.ReportService;
+import org.eclipse.emfforms.spi.core.services.databinding.DatabindingFailedException;
 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;
@@ -49,6 +59,8 @@
  */
 public class GridControlSWTRenderer extends TableControlSWTRenderer {
 
+	private final EStructuralFeatureValueConverterService converterService;
+
 	/**
 	 * Default constructor.
 	 *
@@ -67,10 +79,11 @@
 	public GridControlSWTRenderer(VTableControl vElement, ViewModelContext viewContext, ReportService reportService,
 		EMFFormsDatabindingEMF emfFormsDatabinding, EMFFormsLabelProvider emfFormsLabelProvider,
 		VTViewTemplateProvider vtViewTemplateProvider, ImageRegistryService imageRegistryService,
-		EMFFormsEditSupport emfFormsEditSupport) {
+		EMFFormsEditSupport emfFormsEditSupport, EStructuralFeatureValueConverterService converterService) {
 		// CHECKSTYLE.ON: ParameterNumber
 		super(vElement, viewContext, reportService, emfFormsDatabinding, emfFormsLabelProvider, vtViewTemplateProvider,
 			imageRegistryService, emfFormsEditSupport);
+		this.converterService = converterService;
 	}
 
 	/**
@@ -82,16 +95,40 @@
 
 		@Override
 		public GridTableViewer createTableViewer(Composite parent) {
+
 			final GridTableViewer tableViewer = new GridTableViewer(parent,
-				SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);
+				SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
 			tableViewer.getGrid().setData(CUSTOM_VARIANT, TABLE_CUSTOM_VARIANT);
 			tableViewer.getGrid().setHeaderVisible(true);
 			tableViewer.getGrid().setLinesVisible(true);
 			tableViewer.getGrid().setCellSelectionEnabled(true);
 			tableViewer.getGrid().setFooterVisible(false);
 			tableViewer.getGrid().setRowHeaderVisible(true);
+
 			tableViewer.getGrid().addKeyListener(new GridCopyKeyListener(tableViewer.getGrid().getDisplay()));
-			tableViewer.getGrid().addKeyListener(new GridPasteKeyListener(tableViewer.getGrid().getDisplay()));
+			tableViewer.getGrid()
+				.addKeyListener(new GridPasteKeyListener(tableViewer.getGrid().getDisplay(), getEMFFormsDatabinding(),
+					converterService, true));
+			tableViewer.getGrid().addKeyListener(new GridNewLineKeyListener() {
+
+				@Override
+				public void appendNewRow() {
+
+					try {
+						final Setting setting = getEMFFormsDatabinding().getSetting(getDMRToMultiReference(),
+							getViewModelContext().getDomainModel());
+						final EObject eObject = setting.getEObject();
+						final EStructuralFeature structuralFeature = setting.getEStructuralFeature();
+						final EClass clazz = ((EReference) structuralFeature).getEReferenceType();
+
+						addRow(clazz, eObject, structuralFeature);
+					} catch (final DatabindingFailedException ex) {
+						// nothing to do
+					}
+
+				}
+
+			});
 
 			/* Set background color */
 			final VTBackgroundStyleProperty backgroundStyleProperty = getBackgroundStyleProperty();
@@ -124,17 +161,38 @@
 			// final TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(tableViewer,
 			// new org.eclipse.emf.ecp.edit.internal.swt.controls.ECPFocusCellDrawHighlighter(tableViewer));
 
+			// final TableViewer tableViewer = (TableViewer) getTableViewer();
+			// final TableViewerFocusCellManager focusCellManager = new TableViewerFocusCellManager(
+			// (TableViewer) gridTableViewer,
+			// new CustomFocusCellHighlighter(gridTableViewer);
+
 			final ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
 				gridTableViewer) {
 				@Override
 				protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
-					return event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
+
+					if (event.eventType == ColumnViewerEditorActivationEvent.TRAVERSAL
 						|| event.eventType == ColumnViewerEditorActivationEvent.MOUSE_DOUBLE_CLICK_SELECTION
-						|| event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED
-							&& (event.keyCode == SWT.CR || event.keyCode == 16777296)
-						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
+						|| event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC) {
+						return true;
+					}
+
+					if (event.eventType == ColumnViewerEditorActivationEvent.KEY_PRESSED) {
+
+						for (final int keyCode : Arrays.asList(SWT.CTRL, SWT.ALT, SWT.SHIFT)) {
+							if ((event.keyCode & keyCode) != 0 || (event.stateMask & keyCode) != 0) {
+								return false;
+							}
+						}
+						return !Arrays
+							.asList(SWT.ARROW_UP, SWT.ARROW_DOWN, SWT.ARROW_LEFT, SWT.ARROW_RIGHT, SWT.TAB, SWT.CR)
+							.contains(event.keyCode);
+
+					}
+					return false;
 				}
 			};
+			actSupport.setEnableEditorActivationWithKeyboard(true);
 			GridViewerEditor.create(
 				gridTableViewer,
 				actSupport,
@@ -183,4 +241,5 @@
 	protected ScrollBar getVerticalBar() {
 		return ((GridTableViewer) getTableViewer()).getGrid().getVerticalBar();
 	}
+
 }
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridTableViewerComposite.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridTableViewerComposite.java
index 720c19c..f4a331e 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridTableViewerComposite.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridTableViewerComposite.java
@@ -123,13 +123,21 @@
 	}
 
 	// TODO: could be refactored to reduce overlap with TableViewerComposite
+	// TODO: refactor (ms)
 	@Override
 	protected ViewerColumn createColumn(ColumnDescription columnDescription,
 		EMFDataBindingContext emfDataBindingContext, AbstractTableViewer tableViewer) {
 		final GridViewerColumnBuilder builder = GridViewerColumnBuilder
 			.create();
 
-		final GridViewerColumn column = builder.setData(RESIZABLE, columnDescription.isResizeable())
+		// TODO: set correct colors here
+		// builder.setCellRenderer(new CustomSelectionColorCellRenderer(
+		// getDisplay().getSystemColor(SWT.COLOR_WHITE),
+		// getDisplay().getSystemColor(SWT.COLOR_CYAN)));
+
+		final GridViewerColumn column = builder
+			.setData(columnDescription.getData())
+			.setData(RESIZABLE, columnDescription.isResizeable())
 			.setMoveable(columnDescription.isMoveable())
 			.setStyle(columnDescription.getStyleBits())
 			.setData(WEIGHT, columnDescription.getWeight())
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridViewerColumnBuilder.java b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridViewerColumnBuilder.java
index 52be8d5..2576704 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridViewerColumnBuilder.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.nebula.grid/src/org/eclipse/emf/ecp/view/spi/table/nebula/grid/GridViewerColumnBuilder.java
@@ -15,8 +15,11 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.eclipse.emfforms.spi.swt.table.AbstractTableViewerComposite;
+import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.nebula.jface.gridviewer.GridTableViewer;
 import org.eclipse.nebula.jface.gridviewer.GridViewerColumn;
+import org.eclipse.nebula.widgets.grid.GridCellRenderer;
 import org.eclipse.swt.SWT;
 
 /**
@@ -24,6 +27,9 @@
  *
  */
 public class GridViewerColumnBuilder {
+
+	private int columnId;
+
 	/**
 	 * Creates a new viewer column.
 	 *
@@ -56,12 +62,14 @@
 	 */
 	public GridViewerColumn build(GridTableViewer tableViewer) {
 		final GridViewerColumn column = buildViewerColumn(tableViewer);
+		setData(AbstractTableViewerComposite.COLUMN_ID, columnId++);
 		setText(column);
 		setToolTipText(column);
 		setResizable(column);
 		setMoveable(column);
 		setData(column);
 		setWidth(column);
+		setCellRenderer(column);
 		return column;
 	}
 
@@ -72,6 +80,7 @@
 	private final Map<String, Object> data = new LinkedHashMap<String, Object>();
 	private Integer width;
 	private Integer style = SWT.NONE;
+	private GridCellRenderer cellRenderer;
 
 	/**
 	 * Configures the text of the {@link GridViewerColumn}.
@@ -118,6 +127,17 @@
 	}
 
 	/**
+	 * Configures the application data entries to be set for the {@link TableViewerColumn}.
+	 *
+	 * @param data the data entries to be added
+	 * @return the TableViewerColumnBuilder instance
+	 */
+	public GridViewerColumnBuilder setData(Map<String, Object> data) {
+		this.data.putAll(data);
+		return this;
+	}
+
+	/**
 	 * Configures the application data to be set for the {@link GridViewerColumn}.
 	 *
 	 * @param key the data key
@@ -151,6 +171,17 @@
 		return this;
 	}
 
+	/**
+	 * Overwrites the DefaultGridCellRenderer.
+	 *
+	 * @param cellRenderer
+	 * @return
+	 */
+	public GridViewerColumnBuilder setCellRenderer(GridCellRenderer cellRenderer) {
+		this.cellRenderer = cellRenderer;
+		return this;
+	}
+
 	private void setText(GridViewerColumn column) {
 		if (text != null) {
 			column.getColumn().setText(text);
@@ -174,7 +205,6 @@
 	private void setMoveable(GridViewerColumn column) {
 		if (isMoveable != null) {
 			column.getColumn().setMoveable(true);
-
 		}
 	}
 
@@ -190,4 +220,10 @@
 		}
 	}
 
+	private void setCellRenderer(GridViewerColumn column) {
+		if (cellRenderer != null) {
+			column.getColumn().setCellRenderer(cellRenderer);
+		}
+	}
+
 }
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
index 8e1d0ad..2cf04fa 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
@@ -543,6 +543,8 @@
 						? ECPCellEditor.class.cast(tempCellEditor).getMinWidth() : 10;
 				}
 
+				// TODO: rewrite builder (ms)
+				tableViewerSWTBuilder.setData(AbstractTableViewerComposite.DMR, dmr);
 				tableViewerSWTBuilder.addColumn(true, false, SWT.NONE, weight, minWidth, text, tooltip,
 					labelProvider, editingSupportCreator, null);
 
@@ -627,9 +629,9 @@
 
 	/**
 	 * @return the {@link VDomainModelReference} which ends at the table setting
-	 * @since 1.10
+	 * @since 1.11
 	 */
-	protected final VDomainModelReference getDMRToMultiReference() {
+	protected VDomainModelReference getDMRToMultiReference() {
 		final VTableDomainModelReference tableDomainModelReference = (VTableDomainModelReference) getVElement()
 			.getDomainModelReference();
 		final VDomainModelReference dmrToCheck = tableDomainModelReference.getDomainModelReference() == null
@@ -2166,4 +2168,16 @@
 			return ECPTooltipModifierHelper.modifyString(message, null);
 		}
 	}
-}
\ No newline at end of file
+
+	@Override
+	protected void rootDomainModelChanged() throws DatabindingFailedException {
+		// TODO rebind tooltip and text?
+		final IObservableList oldList = (IObservableList) getTableViewer().getInput();
+		oldList.dispose();
+		final IObservableList list = getEMFFormsDatabinding().getObservableList(getDMRToMultiReference(),
+			getViewModelContext().getDomainModel());
+		// addRelayoutListenerIfNeeded(list, composite);
+		getTableViewer().setInput(list);
+		tableControlSWTRendererButtonBarBuilder.updateValues();
+	}
+}
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/AbstractTableViewerComposite.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/AbstractTableViewerComposite.java
index e6a877b..692a2fe 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/AbstractTableViewerComposite.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/AbstractTableViewerComposite.java
@@ -39,12 +39,17 @@
  *
  */
 public abstract class AbstractTableViewerComposite extends Composite {
+
+	// TODO: refactor these constants into ColumnDescription interface
 	/** Data key for resizable columns. */
-	protected static final String RESIZABLE = "resizable"; //$NON-NLS-1$
+	public static final String RESIZABLE = "resizable"; //$NON-NLS-1$
 	/** Data key for column weight. */
-	protected static final String WEIGHT = "weight"; //$NON-NLS-1$
+	public static final String WEIGHT = "weight"; //$NON-NLS-1$
 	/** Data key for the minimum width of the column. */
-	protected static final String MIN_WIDTH = "min_width"; //$NON-NLS-1$
+	public static final String MIN_WIDTH = "min_width"; //$NON-NLS-1$
+	/** Data key for column id. */
+	public static final String COLUMN_ID = "column_id"; //$NON-NLS-1$
+	public static final String DMR = "domain_model_reference"; //$NON-NLS-1$
 	private final EMFDataBindingContext emfDatabindingContext;
 	private Optional<List<Control>> validationControls;
 
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/ColumnDescriptionImpl.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/ColumnDescriptionImpl.java
index 619cd17..d9c244e 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/ColumnDescriptionImpl.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/ColumnDescriptionImpl.java
@@ -11,6 +11,8 @@
  ******************************************************************************/
 package org.eclipse.emfforms.spi.swt.table;
 
+import java.util.Map;
+
 import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.emfforms.common.Optional;
 import org.eclipse.emfforms.spi.swt.table.TableViewerSWTCustomization.ColumnDescription;
@@ -23,6 +25,7 @@
  * Implementation of the {@link ColumnDescription}.
  *
  * @author Johannes Faltermeier
+ * @author Mathias Schaefer
  *
  */
 public class ColumnDescriptionImpl implements ColumnDescription {
@@ -37,6 +40,7 @@
 	private final CellLabelProviderFactory labelProvider;
 	private final Optional<EditingSupportCreator> editingSupport;
 	private final Optional<Image> image;
+	private final Map<String, Object> data;
 
 	// BEGIN COMPLEX CODE
 	/**
@@ -62,7 +66,8 @@
 		IObservableValue tooltipText,
 		CellLabelProviderFactory labelProvider,
 		EditingSupportCreator editingSupport,
-		Image image) {
+		Image image,
+		Map<String, Object> data) {
 		// END COMPLEX CODE
 		this.resizeable = resizeable;
 		this.moveable = moveable;
@@ -74,6 +79,7 @@
 		this.labelProvider = labelProvider;
 		this.editingSupport = Optional.ofNullable(editingSupport);
 		this.image = Optional.ofNullable(image);
+		this.data = data;
 	}
 
 	@Override
@@ -129,4 +135,19 @@
 		return image;
 	}
 
+	@Override
+	public void setData(Map<String, Object> data) {
+		this.data.putAll(data);
+	}
+
+	@Override
+	public Object getData(String key) {
+		return data.get(key);
+	}
+
+	@Override
+	public Map<String, Object> getData() {
+		return data;
+	}
+
 }
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerColumnBuilder.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerColumnBuilder.java
index 238a341..36a7f5d 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerColumnBuilder.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerColumnBuilder.java
@@ -119,6 +119,17 @@
 	}
 
 	/**
+	 * Configures the application data entries to be set for the {@link TableViewerColumn}.
+	 *
+	 * @param data the data entries to be added
+	 * @return the TableViewerColumnBuilder instance
+	 */
+	public TableViewerColumnBuilder setData(Map<String, Object> data) {
+		data.putAll(data);
+		return this;
+	}
+
+	/**
 	 * Configures the application data to be set for the {@link TableViewerColumn}.
 	 *
 	 * @param key the data key
@@ -131,6 +142,17 @@
 	}
 
 	/**
+	 * Append a map of items to the data map property for the {@link TableViewerColumn}.
+	 *
+	 * @param map to append to data map
+	 * @return the TableViewerColumnBuilder instance
+	 */
+	public TableViewerColumnBuilder addData(Map<String, Object> map) {
+		data.putAll(map);
+		return this;
+	}
+
+	/**
 	 * Configures the style of the {@link TableViewerColumn}.
 	 *
 	 * @param style the style bits to set
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerComposite.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerComposite.java
index d0b2c09..8202b57 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerComposite.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerComposite.java
@@ -127,17 +127,20 @@
 	}
 
 	@Override
+	// TODO: refactor (ms)
 	protected ViewerColumn createColumn(ColumnDescription columnDescription,
 		EMFDataBindingContext emfDataBindingContext, AbstractTableViewer tableViewer) {
 		final TableViewerColumnBuilder builder = TableViewerColumnBuilder
 			.create();
 
-		final TableViewerColumn column = builder.setData(RESIZABLE, columnDescription.isResizeable())
+		final TableViewerColumn column = builder
+			.setData(columnDescription.getData())
+			.setData(RESIZABLE, columnDescription.isResizeable())
 			.setMoveable(columnDescription.isMoveable())
 			.setStyle(columnDescription.getStyleBits())
 			.setData(WEIGHT, columnDescription.getWeight())
 			.setData(MIN_WIDTH, columnDescription.getMinWidth())
-			.build((TableViewer) getTableViewer());
+			.build(getTableViewer());
 
 		/* bind text and tooltip */
 		final IObservableValue text = columnDescription.getColumnText();
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTBuilder.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTBuilder.java
index 12ae098..5a377d9 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTBuilder.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTBuilder.java
@@ -12,6 +12,9 @@
  ******************************************************************************/
 package org.eclipse.emfforms.spi.swt.table;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.eclipse.core.databinding.observable.Observables;
 import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.emfforms.internal.swt.table.DefaultTableControlSWTCustomization;
@@ -44,6 +47,7 @@
 	private final IObservableValue title;
 	/** The tooltip. */
 	private final IObservableValue tooltip;
+	private Map<String, Object> columnData;
 
 	/**
 	 * @param composite the parent {@link Composite}
@@ -60,6 +64,7 @@
 		this.title = title;
 		this.tooltip = tooltip;
 		customization = new DefaultTableControlSWTCustomization();
+		columnData = new HashMap<String, Object>();
 	}
 
 	/**
@@ -221,6 +226,16 @@
 		return this;
 	}
 
+	/**
+	 * Add an arbitrary key/value pair.
+	 *
+	 * @param key literal
+	 * @param value object
+	 */
+	public void setData(String key, Object value) {
+		columnData.put(key, value);
+	}
+
 	// BEGIN COMPLEX CODE
 	/**
 	 * Adds a column.
@@ -261,8 +276,10 @@
 				tooltipText,
 				labelProvider,
 				editingSupport,
-				image));
+				image,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -306,8 +323,10 @@
 				tooltipText,
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				image));
+				image,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -351,8 +370,10 @@
 				Observables.constantObservableValue(tooltipText, String.class),
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				image));
+				image,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -394,8 +415,10 @@
 				tooltipText,
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -437,8 +460,10 @@
 				Observables.constantObservableValue(tooltipText, String.class),
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -469,8 +494,10 @@
 				tooltipText,
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -501,8 +528,10 @@
 				Observables.constantObservableValue(tooltipText, String.class),
 				new StaticCellLabelProviderFactory(labelProvider),
 				editingSupport,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -542,8 +571,10 @@
 				tooltipText,
 				new StaticCellLabelProviderFactory(labelProvider),
 				null,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -583,8 +614,10 @@
 				Observables.constantObservableValue(tooltipText, String.class),
 				new StaticCellLabelProviderFactory(labelProvider),
 				null,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -613,8 +646,10 @@
 				tooltipText,
 				new StaticCellLabelProviderFactory(labelProvider),
 				null,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
@@ -643,8 +678,10 @@
 				Observables.constantObservableValue(tooltipText, String.class),
 				new StaticCellLabelProviderFactory(labelProvider),
 				null,
-				null));
+				null,
+				columnData));
 
+		columnData = new HashMap<String, Object>();
 		return this;
 	}
 
diff --git a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTCustomization.java b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTCustomization.java
index e5d7afb..1bd6daa 100644
--- a/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTCustomization.java
+++ b/bundles/org.eclipse.emfforms.swt.table/src/org/eclipse/emfforms/spi/swt/table/TableViewerSWTCustomization.java
@@ -13,6 +13,7 @@
 package org.eclipse.emfforms.spi.swt.table;
 
 import java.util.List;
+import java.util.Map;
 
 import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.emfforms.common.Optional;
@@ -139,6 +140,28 @@
 		 */
 		Optional<Image> getColumnImage();
 
+		/**
+		 * Get an arbitrary element from the data map.
+		 *
+		 * @param key (see constants)
+		 * @return object
+		 */
+		Object getData(String key);
+
+		/**
+		 * Add the contents of the given map to the data map.
+		 * 
+		 * @param data object
+		 */
+		void setData(Map<String, Object> data);
+
+		/**
+		 * Get the underlying data map.
+		 *
+		 * @return data map object
+		 */
+		Map<String, Object> getData();
+
 	}
 
 }