commit 96e043f8e08ffe51975bc02b01987c3c151b9093
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Fri Jul 6 13:58:11 2018 +0200

    ref #7439 Split BulkEditorE4 in E4 part and Composite
    
     - clean up code

diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java
index 5ff92e15b..ce5fd0592 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorConfigLabelAccumulator.java
@@ -36,10 +36,10 @@ public class BulkEditorConfigLabelAccumulator implements IConfigLabelAccumulator
     public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
         CdmBase rowObject = dataProvider.getRowObject(rowPosition);
         if(input.getMergeCandidates().contains(rowObject)){
-            configLabels.addLabel(BulkEditorE4.CANDIDATE_LABEL);
+            configLabels.addLabel(BulkEditorE4Composite.CANDIDATE_LABEL);
         }
         else if(input.getMergeTarget()==rowObject){
-            configLabels.addLabel(BulkEditorE4.TARGET_LABEL);
+            configLabels.addLabel(BulkEditorE4Composite.TARGET_LABEL);
         }
     }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4.java
index f48b05d2b..c889f4c5c 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4.java
@@ -9,18 +9,12 @@
 
 package eu.etaxonomy.taxeditor.bulkeditor.e4;
 
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.inject.Inject;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
 import org.eclipse.e4.core.contexts.IEclipseContext;
 import org.eclipse.e4.core.di.annotations.Optional;
 import org.eclipse.e4.core.services.events.IEventBroker;
@@ -29,68 +23,15 @@ import org.eclipse.e4.ui.di.Persist;
 import org.eclipse.e4.ui.di.UIEventTopic;
 import org.eclipse.e4.ui.model.application.ui.MDirtyable;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.services.EMenuService;
-import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.nebula.widgets.nattable.NatTable;
-import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
-import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler;
-import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
-import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
-import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
-import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
-import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
-import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
-import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
-import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
-import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
-import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction;
-import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;
-import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
-import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
-import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
-import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
-import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
-import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
-import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack;
-import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
-import org.eclipse.nebula.widgets.nattable.selection.RowSelectionProvider;
-import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
-import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
-import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
-import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
-import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
-import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher;
-import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
-import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction;
-import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Menu;
 
-import ca.odell.glazedlists.SortedList;
 import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.conversation.IConversationEnabled;
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.description.SpecimenDescription;
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
 import eu.etaxonomy.cdm.model.taxon.Taxon;
@@ -99,7 +40,6 @@ import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
 import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
 import eu.etaxonomy.taxeditor.editor.ITaxonEditor;
 import eu.etaxonomy.taxeditor.event.WorkbenchEventConstants;
-import eu.etaxonomy.taxeditor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.IDerivedUnitFacadePart;
 import eu.etaxonomy.taxeditor.model.IDirtyMarkable;
 import eu.etaxonomy.taxeditor.model.IPartContentHasDetails;
@@ -119,28 +59,16 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
         IDirtyMarkable, IDerivedUnitFacadePart, IPartContentHasFactualData,
         IPartContentHasSupplementalData, IPartContentHasMedia, IE4SavablePart, ITaxonEditor {
 
-    public static final String TARGET_LABEL = "target";
-    public static final String CANDIDATE_LABEL = "candidate";
-
-    public static final String TYPE_PROPERTY = Messages.BulkEditorE4_TYPE;
-
     @Inject
 	private MDirtyable dirty;
 
     private AbstractBulkEditorInput input;
 
-    private Composite topComposite;
-
     private ConversationHolder conversation;
 
-    @Inject
-    private ESelectionService selService;
-
     @Inject
     private IEventBroker eventBroker;
 
-    private ISelectionChangedListener selectionChangedListener;
-
     @Inject
     IEclipseContext context;
 
@@ -149,16 +77,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 
     private BulkEditorQuery lastQuery = null;
 
-    private Composite bottomComposite;
-
-    @Inject
-    private EMenuService menuService;
-
-    private NatTable natTable;
-
-    private DefaultBodyLayerStack bodyLayer;
-
-    private ListDataProvider<CdmBase> bodyDataProvider;
+    private BulkEditorE4Composite bulkEditorComposite;
 
     @Inject
     public BulkEditorE4() {
@@ -168,195 +87,16 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     public void init(AbstractBulkEditorInput<?> input){
 	    this.input = input;
 	    this.conversation = input.getConversation();
-
-	    new BulkEditorSearchE4(this, topComposite, SWT.NONE);
-	    //layout needed because the search bar is added after @PostConstuct method
-	    topComposite.getParent().layout();
-
 	    thisPart.setLabel(input.getEditorName());
 
-        if(input.getEntityUuid()!=null){
-            performSearch(new BulkEditorQuery(input.getEntityUuid().toString()));
-        }
-
-        createTable();
-
-        configureTable();
-
-        styleTable();
-
-        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
-
-        //propagate selection
-        selectionChangedListener = (event -> selService.setSelection(getSelection()));
-        RowSelectionProvider<CdmBase> selectionProvider = new RowSelectionProvider<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, true);
-        selectionProvider.addSelectionChangedListener(selectionChangedListener);
-
-        bottomComposite.layout();
-	}
-
-	private void createTable(){
-	    ConfigRegistry configRegistry = new ConfigRegistry();
-	    //property map
-        Map<String, String> propertyToLabels = new HashMap<>();
-        propertyToLabels.put(getEditorInput().getName(), getEditorInput().getName());
-        propertyToLabels.put(TYPE_PROPERTY, TYPE_PROPERTY);
-        String[] propertyNames = new String[] { input.getName(), TYPE_PROPERTY };
-        //sorted list
-        SortedList<CdmBase> sortedList = new SortedList<>(input.getModel(), input.getTitleComparator());
-        //data provider
-        BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(input);
-        bodyDataProvider = new ListDataProvider<CdmBase>(sortedList,
-                columnPropertyAccessor);
-        DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(
-                propertyNames, propertyToLabels);
-        DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
-                bodyDataProvider);
-        //body
-        DataLayer dataLayer = new DataLayer(bodyDataProvider);
-        dataLayer.registerCommandHandler(new VisualRefreshCommandHandler());
-        GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, input.getModel());
-        bodyLayer = new DefaultBodyLayerStack(eventLayer);
-
-        dataLayer.setColumnPercentageSizing(true);
-        dataLayer.setColumnWidthPercentageByPosition(0, 80);
-        dataLayer.setColumnWidthPercentageByPosition(1, 20);
-
-        //column
-        DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider);
-        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
-                columnHeaderDataLayer,
-                bodyLayer, bodyLayer.getSelectionLayer());
-        // add the SortHeaderLayer to the column header layer stack
-        // as we use GlazedLists, we use the GlazedListsSortModel which
-        // delegates the sorting to the SortedList
-        final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>(
-                columnHeaderLayer,
-                new GlazedListsSortModel<>(
-                        sortedList,
-                        columnPropertyAccessor,
-                        configRegistry,
-                        columnHeaderDataLayer));
-        //row
-        DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
-        RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
-                bodyLayer, bodyLayer.getSelectionLayer());
-
-        //corner
-        DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
-                colHeaderDataProvider, rowHeaderDataProvider);
-        DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
-        CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer);
-        //grid
-        GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer,
-                rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing
-        natTable = new NatTable(bottomComposite, gridLayer, false);
-        natTable.setConfigRegistry(configRegistry);
-
-        //full row selection
-        bodyLayer.getSelectionLayer().setSelectionModel(new RowSelectionModel<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, new IRowIdAccessor<CdmBase>() {
-            @Override
-            public Serializable getRowId(CdmBase rowObject) {
-                return input.getModel().indexOf(rowObject);
-            }
-        }));
-
-        //add label to deduplication rows
-        dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, input));
-
-        //add tooltip to table
-        new BulkEditorTooltip(natTable);
-	}
-
-	private void configureTable(){
-
-	    //this configuration enables cell to be editable in general
-	    //necessary because we disabled this beforehand by setting autoconfigure=false
-	    //in the GridLayer constructor
-	    ((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration());
-
-        natTable.addConfiguration(new AbstractUiBindingConfiguration() {
-            @Override
-            public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
-                uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY),
-                        new MouseEditAction());
-            }
-        });
-
-        //make cells editable to allow selecting the text
-        natTable.addConfiguration(new AbstractRegistryConfiguration() {
-            @Override
-            public void configureRegistry(IConfigRegistry configRegistry) {
-                //make cell editable
-                configRegistry.registerConfigAttribute(
-                        EditConfigAttributes.CELL_EDITABLE_RULE,
-                        IEditableRule.ALWAYS_EDITABLE,
-                        DisplayMode.EDIT);
-                //register editor
-                TextCellEditor editor = new TextCellEditor();
-                editor.setEditable(false);
-                configRegistry.registerConfigAttribute(
-                        EditConfigAttributes.CELL_EDITOR,
-                        editor,
-                        DisplayMode.NORMAL);
-            }
-        });
-
-        //+++CONTEXT MENU+++
-        menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
-        // get the menu registered by EMenuService
-        final Menu e4Menu = natTable.getMenu();
-        // remove the menu reference from NatTable instance
-        natTable.setMenu(null);
-        natTable.addConfiguration(
-                new AbstractUiBindingConfiguration() {
-            @Override
-            public void configureUiBindings(
-                    UiBindingRegistry uiBindingRegistry) {
-                // add e4 menu to NatTable
-                new PopupMenuBuilder(natTable, e4Menu)
-                    .build();
-
-                // register the UI binding for header, corner and body region
-                uiBindingRegistry.registerMouseDownBinding(
-                        new MouseEventMatcher(
-                                SWT.NONE,
-                                null,
-                                MouseEventMatcher.RIGHT_BUTTON),
-                        new PopupMenuAction(e4Menu));
-            }
-        });
-
-
-        //enable sorting
-        natTable.addConfiguration(new SingleClickSortConfiguration());
-
-        // Custom style for deduplication labels
-        natTable.addConfiguration(new LabelStyleConfiguration());
-
-        //add default configuration because autoconfigure is set to false in constructor
-        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
-        natTable.configure();
-	}
-
-	private void styleTable(){
-	    natTable.setTheme(new ModernNatTableThemeConfiguration());
+	    bulkEditorComposite.init(input);
 	}
 
 	/** {@inheritDoc} */
 	@PostConstruct
-	public void createPartControl(Composite parent) {
-		parent.setLayout(new GridLayout());
-
-		topComposite = new Composite(parent, SWT.NONE);
-		topComposite.setLayout(new GridLayout());
-
-		GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
-		topComposite.setLayoutData(gridData);
-
-		bottomComposite = new Composite(parent, SWT.NONE);
-		bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
-		bottomComposite.setLayout(new GridLayout());
+	public void createPartControl(Composite parent, IEclipseContext context) {
+	    bulkEditorComposite = new BulkEditorE4Composite(this, parent, SWT.NONE);
+	    ContextInjectionFactory.inject(bulkEditorComposite, context);
 	}
 
 	@Override
@@ -365,6 +105,24 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 	    save(monitor, true);
 	}
 
+    public void save(IProgressMonitor monitor, boolean resetMerge) {
+        if (!input.getCdmEntitySession().isActive()){
+            input.getCdmEntitySession().bind();
+        }
+        input.saveModel(resetMerge);
+
+        IStructuredSelection selection = getSelection();
+
+        dirty.setDirty(false);
+        input.dispose();
+        input.bind();
+        conversation.commit(true);
+
+        if (lastQuery != null){
+            bulkEditorComposite.performSearch(lastQuery, selection);
+        }
+    }
+
 	@Focus
 	public void setFocus() {
         //make sure to bind again if maybe in another view the conversation was unbound
@@ -391,49 +149,6 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 	    dirty.setDirty(false);
 	}
 
-	public void save(IProgressMonitor monitor, boolean resetMerge) {
-	    if (!input.getCdmEntitySession().isActive()){
-            input.getCdmEntitySession().bind();
-        }
-	    input.saveModel(resetMerge);
-
-	    IStructuredSelection selection = getSelection();
-
-        dirty.setDirty(false);
-        input.dispose();
-        input.bind();
-        conversation.commit(true);
-
-        if (lastQuery != null){
-            performSearch(lastQuery, selection);
-        }
-	}
-
-	public void performSearch(BulkEditorQuery query) {
-	    performSearch(query, null);
-	}
-
-	/** {@inheritDoc}
-	 * @param selection */
-    public void performSearch(BulkEditorQuery query, IStructuredSelection selection) {
-        if (query != null) {
-            // TODO check if dirty, prompt save
-            if (isDirty()) {
-                String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
-                MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
-                int result = dialog.open();
-                if (result == 0) {
-                    save(new NullProgressMonitor());
-                } else if (result == 2){
-                    return;
-                }
-            }
-            dirty.setDirty(false);
-            input.performSearch(query, selection);
-            lastQuery = query;
-        }
-    }
-
     @Optional
     @Inject
     private void updateAfterSearch(@UIEventTopic(WorkbenchEventConstants.BULK_EDITOR_SEARCH_FINISHED)IStructuredSelection selection){
@@ -443,33 +158,23 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     }
 
     public void refresh(){
-        natTable.doCommand(new VisualRefreshCommand());
+        bulkEditorComposite.refresh();
     }
 
     public IStructuredSelection getSelection(){
-        List<CdmBase> selection = new ArrayList<>();
-        int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
-        for (int i : fullySelectedRowPositions) {
-            Object rowObject = bodyDataProvider.getRowObject(i);
-            if(rowObject instanceof CdmBase){
-                selection.add((CdmBase) rowObject);
-            }
-        }
-        return new StructuredSelection(selection);
+        return bulkEditorComposite.getSelection();
     }
 
     public void setSelection(IStructuredSelection selection){
-        Object[] objects = selection.toArray();
-        for (Object object : objects) {
+        bulkEditorComposite.setSelection(selection);
+    }
 
-            if(object instanceof CdmBase &&  input.getModel().contains(object)){
-                bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false);
-            }
-        }
+    public void setDirty(boolean isDirty){
+        dirty.setDirty(isDirty);
     }
 
     public void setDirty(){
-        dirty.setDirty(true);
+        setDirty(true);
     }
 
     public boolean isDirty() {
@@ -481,22 +186,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
     }
 
     public void copyDataToClipboard() {
-        String textData = "";
-        IStructuredSelection selection = getSelection();
-        Object[] objects = selection.toArray();
-        for (Object object : objects) {
-            if(object instanceof CdmBase){
-                textData += getEditorInput().getText((CdmBase)object);
-            }
-        }
-        final TextTransfer textTransfer = TextTransfer.getInstance();
-        final Clipboard clipboard = new Clipboard(Display.getDefault());
-        try {
-            clipboard.setContents(new Object[] { textData.toString() },
-                    new Transfer[] { textTransfer });
-        } finally {
-            clipboard.dispose();
-        }
+        bulkEditorComposite.copyDataToClipboard();
     }
 
     @Override
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4Composite.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4Composite.java
new file mode 100644
index 000000000..43ad72289
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorE4Composite.java
@@ -0,0 +1,381 @@
+/**
+* Copyright (C) 2007 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.taxeditor.bulkeditor.e4;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.e4.ui.services.EMenuService;
+import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.nebula.widgets.nattable.NatTable;
+import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommand;
+import org.eclipse.nebula.widgets.nattable.command.VisualRefreshCommandHandler;
+import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
+import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
+import org.eclipse.nebula.widgets.nattable.config.IEditableRule;
+import org.eclipse.nebula.widgets.nattable.data.IRowIdAccessor;
+import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
+import org.eclipse.nebula.widgets.nattable.edit.EditConfigAttributes;
+import org.eclipse.nebula.widgets.nattable.edit.action.MouseEditAction;
+import org.eclipse.nebula.widgets.nattable.edit.config.DefaultEditConfiguration;
+import org.eclipse.nebula.widgets.nattable.edit.editor.TextCellEditor;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsEventLayer;
+import org.eclipse.nebula.widgets.nattable.extension.glazedlists.GlazedListsSortModel;
+import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
+import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
+import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.layer.AbstractLayer;
+import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
+import org.eclipse.nebula.widgets.nattable.layer.stack.DefaultBodyLayerStack;
+import org.eclipse.nebula.widgets.nattable.selection.RowSelectionModel;
+import org.eclipse.nebula.widgets.nattable.selection.RowSelectionProvider;
+import org.eclipse.nebula.widgets.nattable.sort.SortHeaderLayer;
+import org.eclipse.nebula.widgets.nattable.sort.config.SingleClickSortConfiguration;
+import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
+import org.eclipse.nebula.widgets.nattable.style.theme.ModernNatTableThemeConfiguration;
+import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
+import org.eclipse.nebula.widgets.nattable.ui.matcher.CellEditorMouseEventMatcher;
+import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
+import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuAction;
+import org.eclipse.nebula.widgets.nattable.ui.menu.PopupMenuBuilder;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+
+import ca.odell.glazedlists.SortedList;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.description.SpecimenDescription;
+import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
+import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
+import eu.etaxonomy.taxeditor.l10n.Messages;
+
+/**
+ *
+ * @author pplitzner
+ * @since Sep 8, 2017
+ *
+ */
+public class BulkEditorE4Composite extends Composite {
+
+    public static final String TYPE_PROPERTY = Messages.BulkEditorE4_TYPE;
+
+    public static final String CANDIDATE_LABEL = "candidate";
+
+    public static final String TARGET_LABEL = "target";
+
+    private Composite topComposite;
+
+    @Inject
+    private ESelectionService selService;
+
+    private ISelectionChangedListener selectionChangedListener;
+
+    private Composite bottomComposite;
+
+    @Inject
+    private EMenuService menuService;
+
+    private NatTable natTable;
+
+    private DefaultBodyLayerStack bodyLayer;
+
+    private ListDataProvider<CdmBase> bodyDataProvider;
+
+    private BulkEditorE4 bulkEditor;
+
+
+    public BulkEditorE4Composite(BulkEditorE4 bulkEditor, Composite parent, int style) {
+        super(parent, style);
+        parent.setLayout(new GridLayout());
+        this.bulkEditor = bulkEditor;
+
+        this.setLayout(new GridLayout());
+
+        topComposite = new Composite(parent, SWT.NONE);
+        topComposite.setLayout(new GridLayout());
+
+        GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
+        topComposite.setLayoutData(gridData);
+
+        bottomComposite = new Composite(parent, SWT.NONE);
+        bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+        bottomComposite.setLayout(new GridLayout());
+	}
+
+	@SuppressWarnings("unused")
+    public void init(AbstractBulkEditorInput<?> input){
+
+	    new BulkEditorSearchE4(this, topComposite, SWT.NONE);
+	    //layout needed because the search bar is added after @PostConstuct method
+	    topComposite.getParent().layout();
+
+        if(input.getEntityUuid()!=null){
+            performSearch(new BulkEditorQuery(input.getEntityUuid().toString()));
+        }
+
+        createTable();
+
+        configureTable();
+
+        styleTable();
+
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(natTable);
+
+        //propagate selection
+        selectionChangedListener = (event -> selService.setSelection(getSelection()));
+        RowSelectionProvider<CdmBase> selectionProvider = new RowSelectionProvider<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, true);
+        selectionProvider.addSelectionChangedListener(selectionChangedListener);
+
+        bottomComposite.layout();
+	}
+
+	private void createTable(){
+	    ConfigRegistry configRegistry = new ConfigRegistry();
+	    //property map
+        Map<String, String> propertyToLabels = new HashMap<>();
+        propertyToLabels.put(bulkEditor.getEditorInput().getName(), bulkEditor.getEditorInput().getName());
+        propertyToLabels.put(TYPE_PROPERTY, TYPE_PROPERTY);
+        String[] propertyNames = new String[] { bulkEditor.getEditorInput().getName(), TYPE_PROPERTY };
+        //sorted list
+        SortedList<CdmBase> sortedList = new SortedList<>(bulkEditor.getEditorInput().getModel(), bulkEditor.getEditorInput().getTitleComparator());
+        //data provider
+        BulkEditorPropertyAccessor columnPropertyAccessor = new BulkEditorPropertyAccessor(bulkEditor.getEditorInput());
+        bodyDataProvider = new ListDataProvider<CdmBase>(sortedList,
+                columnPropertyAccessor);
+        DefaultColumnHeaderDataProvider colHeaderDataProvider = new DefaultColumnHeaderDataProvider(
+                propertyNames, propertyToLabels);
+        DefaultRowHeaderDataProvider rowHeaderDataProvider = new DefaultRowHeaderDataProvider(
+                bodyDataProvider);
+        //body
+        DataLayer dataLayer = new DataLayer(bodyDataProvider);
+        dataLayer.registerCommandHandler(new VisualRefreshCommandHandler());
+        GlazedListsEventLayer<CdmBase> eventLayer = new GlazedListsEventLayer<>(dataLayer, bulkEditor.getEditorInput().getModel());
+        bodyLayer = new DefaultBodyLayerStack(eventLayer);
+
+        dataLayer.setColumnPercentageSizing(true);
+        dataLayer.setColumnWidthPercentageByPosition(0, 80);
+        dataLayer.setColumnWidthPercentageByPosition(1, 20);
+
+        //column
+        DataLayer columnHeaderDataLayer = new DataLayer(colHeaderDataProvider);
+        ColumnHeaderLayer columnHeaderLayer = new ColumnHeaderLayer(
+                columnHeaderDataLayer,
+                bodyLayer, bodyLayer.getSelectionLayer());
+        // add the SortHeaderLayer to the column header layer stack
+        // as we use GlazedLists, we use the GlazedListsSortModel which
+        // delegates the sorting to the SortedList
+        final SortHeaderLayer<SpecimenDescription> sortHeaderLayer = new SortHeaderLayer<>(
+                columnHeaderLayer,
+                new GlazedListsSortModel<>(
+                        sortedList,
+                        columnPropertyAccessor,
+                        configRegistry,
+                        columnHeaderDataLayer));
+        //row
+        DataLayer rowHeaderDataLayer = new DataLayer(rowHeaderDataProvider);
+        RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(rowHeaderDataLayer,
+                bodyLayer, bodyLayer.getSelectionLayer());
+
+        //corner
+        DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(
+                colHeaderDataProvider, rowHeaderDataProvider);
+        DataLayer cornerDataLayer = new DataLayer(cornerDataProvider);
+        CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowHeaderLayer, sortHeaderLayer);
+        //grid
+        GridLayer gridLayer = new GridLayer(bodyLayer, sortHeaderLayer,
+                rowHeaderLayer, cornerLayer, false);//set autoconfigure to false to get rid of the single click editing
+        natTable = new NatTable(bottomComposite, gridLayer, false);
+        natTable.setConfigRegistry(configRegistry);
+
+        //full row selection
+        bodyLayer.getSelectionLayer().setSelectionModel(new RowSelectionModel<CdmBase>(bodyLayer.getSelectionLayer(), bodyDataProvider, new IRowIdAccessor<CdmBase>() {
+            @Override
+            public Serializable getRowId(CdmBase rowObject) {
+                return bulkEditor.getEditorInput().getModel().indexOf(rowObject);
+            }
+        }));
+
+        //add label to deduplication rows
+        dataLayer.setConfigLabelAccumulator(new BulkEditorConfigLabelAccumulator(bodyDataProvider, bulkEditor.getEditorInput()));
+
+        //add tooltip to table
+        new BulkEditorTooltip(natTable);
+	}
+
+	private void configureTable(){
+
+	    //this configuration enables cell to be editable in general
+	    //necessary because we disabled this beforehand by setting autoconfigure=false
+	    //in the GridLayer constructor
+	    ((AbstractLayer) natTable.getLayer()).addConfiguration(new DefaultEditConfiguration());
+
+        natTable.addConfiguration(new AbstractUiBindingConfiguration() {
+            @Override
+            public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
+                uiBindingRegistry.registerFirstDoubleClickBinding(new CellEditorMouseEventMatcher(GridRegion.BODY),
+                        new MouseEditAction());
+            }
+        });
+
+        //make cells editable to allow selecting the text
+        natTable.addConfiguration(new AbstractRegistryConfiguration() {
+            @Override
+            public void configureRegistry(IConfigRegistry configRegistry) {
+                //make cell editable
+                configRegistry.registerConfigAttribute(
+                        EditConfigAttributes.CELL_EDITABLE_RULE,
+                        IEditableRule.ALWAYS_EDITABLE,
+                        DisplayMode.EDIT);
+                //register editor
+                TextCellEditor editor = new TextCellEditor();
+                editor.setEditable(false);
+                configRegistry.registerConfigAttribute(
+                        EditConfigAttributes.CELL_EDITOR,
+                        editor,
+                        DisplayMode.NORMAL);
+            }
+        });
+
+        //+++CONTEXT MENU+++
+        menuService.registerContextMenu(natTable, "eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor"); //$NON-NLS-1$
+        // get the menu registered by EMenuService
+        final Menu e4Menu = natTable.getMenu();
+        // remove the menu reference from NatTable instance
+        natTable.setMenu(null);
+        natTable.addConfiguration(
+                new AbstractUiBindingConfiguration() {
+            @Override
+            public void configureUiBindings(
+                    UiBindingRegistry uiBindingRegistry) {
+                // add e4 menu to NatTable
+                new PopupMenuBuilder(natTable, e4Menu)
+                    .build();
+
+                // register the UI binding for header, corner and body region
+                uiBindingRegistry.registerMouseDownBinding(
+                        new MouseEventMatcher(
+                                SWT.NONE,
+                                null,
+                                MouseEventMatcher.RIGHT_BUTTON),
+                        new PopupMenuAction(e4Menu));
+            }
+        });
+
+
+        //enable sorting
+        natTable.addConfiguration(new SingleClickSortConfiguration());
+
+        // Custom style for deduplication labels
+        natTable.addConfiguration(new LabelStyleConfiguration());
+
+        //add default configuration because autoconfigure is set to false in constructor
+        natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
+        natTable.configure();
+	}
+
+	private void styleTable(){
+	    natTable.setTheme(new ModernNatTableThemeConfiguration());
+	}
+
+	public void performSearch(BulkEditorQuery query) {
+	    performSearch(query, null);
+	}
+
+	/** {@inheritDoc}
+	 * @param selection */
+    public void performSearch(BulkEditorQuery query, IStructuredSelection selection) {
+        if (query != null) {
+            if (bulkEditor.isDirty()) {
+                String[] labels = {Messages.BulkEditorE4_SAVE_AND_SEARCH, Messages.BulkEditorE4_DONT_SAVE,Messages.BulkEditorE4_CANCEL};
+                MessageDialog dialog =new MessageDialog(topComposite.getShell(), Messages.BulkEditorE4_SAVE_CHANGES_TITLE, null, Messages.BulkEditorE4_SAVE_CHANGES_MESSAGE, MessageDialog.QUESTION,labels, 0);
+                int result = dialog.open();
+                if (result == 0) {
+                    bulkEditor.save(new NullProgressMonitor());
+                } else if (result == 2){
+                    return;
+                }
+            }
+            bulkEditor.setDirty(false);
+            bulkEditor.getEditorInput().performSearch(query, selection);
+            bulkEditor.setLastQuery(query);
+        }
+    }
+
+    public void refresh(){
+        natTable.doCommand(new VisualRefreshCommand());
+    }
+
+    public IStructuredSelection getSelection(){
+        List<CdmBase> selection = new ArrayList<>();
+        int[] fullySelectedRowPositions = bodyLayer.getSelectionLayer().getFullySelectedRowPositions();
+        for (int i : fullySelectedRowPositions) {
+            Object rowObject = bodyDataProvider.getRowObject(i);
+            if(rowObject instanceof CdmBase){
+                selection.add((CdmBase) rowObject);
+            }
+        }
+        return new StructuredSelection(selection);
+    }
+
+    public void setSelection(IStructuredSelection selection){
+        Object[] objects = selection.toArray();
+        for (Object object : objects) {
+
+            if(object instanceof CdmBase &&  bulkEditor.getEditorInput().getModel().contains(object)){
+                bodyLayer.getSelectionLayer().selectRow(0, bodyDataProvider.indexOfRowObject((CdmBase) object), false, false);
+            }
+        }
+    }
+
+    public void copyDataToClipboard() {
+        String textData = "";
+        IStructuredSelection selection = getSelection();
+        Object[] objects = selection.toArray();
+        for (Object object : objects) {
+            if(object instanceof CdmBase){
+                textData += bulkEditor.getEditorInput().getText((CdmBase)object);
+            }
+        }
+        final TextTransfer textTransfer = TextTransfer.getInstance();
+        final Clipboard clipboard = new Clipboard(Display.getDefault());
+        try {
+            clipboard.setContents(new Object[] { textData.toString() },
+                    new Transfer[] { textTransfer });
+        } finally {
+            clipboard.dispose();
+        }
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorFocusCellOwnerDrawHighLighter.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorFocusCellOwnerDrawHighLighter.java
deleted file mode 100755
index 0563d34c5..000000000
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorFocusCellOwnerDrawHighLighter.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// $Id$
-/**
-* Copyright (C) 2018 EDIT
-* European Distributed Institute of Taxonomy
-* http://www.e-taxonomy.eu
-*
-* The contents of this file are subject to the Mozilla Public License Version 1.1
-* See LICENSE.TXT at the top of this package for the full license terms.
-*/
-package eu.etaxonomy.taxeditor.bulkeditor.e4;
-
-import org.eclipse.jface.viewers.ColumnViewer;
-import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-
-/**
- * @author k.luther
- * @date 02.03.2018
- *
- */
-public class BulkEditorFocusCellOwnerDrawHighLighter extends FocusCellOwnerDrawHighlighter {
-
-    /**
-     * @param viewer
-     */
-    public BulkEditorFocusCellOwnerDrawHighLighter(ColumnViewer viewer) {
-        super(viewer);
-
-    }
-
-
-    /**
-     * The color to use when rendering the background of the selected cell when
-     * the control has <b>no</b> input focus
-     *
-     * @param cell
-     *            the cell which is colored
-     * @return the color or <code>null</code> to use the same used when
-     *         control has focus
-     * @since 3.4
-     */
-    @Override
-    protected Color getSelectedCellBackgroundColorNoFocus(ViewerCell cell) {
-        return cell.getItem().getDisplay().getSystemColor(
-                SWT.COLOR_LIST_SELECTION);
-    }
-
-    /**
-     * The color to use when rendering the foreground (=text) of the selected
-     * cell when the control has <b>no</b> input focus
-     *
-     * @param cell
-     *            the cell which is colored
-     * @return the color or <code>null</code> to use the same used when
-     *         control has focus
-     * @since 3.4
-     */
-    @Override
-    protected Color getSelectedCellForegroundColorNoFocus(ViewerCell cell) {
-        return cell.getItem().getDisplay().getSystemColor(
-                SWT.COLOR_LIST_SELECTION_TEXT);
-    }
-
-
-
-}
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelProvider.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelProvider.java
deleted file mode 100644
index 51f2f612c..000000000
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelProvider.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// $Id$
-/**
-* Copyright (C) 2017 EDIT
-* European Distributed Institute of Taxonomy
-* http://www.e-taxonomy.eu
-*
-* The contents of this file are subject to the Mozilla Public License Version 1.1
-* See LICENSE.TXT at the top of this package for the full license terms.
-*/
-package eu.etaxonomy.taxeditor.bulkeditor.e4;
-
-import java.net.URISyntaxException;
-import java.net.URL;
-
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
-import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
-import eu.etaxonomy.taxeditor.model.ImageResources;
-
-/**
- * @author pplitzner
- * @date 11.09.2017
- *
- */
-public class BulkEditorLabelProvider extends LabelProvider implements ITableLabelProvider{
-
-    private BulkEditorE4 editor;
-
-    public BulkEditorLabelProvider(BulkEditorE4 editor) {
-        super();
-        this.editor = editor;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Image getColumnImage(Object element, int columnIndex) {
-        if (columnIndex == 0) {
-            AbstractBulkEditorInput input = editor.getEditorInput();
-
-            try {
-                if(input.getMergeCandidates().contains(element)){
-                    IPath path = new Path("icons/merge_candidate.gif"); //$NON-NLS-1$
-                    URL url = FileLocator.find(TaxeditorBulkeditorPlugin.getDefault().getBundle(), path, null);
-                    return ImageResources.getImage(url.toURI());
-                }
-                else if(input.getMergeTarget()!=null && input.getMergeTarget().equals(element)){
-                    IPath path = new Path("icons/merge_target.gif"); //$NON-NLS-1$
-                    URL url = FileLocator.find(TaxeditorBulkeditorPlugin.getDefault().getBundle(), path, null);
-                    return ImageResources.getImage(url.toURI());
-                }
-            } catch (URISyntaxException e) {
-                return null;
-            }
-        }
-        return null;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public String getColumnText(Object element, int columnIndex) {
-        String text = null;
-
-        if (columnIndex == 0) {
-            if(element instanceof CdmBase){
-                text = editor.getEditorInput().getText((CdmBase) element);
-            }
-        }else if (columnIndex == 1) {
-            if(editor.getEditorInput().getTypeText(element)!=null){
-                text = editor.getEditorInput().getTypeText(element);
-            }
-        }
-        return text;
-    }
-
-
-}
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java
index 1a25cc356..4cb012d2c 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorPropertyAccessor.java
@@ -53,7 +53,7 @@ public class BulkEditorPropertyAccessor implements IColumnPropertyAccessor<CdmBa
             if(columnIndex==0){
                 return input.getName();
             }else if(columnIndex==1){
-                return BulkEditorE4.TYPE_PROPERTY;
+                return BulkEditorE4Composite.TYPE_PROPERTY;
             }
             return null;
         }
@@ -63,7 +63,7 @@ public class BulkEditorPropertyAccessor implements IColumnPropertyAccessor<CdmBa
             if(propertyName.equals(input.getName())){
                 return 0;
             }
-            else if(propertyName.equals(BulkEditorE4.TYPE_PROPERTY)){
+            else if(propertyName.equals(BulkEditorE4Composite.TYPE_PROPERTY)){
                 return 1;
             }
             return 0;
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearchE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearchE4.java
index a1365b946..1321eb3f6 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearchE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorSearchE4.java
@@ -45,7 +45,7 @@ public class BulkEditorSearchE4 {
 
 	private static final String DEFAULT_TEXT = String.format(Messages.BulkEditorSearchE4_WILDCARD, SearchManager.WILDCARD);
 
-	private final BulkEditorE4 editor;
+	private final BulkEditorE4Composite editor;
 
 	private Text text;
 
@@ -54,7 +54,7 @@ public class BulkEditorSearchE4 {
 
 	public Object ORDER_BY = new Object();
 
-	public BulkEditorSearchE4(BulkEditorE4 editor, Composite parent, int style) {
+	public BulkEditorSearchE4(BulkEditorE4Composite editor, Composite parent, int style) {
 		this.editor = editor;
 
 		createControl(parent, style);
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java
index 73c11cb39..6282dbf7f 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorTooltip.java
@@ -46,10 +46,10 @@ public class BulkEditorTooltip extends DefaultToolTip {
         int row = this.natTable.getRowPositionByY(event.y);
 
         LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row);
-        if(configLabels.hasLabel(BulkEditorE4.TARGET_LABEL)){
+        if(configLabels.hasLabel(BulkEditorE4Composite.TARGET_LABEL)){
             return Messages.BulkEditorTooltip_TARGET;
         }
-        else if(configLabels.hasLabel(BulkEditorE4.CANDIDATE_LABEL)){
+        else if(configLabels.hasLabel(BulkEditorE4Composite.CANDIDATE_LABEL)){
             return Messages.BulkEditorTooltip_CANDIDATE;
         }
         return ""; //$NON-NLS-1$
@@ -67,8 +67,8 @@ public class BulkEditorTooltip extends DefaultToolTip {
         int row = this.natTable.getRowPositionByY(event.y);
 
         LabelStack configLabels = natTable.getConfigLabelsByPosition(col, row);
-        if(configLabels.hasLabel(BulkEditorE4.CANDIDATE_LABEL)
-                || configLabels.hasLabel(BulkEditorE4.TARGET_LABEL)){
+        if(configLabels.hasLabel(BulkEditorE4Composite.CANDIDATE_LABEL)
+                || configLabels.hasLabel(BulkEditorE4Composite.TARGET_LABEL)){
             return true;
         }
         return false;
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/LabelStyleConfiguration.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/LabelStyleConfiguration.java
index c2339904d..10b6b03db 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/LabelStyleConfiguration.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/LabelStyleConfiguration.java
@@ -30,7 +30,7 @@ public final class LabelStyleConfiguration extends AbstractRegistryConfiguration
                 GUIHelper.COLOR_YELLOW);
         configRegistry.registerConfigAttribute(
                 CellConfigAttributes.CELL_STYLE, cellStyle,
-                DisplayMode.NORMAL, BulkEditorE4.CANDIDATE_LABEL);
+                DisplayMode.NORMAL, BulkEditorE4Composite.CANDIDATE_LABEL);
 
         cellStyle = new Style();
         cellStyle.setAttributeValue(
@@ -38,7 +38,7 @@ public final class LabelStyleConfiguration extends AbstractRegistryConfiguration
                 GUIHelper.COLOR_GREEN);
         configRegistry.registerConfigAttribute(
                 CellConfigAttributes.CELL_STYLE, cellStyle,
-                DisplayMode.NORMAL, BulkEditorE4.TARGET_LABEL);
+                DisplayMode.NORMAL, BulkEditorE4Composite.TARGET_LABEL);
 
     }
 }
\ No newline at end of file
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java
index 521bc4745..958c266e1 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AbstractBulkEditorInput.java
@@ -304,14 +304,7 @@ public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEnti
 	public String getText(T entity) {
 		if(entity instanceof IdentifiableEntity){
 			IdentifiableEntity identifiableEntity = (IdentifiableEntity) HibernateProxyHelper.deproxy(entity);
-			String text = ""; //$NON-NLS-1$
-			if(markedMergeCandidates.contains(entity)){
-			    text += Messages.AbstractBulkEditorInput_CANDIDATE;
-			}
-			else if(markedMergeTarget==entity){
-			    text += Messages.AbstractBulkEditorInput_TARGET;
-			}
-			text += identifiableEntity.getTitleCache();
+			String text = identifiableEntity.getTitleCache();
 			return text;
 		}
 
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java
index 9c9de3eca..fa22ae4de 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/Messages.java
@@ -4,12 +4,10 @@ import org.eclipse.osgi.util.NLS;
 
 public class Messages extends NLS {
     private static final String BUNDLE_NAME = "src/main/java/eu.etaxonomy.taxeditor.l10n.messages"; //$NON-NLS-1$
-    public static String AbstractBulkEditorInput_CANDIDATE;
     public static String AbstractBulkEditorInput_LOADED;
     public static String AbstractBulkEditorInput_LOADING;
     public static String AbstractBulkEditorInput_MERGE_ERROR_MESSAGE;
     public static String AbstractBulkEditorInput_MERGE_ERROR_TITLE;
-    public static String AbstractBulkEditorInput_TARGET;
     public static String USER_CREATOR_user_exists_title;
     public static String USER_CREATOR_user_exists;
     public static String BulkEditorE4_CANCEL;
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties
index b34d3b229..5fe8b73a3 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages.properties
@@ -1,9 +1,7 @@
-AbstractBulkEditorInput_CANDIDATE=[Candidate] 
 AbstractBulkEditorInput_LOADED=%s/%s %s loaded
 AbstractBulkEditorInput_LOADING=Loading %s for %s 
 AbstractBulkEditorInput_MERGE_ERROR_MESSAGE=Could not merge chosen objects of type %s
 AbstractBulkEditorInput_MERGE_ERROR_TITLE=Merging failes
-AbstractBulkEditorInput_TARGET=[Target] 
 BulkEditorE4_CANCEL=Cancel
 BulkEditorE4_DONT_SAVE=Don't save (and Search)
 BulkEditorE4_SAVE_AND_SEARCH=Save (and Search)
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties
index 9044ddde5..dad790d83 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/l10n/messages_de.properties
@@ -1,9 +1,7 @@
-AbstractBulkEditorInput_CANDIDATE=[Kandidat] 
 AbstractBulkEditorInput_LOADED=%s/%s %s geladen
 AbstractBulkEditorInput_LOADING=Lade %s für %s
 AbstractBulkEditorInput_MERGE_ERROR_MESSAGE=Zusammenführen von Objekten des Typen %s fehlgeschlagen 
 AbstractBulkEditorInput_MERGE_ERROR_TITLE=Zusammenführen fehlgeschlagen
-AbstractBulkEditorInput_TARGET=[Ziel] 
 BulkEditorE4_CANCEL=Abbrechen
 BulkEditorE4_DONT_SAVE=Nicht speichern (und suchen)
 BulkEditorE4_SAVE_AND_SEARCH=Speichern (und suchen)
