commit c0fb722d0d6ef9471e8a2c8e182532dffd7b037f
Author: Katja Luther <k.luther@bgbm.org>
Date:   Thu Mar 22 11:04:07 2018 +0100

    improve deduplication handling and saving in bulkeditor

diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/command/BulkEditorMenuPropertyTester.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/command/BulkEditorMenuPropertyTester.java
index f8e4aaeaf..abfd07293 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/command/BulkEditorMenuPropertyTester.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/command/BulkEditorMenuPropertyTester.java
@@ -24,7 +24,8 @@ public class BulkEditorMenuPropertyTester extends PropertyTester {
 
 	private static final String IS_TEAM = "isTeam";
 	private static final String IS_PERSON = "isPerson";
-	
+	private static final String IS_TEAM_OR_PERSON = "isTeamOrPerson";
+
 	public BulkEditorMenuPropertyTester(){
 	}
 	/**
@@ -36,14 +37,17 @@ public class BulkEditorMenuPropertyTester extends PropertyTester {
 		if(receiver instanceof IStructuredSelection){
 			IStructuredSelection selection = (IStructuredSelection) receiver;
 			Object selectedElement = selection.getFirstElement();
+			if (property.equals(IS_TEAM_OR_PERSON) && (selectedElement instanceof Team || selectedElement instanceof Person)){
+                return true;
+            }
 			if (property.equals(IS_PERSON) && selectedElement instanceof Person){
 				return true;
-			} 
+			}
 			if (property.equals(IS_TEAM) && selectedElement instanceof Team){
 				return true;
 			}
 			return false;
-		
+
 		}
 		return false;
 	}
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 39825ea0b..60838b9eb 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
@@ -67,7 +67,6 @@ import eu.etaxonomy.taxeditor.model.IPartContentHasFactualData;
 import eu.etaxonomy.taxeditor.model.IPartContentHasMedia;
 import eu.etaxonomy.taxeditor.model.IPartContentHasSupplementalData;
 import eu.etaxonomy.taxeditor.operation.IPostOperationEnabled;
-import eu.etaxonomy.taxeditor.store.CdmStore;
 import eu.etaxonomy.taxeditor.workbench.part.IE4SavablePart;
 
 /**
@@ -260,9 +259,7 @@ public class BulkEditorE4 implements IPartContentHasDetails, IConversationEnable
 
 	    List<CdmBase> saveCandidates = getEditorInput().getSaveCandidates();
 
-	    if (!saveCandidates.isEmpty()){
-	        CdmStore.getService(saveCandidates.get(0)).merge(saveCandidates, true);
-	    }
+
         dirty.setDirty(false);
         getEditorInput().resetSaveCandidates();
         getEditorInput().dispose();
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 ec655a611..ec025e6cb 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
@@ -8,6 +8,7 @@
  */
 package eu.etaxonomy.taxeditor.bulkeditor.e4.handler;
 
+import java.util.HashSet;
 import java.util.Set;
 
 import javax.inject.Named;
@@ -48,6 +49,7 @@ public class MergeGroupHandlerE4 {
 
         BulkEditorE4 editor = (BulkEditorE4) activePart.getObject();
         AbstractBulkEditorInput input = editor.getEditorInput();
+        Set<CdmBase> mergedCandidates = new HashSet<>();
 
         if(editor.isDirty()){
             boolean proceed = MessageDialog.openQuestion(null,
@@ -63,8 +65,8 @@ public class MergeGroupHandlerE4 {
         }
 
         // Check whether there are any group annotations
-        Set<CdmBase> mergeCandidates = input.getMergeCandidates();
-        if (mergeCandidates.size() == 0) {
+        Set<CdmBase> candidatesToMerge = input.getMergeCandidates();
+        if (candidatesToMerge.size() == 0) {
             MessageDialog.openWarning(shell,
                     "No merge candidates", "No objects have been chosen for merging.");
             return;
@@ -85,7 +87,7 @@ public class MergeGroupHandlerE4 {
         } else if(mergeTarget instanceof Reference){
             ref = HibernateProxyHelper.deproxy(mergeTarget, Reference.class);
         }
-        for (CdmBase item : mergeCandidates) {
+        for (CdmBase item : candidatesToMerge) {
             //first check whether entities are mergeable
             try{
                 if (ref != null){
@@ -97,6 +99,8 @@ public class MergeGroupHandlerE4 {
                         return;
                     }
                     input.getModel().remove(item);
+                    mergedCandidates.add(item);
+
                 }
                 if (teamOrPerson != null){
                     TeamOrPersonBase<?> teamOrPerson2 = HibernateProxyHelper.deproxy(item, TeamOrPersonBase.class);
@@ -107,12 +111,21 @@ public class MergeGroupHandlerE4 {
                         return;
                     }
                     input.getModel().remove(item);
+                    mergedCandidates.add(item);
                 }
             }catch(MergeException e){
-
+                candidatesToMerge.clear();
+                MessageDialog.openWarning(shell,
+                        "No merge possible", "A merge is not possible." + e.getLocalizedMessage());
+                return;
             }
         }
-
+        if (!candidatesToMerge.isEmpty()){
+            input.getMergedEntities().put(mergeTarget, mergedCandidates);
+//            mergeCandidates.clear();
+            input.getMergeCandidates().clear();
+            input.setMergeTarget(null);
+        }
         editor.setDirty();
         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 bb383be7f..a26da3ad3 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
@@ -57,8 +57,10 @@ public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEnti
 	private List<T> saveCandidates = new ArrayList<>();
 
 
-	private Set<T> mergeCandidates = new HashSet<>();
-	private T mergeTarget = null;
+	private Set<T> markedMergeCandidates = new HashSet<>();
+	private T markedMergeTarget = null;
+
+	private HashMap<T, Set<T>> mergedEntities = new HashMap<>();
 
 	private IEntityCreator<T> entityCreator;
 	private final ConversationHolder conversation;
@@ -91,27 +93,27 @@ public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEnti
 	protected abstract T loadEntity(UUID entityUuid);
 
 	public void setMergeTarget(T t){
-	    mergeTarget = t;
+	    markedMergeTarget = t;
 	}
 
     public Set<T> getMergeCandidates() {
-        return mergeCandidates;
+        return markedMergeCandidates;
     }
 
     public T getMergeTarget() {
-        return mergeTarget;
+        return markedMergeTarget;
     }
 
 	public void removeMergeTarget(){
-	    mergeTarget = null;
+	    markedMergeTarget = null;
 	}
 
 	public void addMergeCandidate(T t){
-	    mergeCandidates.add(t);
+	    markedMergeCandidates.add(t);
 	}
 
 	public void removeMergeCandidate(T t){
-		mergeCandidates.remove(t);
+		markedMergeCandidates.remove(t);
 	}
 
     public void addToDelete(T t, DeleteConfiguratorBase config) {
@@ -198,13 +200,18 @@ public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEnti
             }
 	    }
 	    toDelete.clear();
+	    if (!saveCandidates.isEmpty()){
+            CdmStore.getService(saveCandidates.get(0)).merge(saveCandidates, true);
+        }
 	    if(resetMerge){
 	        //merge entities
-	        for(T mergeCandidate:mergeCandidates){
-	            merge(mergeCandidate, mergeTarget);
+	        for(T mergeTarget:mergedEntities.keySet()){
+	            for (T mergeCandidate: mergedEntities.get(mergeTarget)){
+	                merge(mergeCandidate, mergeTarget);
+	            }
 	        }
-	        mergeCandidates.clear();
-	        mergeTarget = null;
+	        mergedEntities.clear();
+
 	    }
 	}
 
@@ -299,4 +306,12 @@ public abstract class AbstractBulkEditorInput<T extends CdmBase> extends CdmEnti
        this.saveCandidates.clear();
 
     }
+
+    public HashMap<T, Set<T>> getMergedEntities() {
+        return mergedEntities;
+    }
+
+    public void setMergedEntities(HashMap<T, Set<T>> mergedEntities) {
+        this.mergedEntities = mergedEntities;
+    }
 }
diff --git a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java
index 1c5f14056..7bdcf41cd 100644
--- a/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java
+++ b/eu.etaxonomy.taxeditor.bulkeditor/src/main/java/eu/etaxonomy/taxeditor/bulkeditor/input/AgentEditorInput.java
@@ -105,6 +105,7 @@ public class AgentEditorInput extends AbstractBulkEditorInput<TeamOrPersonBase>
 	/** {@inheritDoc} */
 	@Override
 	public List<TeamOrPersonBase> listEntities(IIdentifiableEntityServiceConfigurator configurator) {
+
 		return CdmStore.getSearchManager().findTeamOrPersons(configurator);
 	}
 
