commit 5cfc8708441a139bd767ab38a4cb2e21062c0391
Author: Patrick Plitzner <p.plitzner@bgbm.org>
Date:   Tue Sep 12 16:51:15 2017 +0200

    ref #6932 Migrate bulk editor handlers and add annotation merge support

diff --git a/eu.etaxonomy.taxeditor.bulkeditor/fragment.e4xmi b/eu.etaxonomy.taxeditor.bulkeditor/fragment.e4xmi
index ccf47a9e0..8d3a8b524 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/fragment.e4xmi
+++ b/eu.etaxonomy.taxeditor.bulkeditor/fragment.e4xmi
@@ -53,24 +53,19 @@
       <handlers xmi:id="_vskBsJcOEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.annotatedlineeditor.e4.handler.DeleteObjectHandlerE4" contributionURI="bundleclass://eu.etaxonomy.taxeditor.bulkeditor/eu.etaxonomy.taxeditor.annotatedlineeditor.e4.handler.DeleteObjectHandlerE4" command="_tLGKgJcOEeeM745tzuPNCQ"/>
       <menus xsi:type="menu:PopupMenu" xmi:id="_B6IFsJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.popupmenu.bulkeditor">
         <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_H83EMJcMEeeM745tzuPNCQ" coreExpressionId="isCdmStoreConnected"/>
-        <children xsi:type="menu:Menu" xmi:id="_QNTQYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menu.new" label="%menu.label.1">
-          <children xsi:type="menu:DynamicMenuContribution" xmi:id="_TbcAUJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.dynamicmenucontribution.new"/>
-        </children>
-        <children xsi:type="menu:DynamicMenuContribution" xmi:id="_1xx-YJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.dynamicmenucontribution.bulkEditor.openInCdmViewer" contributionURI="bundleclass://eu.etaxonomy.taxeditor.store/eu.etaxonomy.taxeditor.view.CdmViewerContextMenuE4"/>
+        <children xsi:type="menu:DynamicMenuContribution" xmi:id="_Y49vAJfHEeeUB5KN7hGpYQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.e4.command.DynamicNewObjectMenuE4" contributionURI="bundleclass://eu.etaxonomy.taxeditor.bulkeditor/eu.etaxonomy.taxeditor.bulkeditor.e4.command.DynamicNewObjectMenuE4"/>
         <children xsi:type="menu:MenuSeparator" xmi:id="_VhML4JcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menuseparator.1"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_WOzf0JcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.setMergeTarget" label="%command.label.0"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_c0pycJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.setMergeCandidate" label="%command.label.1"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_gx65QJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.removemergecandidate" label="%command.label.2"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_i2FJYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.mergegroup" label="%command.label.3"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_WOzf0JcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.setMergeTarget" label="%command.label.0" command="_GAm9cJcNEeeM745tzuPNCQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_c0pycJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.setMergeCandidate" label="%command.label.1" command="_Kkf_YJcNEeeM745tzuPNCQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_gx65QJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.removemergecandidate" label="%command.label.2" command="_MNLNYJcNEeeM745tzuPNCQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_i2FJYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.mergegroup" label="%command.label.3" command="_N1zYEJcNEeeM745tzuPNCQ"/>
         <children xsi:type="menu:MenuSeparator" xmi:id="_lFRk0JcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menuseparator.2"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_l6dgYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.convertTeam2Person" label="%command.label.5"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_oKqBYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.convertPerson2Team" label="%command.label.6"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_l6dgYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.convertTeam2Person" label="%command.label.5" command="_PtZy4JcNEeeM745tzuPNCQ"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_oKqBYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.convertPerson2Team" label="%command.label.6" command="_RFEJYJcNEeeM745tzuPNCQ"/>
         <children xsi:type="menu:MenuSeparator" xmi:id="_p-7bYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menuseparator.3"/>
-        <children xsi:type="menu:Menu" xmi:id="_saDaAJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menu.chooseMarkerType" label="%menu.label.2">
-          <children xsi:type="menu:DynamicMenuContribution" xmi:id="_u0_LYJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.dynamicmenucontribution.markerType"/>
-        </children>
+        <children xsi:type="menu:Menu" xmi:id="_saDaAJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menu.chooseMarkerType" label="%menu.label.2"/>
         <children xsi:type="menu:MenuSeparator" xmi:id="_x3rgUJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.menuseparator.4"/>
-        <children xsi:type="menu:HandledMenuItem" xmi:id="_yt2TUJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.delete" label="%command.label.4"/>
+        <children xsi:type="menu:HandledMenuItem" xmi:id="_yt2TUJcMEeeM745tzuPNCQ" elementId="eu.etaxonomy.taxeditor.bulkeditor.handledmenuitem.delete" label="%command.label.4" command="_S8xR4JcNEeeM745tzuPNCQ"/>
       </menus>
     </elements>
   </fragments>
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/annotatedlineeditor/e4/handler/NewObjectHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/annotatedlineeditor/e4/handler/NewObjectHandlerE4.java
index 3c2d0b75f..94639d63a 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/annotatedlineeditor/e4/handler/NewObjectHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/annotatedlineeditor/e4/handler/NewObjectHandlerE4.java
@@ -1,91 +1,85 @@
 /**
-* 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.
-*/
+ * 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.annotatedlineeditor.e4.handler;
 
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.dialogs.IInputValidator;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.window.Window;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.handlers.HandlerUtil;
+import javax.inject.Named;
+
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
+import org.eclipse.e4.ui.services.IServiceConstants;
 
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
-import eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor;
-import eu.etaxonomy.taxeditor.bulkeditor.input.entitycreator.GroupCreator;
-import eu.etaxonomy.taxeditor.bulkeditor.input.entitycreator.UserCreator;
+import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
+import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorConstants;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 
 /**
- * <p>NewObjectHandler class.</p>
  *
- * @author p.ciardelli
- * @created 14.08.2009
- * @version 1.0
+ * @author pplitzner
+ * @date 12.09.2017
+ *
  */
-public class NewObjectHandlerE4 extends AbstractHandler {
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
-	 */
-	/** {@inheritDoc} */
-	@Override
-    public Object execute(ExecutionEvent event) throws ExecutionException {
+public class NewObjectHandlerE4 {
 
-		IEditorPart editor = HandlerUtil.getActiveEditor(event);
-		IEditorInput input = editor.getEditorInput();
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
+            MHandledMenuItem menuItem) {
 
-		if (editor instanceof AnnotatedLineEditor) {
+        Object key = menuItem.getTransientData().get(IBulkEditorConstants.DYNAMIC_OPEN_OBJECT_ID+".key");
 
-			Object key = ((Event)event.getTrigger()).data;
-			if (key != null) {
-				if(!(key instanceof SpecimenOrObservationType)) {
-					String text = ((Event)event.getTrigger()).text;
+        BulkEditorE4 bulkEditor = (BulkEditorE4) activePart.getObject();
 
-					//FIXME : This should probably go into some ValidatorFactory
-					IInputValidator nonEmptyInputValidator = null;
-					//FIXME : This is a workaround to not allow empty strings in the
-					//        input dialog for User and Group entities.
-					//        Normally this should be default
-					//        behaviour, so we need to discuss whether this handler
-					//        should be used to handle the creating new entities of
-					//        type other than User and Group.
-					//        Once #4348 is fixed this check can be removed.
-					if(text.equals(UserCreator.USER) || text.equals(GroupCreator.GROUP)) {
-						nonEmptyInputValidator = new IInputValidator() {
-							@Override
-                            public String isValid(String text) {
-								if(text == null || text.isEmpty()) {
-									return "Input cannot be empty";
-								}
-								return null;
-							}
-						};
-					}
-					InputDialog dialog = new InputDialog(HandlerUtil.getActiveShell(event),
-							String.format("Create %s", text), String.format("Enter new %s", text), "",
-							nonEmptyInputValidator);
 
-					if (dialog.open() != Window.CANCEL) {
-						((AnnotatedLineEditor) editor).createAnnotatedLineNewObject(key, dialog.getValue());
-					}
-				} else {
-					((AnnotatedLineEditor) editor).createAnnotatedLineNewObject(key, "Untitled");
-				}
+        if (key != null) {
+            IEntityCreator entityCreator = bulkEditor.getEditorInput().getEntityCreator();
+            String text = menuItem.getCommand().getCommandName();
+            Object createdEntity = entityCreator.createEntity(text);
+            bulkEditor.getEditorInput().getModel().add(createdEntity);
+            bulkEditor.refresh();
 
-			} else {
-				((AnnotatedLineEditor) editor).createAnnotatedLineNewObject();
-			}
-		}
-		return null;
-	}
+            //				if(!(key instanceof SpecimenOrObservationType)) {
+            //
+            //					//FIXME : This should probably go into some ValidatorFactory
+            //					IInputValidator nonEmptyInputValidator = null;
+            //					//FIXME : This is a workaround to not allow empty strings in the
+            //					//        input dialog for User and Group entities.
+            //					//        Normally this should be default
+            //					//        behaviour, so we need to discuss whether this handler
+            //					//        should be used to handle the creating new entities of
+            //					//        type other than User and Group.
+            //					//        Once #4348 is fixed this check can be removed.
+            //					if(text.equals(UserCreator.USER) || text.equals(GroupCreator.GROUP)) {
+            //						nonEmptyInputValidator = new IInputValidator() {
+            //							@Override
+            //                            public String isValid(String text) {
+            //								if(text == null || text.isEmpty()) {
+            //									return "Input cannot be empty";
+            //								}
+            //								return null;
+            //							}
+            //						};
+            //					}
+            //					InputDialog dialog = new InputDialog(shell,
+            //							String.format("Create %s", text), String.format("Enter new %s", text), "",
+            //							nonEmptyInputValidator);
+            //
+            //					if (dialog.open() != Window.CANCEL) {
+            //						((AnnotatedLineEditor) editor).createAnnotatedLineNewObject(key, dialog.getValue());
+            //					}
+            //				} else {
+            //					((AnnotatedLineEditor) editor).createAnnotatedLineNewObject(key, "Untitled");
+            //				}
+            //
+            //			} else {
+            //				((AnnotatedLineEditor) editor).createAnnotatedLineNewObject();
+            //			}
+        }
+    }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/AnnotatedTableItem.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/AnnotatedTableItem.java
new file mode 100644
index 000000000..d714c8fa9
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/AnnotatedTableItem.java
@@ -0,0 +1,54 @@
+// $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 eu.etaxonomy.cdm.model.common.ICdmBase;
+
+/**
+ * @author pplitzner
+ * @date 12.09.2017
+ *
+ */
+public class AnnotatedTableItem <T extends ICdmBase> {
+
+    private T element;
+    private boolean isMergeCandidate = false;
+    private boolean isMergeTarget = false;
+
+    public AnnotatedTableItem(T element) {
+        super();
+        this.element = element;
+    }
+
+    public T getElement() {
+        return element;
+    }
+
+    public void setMergeCandidate(boolean isMergeCandidate) {
+        this.isMergeCandidate = isMergeCandidate;
+    }
+
+    public void setMergeTarget(boolean isMergeTarget) {
+        this.isMergeTarget = isMergeTarget;
+    }
+
+    public boolean isMergeCandidate() {
+        return isMergeCandidate;
+    }
+
+    public boolean isMergeTarget() {
+        return isMergeTarget;
+    }
+
+    @Override
+    public String toString() {
+        return element.toString();
+    }
+}
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 da1bc60a5..32e781d21 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,6 +9,9 @@
 
 package eu.etaxonomy.taxeditor.bulkeditor.e4;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
@@ -19,7 +22,6 @@ import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.ArrayContentProvider;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.LabelProvider;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.FillLayout;
@@ -108,7 +110,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 		bottomComposite.setLayout(new FillLayout());
 		viewer = new TableViewer(bottomComposite);
 		viewer.setContentProvider(new ArrayContentProvider());
-		viewer.setLabelProvider(new LabelProvider());
+		viewer.setLabelProvider(new BulkEditorLabelProvider());
 
 
         //propagate selection
@@ -146,12 +148,12 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 
             getEditorInput().performSearch(query);
 
+            viewer.setInput(getEditorInput().getWrappedModel());
             refresh();
         }
     }
 
     public void refresh() {
-        viewer.setInput(getEditorInput().getModel());
         viewer.refresh();
     }
 
@@ -163,6 +165,32 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
         return input;
     }
 
+    public List<AnnotatedTableItem> getMergeCandidates(){
+        List<AnnotatedTableItem> mergeCandidates = new ArrayList<>();
+        for(AnnotatedTableItem item: (List<AnnotatedTableItem>)viewer.getInput()){
+            if(item.isMergeCandidate()){
+                mergeCandidates.add(item);
+            }
+        }
+        return mergeCandidates;
+    }
+
+    public AnnotatedTableItem getMergeTarget(){
+        for(AnnotatedTableItem item: (List<AnnotatedTableItem>)viewer.getInput()){
+            if(item.isMergeTarget()){
+                return item;
+            }
+        }
+        return null;
+    }
+
+    public void removeAllAnnotations(){
+        for(AnnotatedTableItem item: (List<AnnotatedTableItem>)viewer.getInput()){
+            item.setMergeCandidate(false);
+            item.setMergeTarget(false);
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
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
new file mode 100644
index 000000000..2d47fd1c7
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/BulkEditorLabelProvider.java
@@ -0,0 +1,62 @@
+// $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.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
+import eu.etaxonomy.taxeditor.model.ImageResources;
+
+/**
+ * @author pplitzner
+ * @date 11.09.2017
+ *
+ */
+public class BulkEditorLabelProvider extends LabelProvider {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Image getImage(Object element) {
+        AnnotatedTableItem item = (AnnotatedTableItem)element;
+        try {
+            if(item.isMergeCandidate()){
+                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(item.isMergeTarget()){
+                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 getText(Object element) {
+        return super.getText(element);
+    }
+
+}
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/command/DynamicNewObjectMenuE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/command/DynamicNewObjectMenuE4.java
new file mode 100644
index 000000000..83a309eef
--- /dev/null
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/command/DynamicNewObjectMenuE4.java
@@ -0,0 +1,95 @@
+/**
+* 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.command;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Named;
+
+import org.eclipse.e4.ui.di.AboutToShow;
+import org.eclipse.e4.ui.model.application.commands.MCommand;
+import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
+import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
+import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.ui.IEditorInput;
+
+import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
+import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorConstants;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
+import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
+
+/**
+ *
+ * @author pplitzner
+ * @date 12.09.2017
+ *
+ */
+public class DynamicNewObjectMenuE4 {
+
+	private Map<? extends Object, String> classLabelPairs;
+    private BulkEditorE4 editor;
+
+	  /** {@inheritDoc} */
+    @AboutToShow
+    public void aboutToShow(@Named(IServiceConstants.ACTIVE_PART)MPart activePart,
+            List<MMenuElement> items) {
+
+        editor = (BulkEditorE4) activePart.getObject();
+
+		classLabelPairs = getClassLabelPairs();
+
+		MMenu menu = MMenuFactory.INSTANCE.createMenu();
+        menu.setLabel("New");
+        items.add(menu);
+
+        for(final Object key : classLabelPairs.keySet()){
+            createMenuItem(menu, key);
+        }
+	}
+
+	private void createMenuItem(MMenu menu, final Object key){
+	    MHandledMenuItem menuItem = MMenuFactory.INSTANCE.createHandledMenuItem();
+        menuItem.setLabel(classLabelPairs.get(key));
+        MCommand mCommand = MCommandsFactory.INSTANCE.createCommand();
+        mCommand.setElementId(IBulkEditorConstants.DYNAMIC_OPEN_OBJECT_ID);
+        mCommand.setCommandName(classLabelPairs.get(key));
+        //set params
+        menuItem.getTransientData().put(IBulkEditorConstants.DYNAMIC_OPEN_OBJECT_ID+".key", key);
+
+        menuItem.setCommand(mCommand);
+        menu.getChildren().add(menuItem);
+
+	}
+
+	/**
+	 * Get class label pairs from Annotated Line Editor's entity creator.
+	 * @return
+	 */
+	private Map<? extends Object, String> getClassLabelPairs() {
+		if (editor != null){
+			IEditorInput input = editor.getEditorInput();
+
+			if(input instanceof AbstractBulkEditorInput){
+				IEntityCreator<?> entityCreator = ((AbstractBulkEditorInput) input).getEntityCreator();
+				if(entityCreator!=null){
+				    return entityCreator.getKeyLabelPairs();
+				}
+			}
+		}
+
+		return Collections.EMPTY_MAP;
+	}
+}
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertPerson2TeamHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertPerson2TeamHandlerE4.java
index d6e7ba716..328d7057c 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertPerson2TeamHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertPerson2TeamHandlerE4.java
@@ -10,8 +10,10 @@ package eu.etaxonomy.taxeditor.bulkeditor.e4.handler;
 
 import javax.inject.Named;
 
+import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
 import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 
@@ -20,6 +22,7 @@ import eu.etaxonomy.cdm.api.service.UpdateResult;
 import eu.etaxonomy.cdm.model.agent.Person;
 import eu.etaxonomy.cdm.model.agent.Team;
 import eu.etaxonomy.cdm.strategy.merge.MergeException;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
 import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
@@ -34,7 +37,7 @@ public class ConvertPerson2TeamHandlerE4 {
 
 
     @Execute
-    public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)Person person,
+    public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem item,
             @Named(IServiceConstants.ACTIVE_PART)MPart activePart) {
 
         BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
@@ -52,7 +55,7 @@ public class ConvertPerson2TeamHandlerE4 {
         Team team =null;
         UpdateResult result = null;
         try {
-            result = CdmStore.getService(IAgentService.class).convertPerson2Team(person.getUuid());
+            result = CdmStore.getService(IAgentService.class).convertPerson2Team(item.getElement().getUuid());
         } catch (IllegalArgumentException e) {
             MessagingUtils.errorDialog("Can not convert Person into a Team", null, e.getLocalizedMessage(), TaxeditorBulkeditorPlugin.PLUGIN_ID,e, true);
         } catch (MergeException e) {
@@ -66,4 +69,14 @@ public class ConvertPerson2TeamHandlerE4 {
         }
     }
 
+    @CanExecute
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem selection,
+            @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
+            MHandledMenuItem menuItem){
+        boolean canExecute = false;
+        canExecute = ((BulkEditorE4)activePart.getObject()).getEditorInput().isConvertingEnabled() && selection.getElement() instanceof Person;
+        menuItem.setVisible(canExecute);
+        return canExecute;
+    }
+
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertTeam2PersonHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertTeam2PersonHandlerE4.java
index 0455cdfd7..bd54325bb 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertTeam2PersonHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/ConvertTeam2PersonHandlerE4.java
@@ -22,6 +22,7 @@ import eu.etaxonomy.cdm.api.service.UpdateResult;
 import eu.etaxonomy.cdm.model.agent.Person;
 import eu.etaxonomy.cdm.model.agent.Team;
 import eu.etaxonomy.cdm.strategy.merge.MergeException;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
 import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
 import eu.etaxonomy.taxeditor.store.CdmStore;
@@ -34,7 +35,7 @@ import eu.etaxonomy.taxeditor.store.CdmStore;
 public class ConvertTeam2PersonHandlerE4 {
 
     @Execute
-	public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)Team team,
+	public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem item,
 	        @Named(IServiceConstants.ACTIVE_PART)MPart activePart) {
 
         BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
@@ -53,7 +54,7 @@ public class ConvertTeam2PersonHandlerE4 {
 		UpdateResult result = null;
 
 		try {
-		    result = CdmStore.getService(IAgentService.class).convertTeam2Person(team.getUuid());
+		    result = CdmStore.getService(IAgentService.class).convertTeam2Person(item.getElement().getUuid());
 		} catch (IllegalArgumentException e) {
 		    MessagingUtils.informationDialog("Can not convert Team to Person", e.getMessage());
 		} catch (MergeException e) {
@@ -68,11 +69,11 @@ public class ConvertTeam2PersonHandlerE4 {
     }
 
     @CanExecute
-    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION)Object selection,
+    public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem selection,
             @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
             MHandledMenuItem menuItem){
         boolean canExecute = false;
-        canExecute = ((BulkEditorE4)activePart.getObject()).getEditorInput().isConvertingEnabled() && selection instanceof Team;
+        canExecute = ((BulkEditorE4)activePart.getObject()).getEditorInput().isConvertingEnabled() && selection.getElement() instanceof Team;
         menuItem.setVisible(canExecute);
         return canExecute;
     }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/DeleteHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/DeleteHandlerE4.java
index d307e7f6e..0f222981d 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/DeleteHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/DeleteHandlerE4.java
@@ -18,7 +18,6 @@ import javax.inject.Named;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.e4.core.di.annotations.CanExecute;
 import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
 import org.eclipse.e4.ui.services.IServiceConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -82,7 +81,6 @@ public class DeleteHandlerE4 {
 
     @Execute
     public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)Object object,
-            @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
             @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
 
         DeleteConfiguratorBase config = null;
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/MergeGroupHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/MergeGroupHandlerE4.java
index 08efd9650..10aeb78a6 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/MergeGroupHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/MergeGroupHandlerE4.java
@@ -1,21 +1,32 @@
 /**
-* 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.
-*/
+ * 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.handler;
 
+import java.util.List;
+
 import javax.inject.Named;
 
 import org.apache.log4j.Logger;
 import org.eclipse.e4.core.di.annotations.Execute;
 import org.eclipse.e4.ui.model.application.ui.basic.MPart;
 import org.eclipse.e4.ui.services.IServiceConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.widgets.Shell;
 
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
+import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.strategy.merge.MergeException;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+
 /**
  *
  * @author pplitzner
@@ -23,84 +34,78 @@ import org.eclipse.swt.widgets.Shell;
  *
  */
 public class MergeGroupHandlerE4 {
-	private static final Logger logger = Logger
-			.getLogger(MergeGroupHandlerE4.class);
+    private static final Logger logger = Logger
+            .getLogger(MergeGroupHandlerE4.class);
 
     @Execute
     public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)Object object,
             @Named(IServiceConstants.ACTIVE_PART)MPart activePart,
             @Named(IServiceConstants.ACTIVE_SHELL)Shell shell) {
 
-        //FIXME E4 migrate merge handler
-//        BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
-//
-//			IDocumentProvider provider = ((BulkEditor) editor).getDocumentProvider();
-//			LineAnnotationModel model =
-//					(LineAnnotationModel) provider.getAnnotationModel(input);
-//
-//			// Check whether there are any group annotations
-//			Set<LineAnnotation> candidateAnnotations = model.getAllAnnotationsOfType(IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
-//			if (candidateAnnotations.size() == 0) {
-//				MessageDialog.openWarning(HandlerUtil.getActiveShell(event),
-//						"No merge candidates", "No objects have been chosen for merging.");
-//				return null;
-//			}
-//
-//			// Check whether group merge target has been set
-//			Annotation targetAnnotation = model.getFirstAnnotationOfType(IBulkEditorConstants.TYPE_MERGE_TARGET);
-//			if (targetAnnotation == null) {
-//				MessageDialog.openWarning(HandlerUtil.getActiveShell(event),
-//						"No group merge target set", "No group merge target has been set.");
-//				return null;
-//			}
-//			Object targetEntity = ((IEntityContainer<?>) targetAnnotation).getEntity();
-//
-//			TeamOrPersonBase teamOrPerson = null;
-//			Reference ref = null;
-//			if (targetEntity instanceof TeamOrPersonBase){
-//				teamOrPerson = HibernateProxyHelper.deproxy(targetEntity, TeamOrPersonBase.class);
-//			} else if(targetEntity instanceof Reference){
-//				ref = HibernateProxyHelper.deproxy(targetEntity, Reference.class);
-//			}
-//			logger.info("Merging group");
-////			model.printAnnotations();
-//			for (LineAnnotation annotation : candidateAnnotations) {
-//				//first check whether entities are mergeable
-//
-//
-//			try{
-//				if (ref != null){
-//					Reference ref2 = HibernateProxyHelper.deproxy(annotation.getEntity(), Reference.class);
-//
-//					if (!CdmStore.getCommonService().isMergeable(ref, ref2, null)){
-//						MessageDialog.openWarning(HandlerUtil.getActiveShell(event),
-//								"No merge possible", "A merge of " + ref.getTitleCache() + " and " + ref2.getTitleCache() + " is not possible.");
-//						return null;
-//					}
-//				}
-//				if (teamOrPerson != null){
-//					TeamOrPersonBase teamOrPerson2 = HibernateProxyHelper.deproxy(annotation.getEntity(), TeamOrPersonBase.class);
-//
-//					if (!CdmStore.getCommonService().isMergeable(teamOrPerson, teamOrPerson2, null)){
-//						MessageDialog.openWarning(HandlerUtil.getActiveShell(event),
-//								"No merge possible", "A merge of " + teamOrPerson.getTitleCache() + " and " + teamOrPerson2.getTitleCache() + " is not possible.");
-//						return null;
-//					}
-//				}
-//			}catch(MergeException e){
-//
-//			}
-//				((BulkEditor) editor).removeAnnotatedLine(annotation);
-//
-//				// Mark entity container for merging with target entity
-//				((IEntityContainer) annotation).markAsMerged(targetEntity);
-//				logger.info("Merging " + annotation + " with " + targetAnnotation);
-//
-//				// Remove annotation from model
-//				model.removeAnnotation(annotation);
-//			}
-//
-//			model.removeTypeFromAllAnnotations(IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
-//			model.removeTypeFromAllAnnotations(IBulkEditorConstants.TYPE_MERGE_TARGET);
-	}
+        BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
+
+        // Check whether there are any group annotations
+        List<AnnotatedTableItem> mergeCandidates = editor.getMergeCandidates();
+        if (mergeCandidates.size() == 0) {
+            MessageDialog.openWarning(shell,
+                    "No merge candidates", "No objects have been chosen for merging.");
+            return;
+        }
+
+        // Check whether group merge target has been set
+        AnnotatedTableItem mergeTarget = editor.getMergeTarget();
+        if (mergeTarget == null) {
+            MessageDialog.openWarning(shell,
+                    "No group merge target set", "No group merge target has been set.");
+            return;
+        }
+        Object targetEntity = mergeTarget.getElement();
+
+        TeamOrPersonBase teamOrPerson = null;
+        Reference ref = null;
+        if (targetEntity instanceof TeamOrPersonBase){
+            teamOrPerson = HibernateProxyHelper.deproxy(targetEntity, TeamOrPersonBase.class);
+        } else if(targetEntity instanceof Reference){
+            ref = HibernateProxyHelper.deproxy(targetEntity, Reference.class);
+        }
+        for (AnnotatedTableItem item : mergeCandidates) {
+            //first check whether entities are mergeable
+            try{
+                if (ref != null){
+                    Reference ref2 = HibernateProxyHelper.deproxy(item.getElement(), Reference.class);
+
+                    if (!CdmStore.getCommonService().isMergeable(ref, ref2, null)){
+                        MessageDialog.openWarning(shell,
+                                "No merge possible", "A merge of " + ref.getTitleCache() + " and " + ref2.getTitleCache() + " is not possible.");
+                        return;
+                    }
+                }
+                if (teamOrPerson != null){
+                    TeamOrPersonBase teamOrPerson2 = HibernateProxyHelper.deproxy(item.getElement(), TeamOrPersonBase.class);
+
+                    if (!CdmStore.getCommonService().isMergeable(teamOrPerson, teamOrPerson2, null)){
+                        MessageDialog.openWarning(shell,
+                                "No merge possible", "A merge of " + teamOrPerson.getTitleCache() + " and " + teamOrPerson2.getTitleCache() + " is not possible.");
+                        return;
+                    }
+                }
+            }catch(MergeException e){
+
+            }
+            editor.removeAllAnnotations();
+            editor.refresh();
+            //				((BulkEditor) editor).removeAnnotatedLine(item);
+            //
+            //				// Mark entity container for merging with target entity
+            //				((IEntityContainer) item).markAsMerged(targetEntity);
+            //				logger.info("Merging " + item + " with " + targetAnnotation);
+            //
+            //				// Remove annotation from model
+            //				model.removeAnnotation(item);
+            //			}
+            //
+            //			model.removeTypeFromAllAnnotations(IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
+            //			model.removeTypeFromAllAnnotations(IBulkEditorConstants.TYPE_MERGE_TARGET);
+        }
+    }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/RemoveMergeCandidateHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/RemoveMergeCandidateHandlerE4.java
index 3c93be9b4..453bf7e1f 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/RemoveMergeCandidateHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/RemoveMergeCandidateHandlerE4.java
@@ -1,57 +1,36 @@
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* 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.handler;
 
-import java.util.Iterator;
+import javax.inject.Named;
 
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
 
-import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation;
-import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotationModel;
-import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 
 /**
- * <p>RemoveMergeCandidateHandler class.</p>
  *
- * @author p.ciardelli
- * @created 25.06.2009
- * @version 1.0
+ * @author pplitzner
+ * @date 12.09.2017
+ *
  */
-public class RemoveMergeCandidateHandlerE4 extends AbstractHandler {
+public class RemoveMergeCandidateHandlerE4  {
+
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
-	 */
-	/** {@inheritDoc} */
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-				
-		if (HandlerUtil.getCurrentSelection(event) instanceof TextSelection 
-				&& HandlerUtil.getActiveEditor(event) instanceof BulkEditor) {
-			TextSelection selection = (TextSelection) HandlerUtil.getCurrentSelection(event);
-			BulkEditor editor = (BulkEditor) HandlerUtil.getActiveEditor(event);
-			
-			LineAnnotationModel model = (LineAnnotationModel) editor.getDocumentProvider().getAnnotationModel(editor.getEditorInput());
-			if (model != null) {
-				Iterator iter = model.getAnnotationIterator(selection.getOffset(), selection.getLength(), true, true);
-				while (iter.hasNext()) {
-					Object next = iter.next();
-					if (next instanceof LineAnnotation) {
-						model.changeAnnotationType(
-								(LineAnnotation) next, LineAnnotation.TYPE_GENERIC);
-					}
-				}
-			}
-		}	
-		return null;
-	}
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem item,
+            @Named(IServiceConstants.ACTIVE_PART)MPart activePart) {
+        BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
+        item.setMergeCandidate(false);
+        editor.refresh();
+    }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeCandidateHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeCandidateHandlerE4.java
index 15fb94e51..edc7bcf00 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeCandidateHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeCandidateHandlerE4.java
@@ -1,59 +1,35 @@
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* 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.handler;
 
-import java.util.Iterator;
+import javax.inject.Named;
 
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
 
-import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotation;
-import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotationModel;
-import eu.etaxonomy.taxeditor.bulkeditor.BulkEditor;
-import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorConstants;
-import eu.etaxonomy.taxeditor.model.LineSelection;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 
 /**
- * <p>SetMergeCandidateHandler class.</p>
  *
- * @author p.ciardelli
- * @created 25.06.2009
- * @version 1.0
+ * @author pplitzner
+ * @date 12.09.2017
+ *
  */
-public class SetMergeCandidateHandlerE4 extends AbstractHandler {
+public class SetMergeCandidateHandlerE4 {
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
-	 */
-	/** {@inheritDoc} */
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-				
-		if (HandlerUtil.getCurrentSelection(event) instanceof TextSelection 
-				&& HandlerUtil.getActiveEditor(event) instanceof BulkEditor) {
-			TextSelection selection = (TextSelection) HandlerUtil.getCurrentSelection(event);
-			BulkEditor editor = (BulkEditor) HandlerUtil.getActiveEditor(event);
-			
-			LineAnnotationModel model = (LineAnnotationModel) editor.getDocumentProvider().getAnnotationModel(editor.getEditorInput());
-			if (model != null) {
-				Iterator iter = model.getAnnotationIterator(selection.getOffset(), selection.getLength(), true, true);
-				while (iter.hasNext()) {
-					Object next = iter.next();
-					if (next instanceof LineAnnotation) {
-						model.changeAnnotationType(
-								(LineAnnotation) next, IBulkEditorConstants.TYPE_MERGE_CANDIDATE);
-					}
-				}
-			}
-		}	
-		return null;
-	}
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem item,
+            @Named(IServiceConstants.ACTIVE_PART)MPart activePart) {
+        BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
+        item.setMergeCandidate(true);
+        editor.refresh();
+    }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeTargetHandlerE4.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeTargetHandlerE4.java
index c2c6b2eb3..77da3fa91 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeTargetHandlerE4.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/e4/handler/SetMergeTargetHandlerE4.java
@@ -1,73 +1,35 @@
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* 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.handler;
 
-import org.eclipse.core.commands.AbstractHandler;
-import org.eclipse.core.commands.ExecutionEvent;
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.TextSelection;
-import org.eclipse.jface.text.source.Annotation;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.handlers.HandlerUtil;
-import org.eclipse.ui.texteditor.IDocumentProvider;
+import javax.inject.Named;
 
-import eu.etaxonomy.taxeditor.annotatedlineeditor.AnnotatedLineEditor;
-import eu.etaxonomy.taxeditor.annotatedlineeditor.LineAnnotationModel;
-import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorConstants;
-import eu.etaxonomy.taxeditor.bulkeditor.input.AbstractBulkEditorInput;
+import org.eclipse.e4.core.di.annotations.Execute;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.services.IServiceConstants;
+
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.BulkEditorE4;
 
 /**
- * <p>SetMergeTargetHandler class.</p>
  *
- * @author p.ciardelli
- * @created 25.06.2009
- * @version 1.0
+ * @author pplitzner
+ * @date 12.09.2017
+ *
  */
-public class SetMergeTargetHandlerE4 extends AbstractHandler {
+public class SetMergeTargetHandlerE4 {
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.core.commands.AbstractHandler#execute(org.eclipse.core.commands.ExecutionEvent)
-	 */
-	/** {@inheritDoc} */
-	public Object execute(ExecutionEvent event) throws ExecutionException {
-				
-		IEditorPart editor = HandlerUtil.getActiveEditor(event);
-		IEditorInput input = editor.getEditorInput();
-		
-		if (editor instanceof AnnotatedLineEditor && input instanceof AbstractBulkEditorInput) {
-			
-			IDocumentProvider provider = ((AnnotatedLineEditor) editor).getDocumentProvider();
-			LineAnnotationModel model = 
-					(LineAnnotationModel) provider.getAnnotationModel(input);
-			IDocument document = provider.getDocument(input);
-			
-			ISelection selection = HandlerUtil.getCurrentSelection(event);
-			if (selection instanceof TextSelection) {
-				Annotation annotation = null;
-				
-				// Get annotation in current line
-				int line = ((TextSelection) selection).getStartLine();
-				annotation = model.getAnnotationAtLine(line, document);
-				
-				// Remove existing merge target
-				model.removeTypeFromAllAnnotations(IBulkEditorConstants.TYPE_MERGE_TARGET);
-				
-				// Set annotation in current line to merge target
-				if (annotation != null) {
-					model.changeAnnotationType(
-							annotation, IBulkEditorConstants.TYPE_MERGE_TARGET);
-				}
-			}
-		}		
-		return null;
+    @Execute
+    public void execute(@Named(IServiceConstants.ACTIVE_SELECTION)AnnotatedTableItem item,
+            @Named(IServiceConstants.ACTIVE_PART)MPart activePart) {
+        BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
+        item.setMergeTarget(true);
+        editor.refresh();
 	}
 }
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 c87a2a01e..5813dcdd7 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
@@ -32,6 +32,7 @@ import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator;
 import eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityPersistenceService;
 import eu.etaxonomy.taxeditor.bulkeditor.BulkEditorQuery;
 import eu.etaxonomy.taxeditor.bulkeditor.IBulkEditorSortProvider;
+import eu.etaxonomy.taxeditor.bulkeditor.e4.AnnotatedTableItem;
 import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.CdmBaseSortProvider;
 import eu.etaxonomy.taxeditor.bulkeditor.input.sortprovider.TitleCacheComparator;
 import eu.etaxonomy.taxeditor.bulkeditor.internal.TaxeditorBulkeditorPlugin;
@@ -222,6 +223,14 @@ public abstract class AbstractBulkEditorInput<T extends ICdmBase> extends CdmEnt
 		return model;
 	}
 
+	public List<AnnotatedTableItem<T>> getWrappedModel() {
+	    List<AnnotatedTableItem<T>> wrappetItems = new ArrayList<>();
+	    for(T t:model){
+	        wrappetItems.add(new AnnotatedTableItem<T>(t));
+	    }
+	    return wrappetItems;
+	}
+
 	protected boolean replaceInModel(T entity) {
 	    int index = model.indexOf(entity);
 	    if(index >= 0) {
