commit 2d981b4e3a6de768cde6f729655ad94fb0aa7644
Author: Andreas Kohlbecker <a.kohlbecker@bgbm.org>
Date:   Fri Mar 24 15:20:42 2017 +0100

    ref #6169 RegistrationWorkingSets more complete, validation problems accessible via UI

diff --git a/src/main/java/eu/etaxonomy/cdm/mock/Registration.java b/src/main/java/eu/etaxonomy/cdm/mock/Registration.java
index 3ebfa4ae..2f827d3f 100644
--- a/src/main/java/eu/etaxonomy/cdm/mock/Registration.java
+++ b/src/main/java/eu/etaxonomy/cdm/mock/Registration.java
@@ -56,7 +56,8 @@ public class Registration extends CdmBase {
     public Registration() {
         super();
         status = RegistrationStatus.values()[(int) (Math.random() * RegistrationStatus.values().length)];
-        specificIdentifier = Integer.toString(idAutoincrement++);
+        setId(idAutoincrement++);
+        specificIdentifier = Integer.toString(getId());
         identifier = "http://pyhcobank.org/" + specificIdentifier;
         registrationDate = DateTime.now();
     }
diff --git a/src/main/java/eu/etaxonomy/cdm/mock/RegistrationService.java b/src/main/java/eu/etaxonomy/cdm/mock/RegistrationService.java
index 28ee6fa2..dcf23eb5 100644
--- a/src/main/java/eu/etaxonomy/cdm/mock/RegistrationService.java
+++ b/src/main/java/eu/etaxonomy/cdm/mock/RegistrationService.java
@@ -8,15 +8,14 @@
 */
 package eu.etaxonomy.cdm.mock;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 
-import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Service;
@@ -27,6 +26,7 @@ import eu.etaxonomy.cdm.api.application.CdmRepository;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
+import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationDTO;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationValidationException;
 
@@ -49,9 +49,10 @@ public class RegistrationService {
     private CdmRepository repo;
 
     private Map<UUID, Registration> registrationsByUUID = new HashMap<>();
-    private Map<String, Registration> registrationsByRegID = new HashMap<>();
-    private Map<String, RegistrationDTO> registrationDTOsByRegID = new HashMap<>();
-    private Map<Integer, Set<RegistrationDTO>> registrationDTOsByCitationID = new HashMap<>();
+    private Map<Integer, Registration> registrationsByRegID = new HashMap<>();
+    private Map<Integer, RegistrationDTO> registrationDTOsById = new HashMap<>();
+    private Map<String, RegistrationDTO> registrationDTOsByIdentifier = new HashMap<>();
+    private Map<Integer, List<RegistrationDTO>> registrationDTOsByCitationId = new HashMap<>();
 
     private Collection<CdmBase> cdmEntities = new HashSet<>();
 
@@ -75,23 +76,13 @@ public class RegistrationService {
                             Registration nameReg = new Registration();
                             nameReg.setName(name);
                             cdmEntities.add(name);
-                            try {
-                                put(nameReg, new RegistrationDTO(nameReg));
-                            } catch (RegistrationValidationException e) {
-                                //FIXME throw  and handle Exception
-                                Logger.getLogger(this.getClass()).error(e);
-                            }
+                            put(new RegistrationDTO(nameReg));
 
                             // typedesignation
                             Registration typedesignationReg = new Registration();
                             typedesignationReg.addTypeDesignations(name.getTypeDesignations());
                             cdmEntities.addAll(name.getTypeDesignations());
-                            try {
-                                put(typedesignationReg,  new RegistrationDTO(typedesignationReg));
-                            } catch (RegistrationValidationException e) {
-                                //FIXME throw  and handle Exception
-                                Logger.getLogger(this.getClass()).error(e);
-                            }
+                            put(new RegistrationDTO(typedesignationReg));
                         }
                     }
                 }
@@ -103,14 +94,18 @@ public class RegistrationService {
     /**
      * @param reg
      */
-    private void put(Registration reg, RegistrationDTO dto) {
-        registrationsByUUID.put(reg.getUuid(), reg);
-        registrationsByRegID.put(reg.getSpecificIdentifier(), reg);
-        registrationDTOsByRegID.put(reg.getSpecificIdentifier(), dto);
-        if(! registrationDTOsByCitationID.containsKey(dto.getCitationID())){
-            registrationDTOsByCitationID.put(dto.getCitationID(), new HashSet<RegistrationDTO>());
+    private void put(RegistrationDTO dto) {
+        Registration reg = dto.registration();
+        registrationsByUUID.put(dto.getUuid(), reg);
+        registrationsByRegID.put(reg.getId(), reg);
+
+        registrationDTOsById.put(reg.getId(), dto);
+        registrationDTOsByIdentifier.put(reg.getIdentifier(), dto);
+
+        if(! registrationDTOsByCitationId.containsKey(dto.getCitationID())){
+            registrationDTOsByCitationId.put(dto.getCitationID(), new ArrayList<RegistrationDTO>());
         }
-        registrationDTOsByCitationID.get(dto.getCitationID()).add(dto);
+        registrationDTOsByCitationId.get(dto.getCitationID()).add(dto);
     }
 
     private void mergeBack(){
@@ -125,6 +120,7 @@ public class RegistrationService {
         return registrationsByUUID.get(uuid);
     }
 
+
     public Collection<Registration> list(){
         init();
         return registrationsByUUID.values();
@@ -132,21 +128,51 @@ public class RegistrationService {
 
     public Collection<RegistrationDTO> listDTOs() {
         init();
-        return registrationDTOsByRegID.values();
+        return registrationDTOsById.values();
+    }
+
+    public Map<Integer, List<RegistrationDTO>> listDTOsByWorkingSet() {
+        init();
+        return registrationDTOsByCitationId;
+    }
+
+    /**
+     * @param  id the CDM Entity id
+     * @return
+     */
+    public Registration loadByRegistrationID(Integer id) {
+        init();
+        return registrationsByRegID.get(id);
     }
 
-    public Map<Integer, Set<RegistrationDTO>> listDTOsByWorkingSet() {
+    /**
+     * @param identifier the Registration Identifier String
+     * @return
+     */
+    public RegistrationDTO loadDtoByIdentifier(String identifier) {
         init();
-        return registrationDTOsByCitationID;
+        return registrationDTOsById.get(identifier);
     }
 
     /**
-     * @param registrationID
+     * @param id the CDM Entity id
      * @return
      */
-    public Registration loadByRegistrationID(Integer registrationID) {
+    public RegistrationDTO loadDtoById(Integer id) {
         init();
-        return registrationsByRegID.get(registrationID.toString());
+        return registrationDTOsById.get(id);
+    }
+
+    /**
+     * @param  id the CDM Entity id
+     * @return
+     * @throws RegistrationValidationException
+     */
+    public RegistrationWorkingSet loadWorkingSetByRegistrationID(Integer id) throws RegistrationValidationException {
+        init();
+        RegistrationDTO dto = registrationDTOsById.get(id);
+
+        return new RegistrationWorkingSet(registrationDTOsByCitationId.get(dto.getCitationID()));
     }
 
 
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/component/registration/RegistrationItem.java b/src/main/java/eu/etaxonomy/cdm/vaadin/component/registration/RegistrationItem.java
index 873dea2d..9c220d46 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/component/registration/RegistrationItem.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/component/registration/RegistrationItem.java
@@ -22,6 +22,7 @@ import com.vaadin.ui.Label;
 import com.vaadin.ui.Link;
 import com.vaadin.ui.themes.ValoTheme;
 
+import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationDTO;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationType;
 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationTypeConverter;
@@ -131,11 +132,25 @@ public class RegistrationItem extends GridLayout {
         updateTypeStateLabel();
         getCitationSummaryLabel().setValue(regDto.getCitationString() + "</br>" + regDto.getSummary());
         updateIdentifierLink();
-        getOpenButton().addClickListener(e -> parentView.getEventBus().publishEvent(new NavigationEvent(
+
+        // Buttons
+        getOpenButton().addClickListener(e -> publishEvent(new NavigationEvent(
                 RegistrationWorkflowViewBean.NAME,
                 RegistrationWorkflowViewBean.ACTION_EDIT,
-                regDto.getSpecificIdentifier().toString()
+                Integer.toString(regDto.getId())
                 )));
+        if(regDto.getMessages().size() > 0){
+            getMessageButton().setEnabled(true);
+            getMessageButton().addStyleName(ValoTheme.BUTTON_FRIENDLY);
+            getMessageButton().addClickListener(e -> publishEvent(
+                    new ShowDetailsEvent<RegistrationDTO, Integer>(
+                            e,
+                            RegistrationDTO.class,
+                            regDto.getId(),
+                            "messages"))
+                    );
+        }
+
         updateDateLabels();
     }
 
@@ -162,9 +177,9 @@ public class RegistrationItem extends GridLayout {
      *
      */
     private void updateIdentifierLink() {
-        getIdentifierLink().setResource(new ExternalResource(regDto.getRegistrationId()));
+        getIdentifierLink().setResource(new ExternalResource(regDto.getIdentifier()));
         //TODO make responsive and use specificIdetifier in case the space gets too narrow
-        getIdentifierLink().setCaption(regDto.getRegistrationId());
+        getIdentifierLink().setCaption(regDto.getIdentifier());
     }
 
     /**
@@ -179,6 +194,10 @@ public class RegistrationItem extends GridLayout {
         }
     }
 
+    private void publishEvent(Object event) {
+        parentView.getEventBus().publishEvent(event);
+    }
+
     /* ====== RegistrationItemDesign Getters ====== */
     /**
      * @return the typeStateLabel
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/event/ShowDetailsEvent.java b/src/main/java/eu/etaxonomy/cdm/vaadin/event/ShowDetailsEvent.java
new file mode 100644
index 00000000..d5f78212
--- /dev/null
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/event/ShowDetailsEvent.java
@@ -0,0 +1,75 @@
+/**
+* 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.cdm.vaadin.event;
+
+import com.vaadin.ui.Component.Event;
+
+/**
+ * A request to display the details of the <code>property</code> for an object of
+ * the class <code>entityType</code> which is uniquely identified by the <code>identifier</code>
+ * This event is usually passed from a view to the according presenter implementation
+ * which is capable of retrieving the details based on the <code>entityType</code> +
+ * <code>identifier</code> + <code>property</code> and which should in turn pass the
+ * extracted details data to the view for display.
+ *
+ * @author a.kohlbecker
+ * @since Mar 24, 2017
+ *
+ */
+public class ShowDetailsEvent<T extends Object, I extends Object> {
+
+    private Event source;
+    private Class<T> entityType;
+    private I identifier;
+    private String property;
+
+    /**
+     *
+     * @param e
+     * @param identifier
+     * @param property
+     */
+    public ShowDetailsEvent(Event e, Class<T> entityType , I identifier, String property) {
+        this.source = e;
+        this.entityType = entityType;
+        this.identifier = identifier;
+        this.property = property;
+    }
+
+    /**
+     * @return the source
+     */
+    public Event getSource() {
+        return source;
+    }
+
+    /**
+     * @return the type
+     */
+    public Class<T> getType() {
+        return entityType;
+    }
+
+    /**
+     * @return the identifier
+     */
+    public I getIdentifier() {
+        return identifier;
+    }
+
+    /**
+     * @return the property
+     */
+    public String getProperty() {
+        return property;
+    }
+
+
+
+}
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/model/registration/RegistrationWorkingSet.java b/src/main/java/eu/etaxonomy/cdm/vaadin/model/registration/RegistrationWorkingSet.java
index 87b94833..40c4848b 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/model/registration/RegistrationWorkingSet.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/model/registration/RegistrationWorkingSet.java
@@ -14,6 +14,7 @@ import java.util.List;
 import java.util.Set;
 
 import eu.etaxonomy.cdm.mock.Registration;
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationDTO;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationValidationException;
 
@@ -24,15 +25,21 @@ import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationValidationExce
  */
 public class RegistrationWorkingSet {
 
-    private Set<Registration> registrations = new HashSet<>();
+    private List<RegistrationDTO> registrationDTOs = new ArrayList<>();
 
     private int citationId = -1;
 
     private String citation = null;
 
-    public RegistrationWorkingSet(Set<Registration> registrations) throws RegistrationValidationException {
+    /**
+     * Creates an empty working set
+     */
+    public RegistrationWorkingSet() {
+
+    }
 
-        validateAndAdd(registrations);
+    public RegistrationWorkingSet(List<RegistrationDTO> registrationDTOs) throws RegistrationValidationException {
+        validateAndAddDTOs(registrationDTOs, null);
     }
 
     /**
@@ -40,42 +47,70 @@ public class RegistrationWorkingSet {
      * @throws RegistrationValidationException
      *
      */
-    private void validateAndAdd(Set<Registration> candidated) throws RegistrationValidationException {
-        List<String> problems = new ArrayList<>();
-        for(Registration reg : candidated){
-            try {
-                RegistrationDTO regDto = new RegistrationDTO(reg);
+    private void validateAndAdd(Set<Registration> candidates) throws RegistrationValidationException {
+        List<RegistrationDTO> dtos = new ArrayList<>(registrationDTOs.size());
+        candidates.forEach(reg -> dtos.add(new RegistrationDTO(reg)));
+        validateAndAddDTOs(dtos, null);
+    }
+
+    /**
+     * Validate and add all Registrations to the working set which are referring to the same publication
+     * which is either the citation of the nomenclatural reference of the {@link TaxonNameBase} or the
+     * citation of the {@link TypeDesignations}. Registration with a differing publication are not added to
+     * the working set, instead a {@link RegistrationValidationException} is thrown which is a container for
+     * all validation problems.
+     *
+     * @param candidates
+     * @param problems Problems detected in prior validation and processing passed to this method to be completed.
+     * @throws RegistrationValidationException
+     */
+    private void validateAndAddDTOs(List<RegistrationDTO> candidates, List<String> problems) throws RegistrationValidationException {
+        if(problems == null){
+            problems = new ArrayList<>();
+        }
+        for(RegistrationDTO regDto : candidates){
                 if(citationId == -1){
                     citationId = regDto.getCitationID();
                     citation = regDto.getCitation();
                 } else {
                     if(regDto.getCitationID() != citationId){
-                        problems.add("Removing Registration " + reg.toString() + " from set since this refers to a different citation.\n");
+                        problems.add("Removing Registration " + regDto.registration().toString() + " from set since this refers to a different citation.");
                         continue;
                     }
                 }
-                this.registrations.add(reg);
-
-            } catch (RegistrationValidationException e) {
-                problems.add(e.getMessage());
-            }
+                this.registrationDTOs.add(regDto);
         }
 
         if(!problems.isEmpty()){
-            throw new RegistrationValidationException(problems.toString());
+            throw new RegistrationValidationException("", problems);
         }
 
     }
 
-    public boolean add(Registration registration){
-        return registrations.add(registration);
+    /**
+     * @param reg
+     * @throws RegistrationValidationException
+     */
+    public void add(Registration reg) throws RegistrationValidationException {
+        Set<Registration> candidates = new HashSet<>();
+        candidates.add(reg);
+        validateAndAdd(candidates);
+    }
+
+    /**
+     * @return the registrations
+     */
+    public List<Registration> getRegistrations() {
+        List<Registration> regs = new ArrayList<>(registrationDTOs.size());
+        registrationDTOs.forEach(dto -> regs.add(dto.registration()));
+        return regs;
     }
 
     /**
      * @return the registrations
      */
-    public Set<Registration> getRegistrations() {
-        return registrations;
+    public List<RegistrationDTO> getRegistrationDTOs() {
+        return registrationDTOs;
     }
 
     /**
@@ -94,4 +129,5 @@ public class RegistrationWorkingSet {
 
 
 
+
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/ListPresenter.java b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/ListPresenter.java
index c829df09..6f5f95fc 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/ListPresenter.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/ListPresenter.java
@@ -11,11 +11,13 @@ package eu.etaxonomy.cdm.vaadin.presenter.registration;
 import java.util.Collection;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
 
 import com.vaadin.spring.annotation.SpringComponent;
 import com.vaadin.spring.annotation.ViewScope;
 
 import eu.etaxonomy.cdm.mock.RegistrationService;
+import eu.etaxonomy.cdm.vaadin.event.ShowDetailsEvent;
 import eu.etaxonomy.cdm.vaadin.view.registration.ListView;
 import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
 
@@ -45,4 +47,12 @@ public class ListPresenter extends AbstractPresenter<ListView> {
         return dtos;
     }
 
+    @EventListener(classes=ShowDetailsEvent.class) // (condition = "#event.entityType == eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationDTO")
+    public void onShowDetailsEvent(ShowDetailsEvent<?,?> event) { // WARNING don't use more specific generic type arguments
+        RegistrationDTO regDto = serviceMock.loadDtoById((Integer)event.getIdentifier());
+        if(event.getProperty().equals("messages")){
+            getView().openDetailsPopup("Messages", regDto.getMessages());
+        }
+    }
+
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationDTO.java b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationDTO.java
index 37d56219..514721be 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationDTO.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationDTO.java
@@ -8,8 +8,11 @@
 */
 package eu.etaxonomy.cdm.vaadin.presenter.registration;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 import org.joda.time.DateTime;
 
@@ -33,7 +36,7 @@ public class RegistrationDTO{
 
     private Registration reg;
 
-    static int idAutoincrement = 100000;
+    private List<String> messages = new ArrayList<>();
 
     private Set<Registration> blockedBy = new HashSet<>();
 
@@ -42,9 +45,8 @@ public class RegistrationDTO{
     /**
      * @param reg
      * @param typifiedName should be provided in for Registrations for TypeDesignations
-     * @throws RegistrationValidationException in case of inconsistencies in the Registration
      */
-    public RegistrationDTO(Registration reg) throws RegistrationValidationException {
+    public RegistrationDTO(Registration reg) {
 
          this.reg = reg;
 
@@ -57,7 +59,11 @@ public class RegistrationDTO{
                 citationID = citation.getId();
             }
         } else if(registrationType.isTypification()){
-            typifiedName = findTypifiedName();
+            try {
+                typifiedName = findTypifiedName();
+            } catch (RegistrationValidationException e) {
+                messages.add("Validation errors: " + e.getMessage());
+            }
             summary = new TypeDesignationConverter(reg.getTypeDesignations(), typifiedName)
                     .buildString().print();
             if(!reg.getTypeDesignations().isEmpty()){
@@ -70,17 +76,21 @@ public class RegistrationDTO{
         } else {
             summary = "- INVALID REGISTRATION -";
         }
+
+        messages.add("dummy");
     }
 
 
 
     /**
+     * FIXME use the validation framework validators and to store the validation problems!!!
+     *
      * @return
      * @throws RegistrationValidationException
      */
     private TaxonNameBase<?,?> findTypifiedName() throws RegistrationValidationException {
 
-        StringBuffer problems = new StringBuffer();
+        List<String> problems = new ArrayList<>();
 
         TaxonNameBase<?,?> typifiedName = null;
 
@@ -89,12 +99,12 @@ public class RegistrationDTO{
             if(typeDesignation.getTypifiedNames().isEmpty()){
 
                 //TODO instead throw RegistrationValidationException()
-                problems.append(" - Missing typifiedName in " + typeDesignation.toString()).append("\n");
+                problems.add("Missing typifiedName in " + typeDesignation.toString());
                 continue;
             }
             if(typeDesignation.getTypifiedNames().size() > 1){
               //TODO instead throw RegistrationValidationException()
-                problems.append(" - Multiple typifiedName in " + typeDesignation.toString()).append("\n");
+                problems.add("Multiple typifiedName in " + typeDesignation.toString());
                 continue;
             }
             if(typifiedName == null){
@@ -105,18 +115,30 @@ public class RegistrationDTO{
                 TaxonNameBase<?,?> otherTypifiedName = typeDesignation.getTypifiedNames().iterator().next();
                 if(typifiedName.getId() != otherTypifiedName.getId()){
                   //TODO instead throw RegistrationValidationException()
-                    problems.append(" - Multiple typifiedName in " + typeDesignation.toString()).append("\n");
+                    problems.add("Multiple typifiedName in " + typeDesignation.toString());
                 }
             }
 
         }
-        if(problems.length() > 0){
-            throw new RegistrationValidationException("Inconsistent Registration entity. " + reg.toString() + " Problems:\n" + problems.toString());
+        if(!problems.isEmpty()){
+            // FIXME use the validation framework
+            throw new RegistrationValidationException("Inconsistent Registration entity. " + reg.toString(), problems);
         }
 
         return typifiedName;
     }
 
+    /**
+     * Provides access to the Registration entity this DTO has been build from.
+     * This method is purposely not a getter to hide the original Registration
+     * from generic processes which are exposing, binding bean properties.
+     *
+     * @return
+     */
+    public Registration registration() {
+        return reg;
+    }
+
 
     /**
      * @return the summary
@@ -143,13 +165,22 @@ public class RegistrationDTO{
 
 
     /**
-     * @return the registrationId
+     * @return the identifier
      */
-    public String getRegistrationId() {
+    public String getIdentifier() {
         return reg.getIdentifier();
     }
 
 
+    public int getId() {
+        return reg.getId();
+    }
+
+
+    public UUID getUuid() {
+        return reg.getUuid();
+    }
+
     /**
      * @return the specificIdentifier
      */
@@ -196,4 +227,13 @@ public class RegistrationDTO{
         return citationID;
     }
 
+
+
+    /**
+     * @return
+     */
+    public List<String> getMessages() {
+        return messages;
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationValidationException.java b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationValidationException.java
index 6e9977b9..ae115915 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationValidationException.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationValidationException.java
@@ -8,18 +8,36 @@
 */
 package eu.etaxonomy.cdm.vaadin.presenter.registration;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * @author a.kohlbecker
  * @since Mar 23, 2017
  *
  */
+@SuppressWarnings("serial")
 public class RegistrationValidationException extends Exception {
 
+    List<String> problems = new ArrayList<>();
+
     /**
      * @param message
      */
-    public RegistrationValidationException(String message) {
+    public RegistrationValidationException(String message, List<String> problems) {
         super(message);
+        this.problems = problems;
+    }
+
+    @Override
+    public String getMessage() {
+        StringBuffer sb = new StringBuffer(super.getMessage()).append(" - Problems:");
+        problems.forEach(p -> sb.append("- ").append(p).append("\n"));
+        return sb.toString();
+    }
+
+    public List<String> getProblems() {
+        return problems;
     }
 
 
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationWorkflowPresenter.java b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationWorkflowPresenter.java
index 959035c6..b0000713 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationWorkflowPresenter.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/presenter/registration/RegistrationWorkflowPresenter.java
@@ -12,6 +12,7 @@ import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 
+import com.vaadin.server.SystemError;
 import com.vaadin.spring.annotation.SpringComponent;
 import com.vaadin.spring.annotation.ViewScope;
 
@@ -21,6 +22,7 @@ import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
 import eu.etaxonomy.cdm.vaadin.event.ReferenceEvent;
 import eu.etaxonomy.cdm.vaadin.event.registration.RegistrationWorkflowEvent;
+import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationWorkflowView;
 import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
 
@@ -37,7 +39,7 @@ public class RegistrationWorkflowPresenter extends AbstractPresenter<Registratio
     @Autowired
     private RegistrationService serviceMock;
 
-    private Registration registration;
+    private RegistrationWorkingSet workingset;
 
     /**
      *
@@ -46,24 +48,37 @@ public class RegistrationWorkflowPresenter extends AbstractPresenter<Registratio
     }
 
     @EventListener
-    protected void onRegistrationStartEvent(RegistrationWorkflowEvent e){
+    protected void onRegistrationStartEvent(RegistrationWorkflowEvent event){
 
-        if(registration != null){
-            Logger.getLogger(RegistrationWorkflowPresenter.class).warn("Foiling attempt to start another registration in existing workflow");
+        if(workingset != null){
+            Logger.getLogger(RegistrationWorkflowPresenter.class).warn("Cant start a new workflow over an existing one.");
             return;
         }
 
-        if(e.isStart()) {
-            registration = new Registration();
-            registration.setName(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()));
-            getView().setHeaderText("New " + e.getType().name().toString()+ " Registration");
+
+        if(event.isStart()) {
+            workingset = new RegistrationWorkingSet();
+            Registration reg = new Registration();
+            reg.setName(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()));
+            getView().setHeaderText("New " + event.getType().name().toString()+ " Registration");
+            try {
+                workingset.add(reg);
+            } catch (RegistrationValidationException error) {
+                getView().getWorkflow().setComponentError(new SystemError(error));
+            }
         } else {
-            registration = serviceMock.loadByRegistrationID(e.getRegistrationID());
-            getView().setHeaderText("Registration " + registration.getIdentifier());
+            try {
+                workingset = serviceMock.loadWorkingSetByRegistrationID(event.getRegistrationID());
+            } catch (RegistrationValidationException error) {
+                getView().getWorkflow().setComponentError(new SystemError(error));
+            }
+            getView().setHeaderText("Registration for " + workingset.getCitation());
         }
-        if(registration != null){
+        if(workingset != null){
             // getView().getTitle().setValue("Workflow for a " + registrationType().name());
-            getView().makeWorflow(registrationType());
+            for(Registration reg : workingset.getRegistrations()){
+                getView().makeWorflow(RegistrationType.from(reg));
+            }
         }
     }
 
@@ -77,14 +92,4 @@ public class RegistrationWorkflowPresenter extends AbstractPresenter<Registratio
         getView().openReferenceEditor(null);
     }
 
-
-    /**
-     * @return
-     */
-    private RegistrationType registrationType() {
-        return RegistrationType.from(registration);
-    }
-
-
-
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListView.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListView.java
index 28c429f0..ae1af599 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListView.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListView.java
@@ -9,6 +9,7 @@
 package eu.etaxonomy.cdm.vaadin.view.registration;
 
 import java.util.Collection;
+import java.util.List;
 
 import eu.etaxonomy.cdm.vaadin.presenter.registration.ListPresenter;
 import eu.etaxonomy.cdm.vaadin.presenter.registration.RegistrationDTO;
@@ -26,5 +27,10 @@ public interface ListView extends ApplicationView<ListPresenter>{
      */
     void populate(Collection<RegistrationDTO> registrations);
 
+    /**
+     * @param messages
+     */
+    void openDetailsPopup(String caption, List<String> messages);
+
 
 }
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListViewBean.java b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListViewBean.java
index b7a8a6ce..35326afa 100644
--- a/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListViewBean.java
+++ b/src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListViewBean.java
@@ -10,6 +10,7 @@ package eu.etaxonomy.cdm.vaadin.view.registration;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -19,6 +20,7 @@ import com.vaadin.data.util.GeneratedPropertyContainer;
 import com.vaadin.data.util.PropertyValueGenerator;
 import com.vaadin.navigator.View;
 import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
+import com.vaadin.server.Page;
 import com.vaadin.shared.ui.grid.HeightMode;
 import com.vaadin.spring.annotation.SpringView;
 import com.vaadin.ui.Button;
@@ -28,6 +30,7 @@ import com.vaadin.ui.CssLayout;
 import com.vaadin.ui.Grid;
 import com.vaadin.ui.Grid.Column;
 import com.vaadin.ui.Grid.SelectionMode;
+import com.vaadin.ui.Notification;
 import com.vaadin.ui.renderers.ButtonRenderer;
 import com.vaadin.ui.renderers.DateRenderer;
 import com.vaadin.ui.renderers.HtmlRenderer;
@@ -181,7 +184,7 @@ public class ListViewBean extends AbstractPageView<ListPresenter> implements Lis
 
         Column summaryColumn = grid.addColumn("summary");
 
-        Column regidColumn = grid.addColumn("registrationId");
+        Column regidColumn = grid.addColumn("identifier");
         regidColumn.setHeaderCaption("Id");
         regidColumn.setRenderer(new HtmlRenderer(), new UrlStringConverter("http://pyhcobank.org/"));
 
@@ -213,12 +216,21 @@ public class ListViewBean extends AbstractPageView<ListPresenter> implements Lis
     public void populateList(Collection<RegistrationDTO> registrations) {
 
         for(RegistrationDTO regDto : registrations) {
-            Component lazyItem = new RegistrationItem(regDto, this); //new LazyLoadWrapper(new RegistrationItem(regDto, this));
-            lazyItem.setWidth(100, Unit.PERCENTAGE);
-            listContainer.addComponent(lazyItem);
+            Component item = new RegistrationItem(regDto, this);
+            item.setWidth(100, Unit.PERCENTAGE);
+            listContainer.addComponent(item);
         }
     }
 
+    @Override
+    public void openDetailsPopup(String caption, List<String> messages){
+        StringBuffer sb = new StringBuffer();
+        sb.append("<div class=\"details-popup-content\">");
+        messages.forEach(s -> sb.append(s).append("</br>"));
+        sb.append("</div>");
+        new Notification(caption, sb.toString(), Notification.Type.HUMANIZED_MESSAGE, true).show(Page.getCurrent());
+    }
+
     /**
      * @param registrationItems
      * @return
