From 078fb6a05a4bff2bb7595458b4154f76fe1caea7 Mon Sep 17 00:00:00 2001
From: Alexander Marsalek <amarsalek@iaik.tugraz.at>
Date: Fri, 4 Dec 2020 12:59:42 +0100
Subject: added dummy ZMR & ERnB client

---
 .../auth/eidas/v2/dao/InitialSearchResult.java     |  12 --
 .../eidas/v2/dao/MergedRegisterSearchResult.java   |  16 ++
 .../modules/auth/eidas/v2/dao/RegisterResult.java  |  59 ++++++++
 .../modules/auth/eidas/v2/dao/SimpleEidasData.java |  52 +++++++
 .../auth/eidas/v2/ernb/DummyErnbClient.java        |  49 ++++++
 .../modules/auth/eidas/v2/ernb/IErnbClient.java    |  12 ++
 .../v2/exception/ManualFixNecessaryException.java  |   6 +-
 .../eidas/v2/handler/AbstractEidProcessor.java     | 136 ++++-------------
 .../ICountrySpecificDetailSearchProcessor.java     |   6 +-
 .../auth/eidas/v2/tasks/InitialSearchTask.java     | 147 +++++++++++++-----
 .../auth/eidas/v2/utils/EidasResponseUtils.java    | 168 +++++++++++++++++++++
 .../modules/auth/eidas/v2/zmr/DummyZmrClient.java  |  49 ++++++
 .../modules/auth/eidas/v2/zmr/IZmrClient.java      |  12 ++
 .../src/main/resources/eidas_v2_auth.beans.xml     |   6 +
 14 files changed, 569 insertions(+), 161 deletions(-)
 delete mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java
 create mode 100644 eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java

(limited to 'eidas_modules/authmodule-eIDAS-v2/src')

diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java
deleted file mode 100644
index 8fe69414..00000000
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/InitialSearchResult.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
-
-public class InitialSearchResult {
-
-  int resultsZmr;
-  int resultsErnb;
-
-  public int getResultCount() {
-    return resultsErnb + resultsZmr;
-  }
-
-}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java
new file mode 100644
index 00000000..bc5b358d
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/MergedRegisterSearchResult.java
@@ -0,0 +1,16 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+
+@Data public class MergedRegisterSearchResult {
+
+  ArrayList<RegisterResult> resultsZmr = new ArrayList<>();
+  ArrayList<RegisterResult> resultsErnb = new ArrayList<>();
+
+  public int getResultCount() {
+    return resultsZmr.size() + resultsErnb.size();
+  }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java
new file mode 100644
index 00000000..9509e7de
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/RegisterResult.java
@@ -0,0 +1,59 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
+
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
+import lombok.Data;
+
+@Data public class RegisterResult {
+
+  // MDS
+  private String pseudonym = null;
+  private String givenName = null;
+  private String familyName = null;
+  private String dateOfBirth = null;
+
+  // additional attributes
+  private String placeOfBirth = null;
+  private String birthName = null;
+  private String taxNumber = null;
+  private PostalAddressType address = null;
+
+  /**
+   * Register search result.
+   * @param pseudonym The pseudonym
+   * @param givenName The givenName
+   * @param familyName The familyName
+   * @param dateOfBirth The dateOfBirth
+   * @param placeOfBirth The placeOfBirth
+   */
+  public RegisterResult(String pseudonym, String givenName, String familyName, String dateOfBirth,
+                        String placeOfBirth) {
+    this.pseudonym = pseudonym;
+    this.givenName = givenName;
+    this.familyName = familyName;
+    this.dateOfBirth = dateOfBirth;
+    this.placeOfBirth = placeOfBirth;
+  }
+
+  /**
+   * Register search result.
+   * @param pseudonym The pseudonym
+   * @param givenName The givenName
+   * @param familyName The familyName
+   * @param dateOfBirth The dateOfBirth
+   * @param placeOfBirth The placeOfBirth
+   * @param birthName The birthName
+   * @param taxNumber The taxNumber
+   * @param address The address
+   */
+  public RegisterResult(String pseudonym, String givenName, String familyName, String dateOfBirth,
+                        String placeOfBirth, String birthName, String taxNumber, PostalAddressType address) {
+    this.pseudonym = pseudonym;
+    this.givenName = givenName;
+    this.familyName = familyName;
+    this.dateOfBirth = dateOfBirth;
+    this.placeOfBirth = placeOfBirth;
+    this.birthName = birthName;
+    this.taxNumber = taxNumber;
+    this.address = address;
+  }
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java
new file mode 100644
index 00000000..0b116bfb
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/dao/SimpleEidasData.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2018 A-SIT Plus GmbH
+ * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
+ * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "License");
+ * You may not use this work except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://joinup.ec.europa.eu/news/understanding-eupl-v12
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.dao;
+
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
+import lombok.Data;
+import org.joda.time.DateTime;
+
+import java.text.SimpleDateFormat;
+
+@Data public class SimpleEidasData {
+
+  private String citizenCountryCode = null;
+
+  // MDS
+  private String pseudonym = null;
+  private String givenName = null;
+  private String familyName = null;
+  private DateTime dateOfBirth = null;
+
+  // additional attributes
+  private String placeOfBirth = null;
+  private String birthName = null;
+  private PostalAddressType address = null;
+  private String taxNumber;
+
+  public String getFormatedDateOfBirth() {
+    return new SimpleDateFormat("yyyy-MM-dd").format(dateOfBirth.toDate());
+  }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java
new file mode 100644
index 00000000..8b2379bf
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/DummyErnbClient.java
@@ -0,0 +1,49 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+
+@Service("ErnbClientForeIDAS")
+public class DummyErnbClient implements IErnbClient {
+
+  @Override
+  public ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer) {
+    switch (personIdentifer) {
+      case "a12345":
+      case "a12345-":
+        return result1();
+      case "a123456":
+        return result2();
+      default:
+        return resultEmpty();
+    }
+  }
+
+  @Override
+  public ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth) {
+    return resultEmpty();//TODO will I only receive matches where all three values match perfectly?
+  }
+
+  private ArrayList<RegisterResult> resultEmpty() {
+    return new ArrayList<RegisterResult>();//Nobody found
+  }
+
+  private ArrayList<RegisterResult> result1() {
+    ArrayList<RegisterResult> results = new ArrayList<>();
+    RegisterResult result1 = new RegisterResult("a12345", "Tom", "Mustermann", "1950-01-01", "Wien");
+    results.add(result1);
+    RegisterResult result2 = new RegisterResult("a12345-", "Tom", "Mustermann", "1950-01-01", "Wien");
+    results.add(result2);
+    return results;
+  }
+
+  private ArrayList<RegisterResult> result2() {
+    ArrayList<RegisterResult> results = new ArrayList<>();
+    RegisterResult result = new RegisterResult("a123456", "Max", "Mustermann", "2000-01-01", "Wien");
+    results.add(result);
+    return results;
+  }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java
new file mode 100644
index 00000000..4873b939
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/ernb/IErnbClient.java
@@ -0,0 +1,12 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
+
+import java.util.ArrayList;
+
+public interface IErnbClient {
+
+  ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer);
+
+  ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth);
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java
index f3916ed6..c22e8135 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/exception/ManualFixNecessaryException.java
@@ -23,18 +23,16 @@
 
 package at.asitplus.eidas.specific.modules.auth.eidas.v2.exception;
 
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
 
 public class ManualFixNecessaryException extends EidasSAuthenticationException {
   private static final long serialVersionUID = 1L;
 
   public ManualFixNecessaryException(String personIdentifier) {
     super("eidas.00", new Object[] { personIdentifier });//TODO "eidas.00"
-
   }
 
-  public ManualFixNecessaryException(ErnbEidData eidData) {
-
+  public ManualFixNecessaryException(SimpleEidasData eidData) {
     super("eidas.00", new Object[] { eidData.getPseudonym() });//TODO "eidas.00"   => what info to pass???
   }
 }
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
index fe839c37..e3c1e00f 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/AbstractEidProcessor.java
@@ -23,18 +23,6 @@
 
 package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
 
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import com.google.common.collect.ImmutableSortedSet;
-
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
@@ -46,12 +34,21 @@ import at.gv.egiz.eaaf.core.api.IRequest;
 import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
 import at.gv.egiz.eaaf.core.api.idp.ISpConfiguration;
 import at.gv.egiz.eaaf.core.impl.data.Triple;
+import com.google.common.collect.ImmutableSortedSet;
 import edu.umd.cs.findbugs.annotations.NonNull;
 import eu.eidas.auth.commons.attribute.AttributeDefinition;
 import eu.eidas.auth.commons.attribute.ImmutableAttributeMap;
 import eu.eidas.auth.commons.light.impl.LightRequest.Builder;
 import eu.eidas.auth.commons.protocol.eidas.SpType;
-import eu.eidas.auth.commons.protocol.eidas.impl.PostalAddress;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public abstract class AbstractEidProcessor implements INationalEidProcessor {
   private static final Logger log = LoggerFactory.getLogger(AbstractEidProcessor.class);
@@ -66,7 +63,6 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
 
     buildProviderNameAttribute(pendingReq, authnRequestBuilder);
     buildRequestedAttributes(authnRequestBuilder);
-
   }
 
   @Override
@@ -91,13 +87,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
     result.setAddress(processAddress(eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));
 
     return result;
-
   }
 
-  
+
   /**
    * Get a Map of country-specific requested attributes.
-   * 
+   *
    * @return
    */
   @NonNull
@@ -105,7 +100,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
 
   /**
    * Post-Process the eIDAS CurrentAddress attribute.
-   * 
+   *
    * @param currentAddressObj eIDAS current address information
    * @return current address or null if no attribute is available
    * @throws EidPostProcessingException if post-processing fails
@@ -113,34 +108,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException,
       EidasAttributeException {
-
-    if (currentAddressObj != null) {
-      if (currentAddressObj instanceof PostalAddress) {
-        final PostalAddressType result = new PostalAddressType();
-        result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode());
-        result.setMunicipality(((PostalAddress) currentAddressObj).getPostName());
-
-        // TODO: add more mappings
-        
-        return result;
-
-      } else {
-        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
-        throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS);
-
-      }
-
-    } else {
-      log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
-    }
-
-    return null;
-
+    return EidasResponseUtils.processAddress(currentAddressObj);
   }
 
   /**
    * Post-Process the eIDAS BirthName attribute.
-   * 
+   *
    * @param birthNameObj eIDAS birthname information
    * @return birthName or null if no attribute is available
    * @throws EidPostProcessingException if post-processing fails
@@ -148,27 +121,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected String processBirthName(Object birthNameObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (birthNameObj != null) {
-      if (birthNameObj instanceof String) {
-        return (String) birthNameObj;
-
-      } else {
-        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
-        throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME);
-
-      }
-
-    } else {
-      log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
-    }
-
-    return null;
-
+    return EidasResponseUtils.processBirthName(birthNameObj);
   }
 
   /**
    * Post-Process the eIDAS PlaceOfBirth attribute.
-   * 
+   *
    * @param placeOfBirthObj eIDAS Place-of-Birth information
    * @return place of Birth or null if no attribute is available
    * @throws EidPostProcessingException if post-processing fails
@@ -176,27 +134,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (placeOfBirthObj != null) {
-      if (placeOfBirthObj instanceof String) {
-        return (String) placeOfBirthObj;
-
-      } else {
-        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
-        throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH);
-
-      }
-
-    } else {
-      log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
-    }
-
-    return null;
-
+    return EidasResponseUtils.processPlaceOfBirth(placeOfBirthObj);
   }
 
   /**
    * Post-Process the eIDAS DateOfBirth attribute.
-   * 
+   *
    * @param dateOfBirthObj eIDAS date-of-birth attribute information
    * @return formated user's date-of-birth
    * @throws EidasAttributeException    if NO attribute is available
@@ -204,17 +147,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) {
-      throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
-    }
-
-    return (DateTime) dateOfBirthObj;
-
+    return EidasResponseUtils.processDateOfBirth(dateOfBirthObj);
   }
 
   /**
    * Post-Process the eIDAS GivenName attribute.
-   * 
+   *
    * @param givenNameObj eIDAS givenName attribute information
    * @return formated user's givenname
    * @throws EidasAttributeException    if NO attribute is available
@@ -222,17 +160,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected String processGivenName(Object givenNameObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (givenNameObj == null || !(givenNameObj instanceof String)) {
-      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
-    }
-
-    return (String) givenNameObj;
-
+    return EidasResponseUtils.processGivenName(givenNameObj);
   }
 
   /**
    * Post-Process the eIDAS FamilyName attribute.
-   * 
+   *
    * @param familyNameObj eIDAS familyName attribute information
    * @return formated user's familyname
    * @throws EidasAttributeException    if NO attribute is available
@@ -240,17 +173,12 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected String processFamilyName(Object familyNameObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (familyNameObj == null || !(familyNameObj instanceof String)) {
-      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
-    }
-
-    return (String) familyNameObj;
-
+    return EidasResponseUtils.processFamilyName(familyNameObj);
   }
 
   /**
    * Post-Process the eIDAS pseudonym to ERnB unique identifier.
-   * 
+   *
    * @param personalIdObj eIDAS PersonalIdentifierAttribute
    * @return Unique personal identifier without country-code information
    * @throws EidasAttributeException    if NO attribute is available
@@ -258,15 +186,7 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
    */
   protected String processPseudonym(Object personalIdObj) throws EidPostProcessingException,
       EidasAttributeException {
-    if (personalIdObj == null || !(personalIdObj instanceof String)) {
-      throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
-    }
-
-    final Triple<String, String, String> eIdentifier =
-        EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj);
-
-    return eIdentifier.getThird();
-
+    return EidasResponseUtils.processPseudonym(personalIdObj);
   }
 
   private void buildRequestedAttributes(Builder authnRequestBuilder) {
@@ -332,8 +252,8 @@ public abstract class AbstractEidProcessor implements INationalEidProcessor {
         final String providerName = pendingReq.getRawData(Constants.DATA_PROVIDERNAME, String.class);
         if (StringUtils.isNotEmpty(providerName)
             && basicConfig.getBasicConfigurationBoolean(
-                Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME,
-                false)) {
+            Constants.CONIG_PROPS_EIDAS_NODE_WORKAROUND_ADD_ALWAYS_PROVIDERNAME,
+            false)) {
           authnRequestBuilder.providerName(providerName);
 
         }
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java
index c35f6e16..13d9117d 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/handler/ICountrySpecificDetailSearchProcessor.java
@@ -24,7 +24,7 @@
 package at.asitplus.eidas.specific.modules.auth.eidas.v2.handler;
 
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.CountrySpecificDetailSearchResult;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
 
 public interface ICountrySpecificDetailSearchProcessor {
 
@@ -52,7 +52,7 @@ public interface ICountrySpecificDetailSearchProcessor {
    * @param eidData eID data
    * @return true if this implementation can handle the country, otherwise false
    */
-  boolean canHandle(String countryCode, ErnbEidData eidData);
+  boolean canHandle(String countryCode, SimpleEidasData eidData);
 
-  CountrySpecificDetailSearchResult search(ErnbEidData eidData);
+  CountrySpecificDetailSearchResult search(SimpleEidasData eidData);
 }
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java
index d9f70a81..6f4cfefc 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java
@@ -25,14 +25,19 @@ package at.asitplus.eidas.specific.modules.auth.eidas.v2.tasks;
 
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.CountrySpecificDetailSearchResult;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.ErnbEidData;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.InitialSearchResult;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MergedRegisterSearchResult;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb.IErnbClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ManualFixNecessaryException;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.handler.ICountrySpecificDetailSearchProcessor;
-import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService;
 import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.EidasResponseUtils;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.IZmrClient;
 import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
 import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
 import at.gv.egiz.eaaf.core.impl.idp.auth.data.AuthProcessDataWrapper;
 import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
 import com.google.common.collect.ImmutableMap;
@@ -75,13 +80,19 @@ public class InitialSearchTask extends AbstractAuthServletTask {
   //  private IConfiguration basicConfig;
   //  @Autowired
   //  private SzrClient szrClient;
-  @Autowired
-  private ICcSpecificEidProcessingService eidPostProcessor;
+  //  @Autowired
+  //  private ICcSpecificEidProcessingService eidPostProcessor;
 
   //  private static final String EID_STATUS = "urn:eidgvat:eid.status.eidas";
   @Autowired
   private ApplicationContext context;
 
+  @Autowired
+  private IErnbClient ernbClient;
+
+  @Autowired
+  private IZmrClient zmrClient;
+
   @PostConstruct
   private void initialize() {
     log.debug("Initialize country specific detail search services ... ");
@@ -127,36 +138,82 @@ public class InitialSearchTask extends AbstractAuthServletTask {
           eidasResponse.getAttributes().getAttributeMap());
 
       // post-process eIDAS attributes
-      final ErnbEidData eidData = eidPostProcessor.postProcess(simpleAttrMap);
-
-      String personIdentifier = eidData.getPseudonym();
-
-      //search in register(step 2)
-      InitialSearchResult result = searchInZmrAndErnp(personIdentifier);
-      switch (result.getResultCount()) {
-        case 0:
-          step5(result, eidData);
-          break;
-        case 1:
-          step3(result, eidData);
-          break;
-        default://should not happen
-          throw new TaskExecutionException(pendingReq, "Initial search - Kitt Process necessary.",
-              new ManualFixNecessaryException(personIdentifier));
-      }
+      final SimpleEidasData eidData = convertSimpleMapToSimpleData(simpleAttrMap);
+      step2(eidData);
     } catch (final Exception e) {
       log.error("Initial search FAILED.", e);
       throw new TaskExecutionException(pendingReq, "Initial search FAILED.", e);
     }
   }
 
-  private void step3(InitialSearchResult result, ErnbEidData eidData) {
+  private void step2(SimpleEidasData eidData) throws TaskExecutionException {
+    String personIdentifier = eidData.getPseudonym();
+    //search in register(step 2)
+    MergedRegisterSearchResult result = searchInZmrAndErnp(personIdentifier);
+    switch (result.getResultCount()) {
+      case 0:
+        step5(result, eidData);
+        break;
+      case 1:
+        step3(result, eidData);
+        break;
+      default://should not happen
+        throw new TaskExecutionException(pendingReq, "Initial search - Kitt Process necessary.",
+            new ManualFixNecessaryException(personIdentifier));
+    }
+  }
+
+  private SimpleEidasData convertSimpleMapToSimpleData(Map<String, Object> eidasAttrMap)
+      throws EidasAttributeException, EidPostProcessingException {
+    SimpleEidasData simpleEidasData = new SimpleEidasData();
+
+    final Object eIdentifierObj = eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+    final Triple<String, String, String> eIdentifier =
+        EidasResponseUtils.parseEidasPersonalIdentifier((String) eIdentifierObj);
+    simpleEidasData.setCitizenCountryCode(eIdentifier.getFirst());
+
+    // MDS attributes
+    simpleEidasData.setPseudonym(EidasResponseUtils.processPseudonym(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_PERSONALIDENTIFIER)));
+    simpleEidasData.setFamilyName(EidasResponseUtils.processFamilyName(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTFAMILYNAME)));
+    simpleEidasData.setGivenName(EidasResponseUtils.processGivenName(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTGIVENNAME)));
+    simpleEidasData.setDateOfBirth(EidasResponseUtils.processDateOfBirth(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_DATEOFBIRTH)));
+
+    // additional attributes
+    simpleEidasData.setPlaceOfBirth(EidasResponseUtils.processPlaceOfBirth(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_PLACEOFBIRTH)));
+    simpleEidasData.setBirthName(EidasResponseUtils.processBirthName(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_BIRTHNAME)));
+    simpleEidasData.setAddress(EidasResponseUtils.processAddress(
+        eidasAttrMap.get(Constants.eIDAS_ATTR_CURRENTADDRESS)));
+
+    //TODO other additional attributes
+    return simpleEidasData;
+  }
+
+  private void step3(MergedRegisterSearchResult result, SimpleEidasData eidData) {
     //check if data from eidas authentication matches with data from register
-    //TODO
 
+    log.debug("Compare " + result + " with " + eidData);
+    //TODO check if data matches
+    boolean match = true;
+    if (match) {
+      return;
+    } else {
+      step4(result, eidData);
+    }
   }
 
-  private void step5(InitialSearchResult result, ErnbEidData eidData) throws TaskExecutionException {
+  private void step4(MergedRegisterSearchResult result, SimpleEidasData eidData) {
+    log.debug("Update " + result + " with " + eidData);
+    //TODO
+  }
+
+  private void step5(MergedRegisterSearchResult result, SimpleEidasData eidData)
+      throws TaskExecutionException {
     String citizenCountry = eidData.getCitizenCountryCode();
     ICountrySpecificDetailSearchProcessor foundHandler = null;
     for (final ICountrySpecificDetailSearchProcessor el : handlers) {
@@ -178,7 +235,8 @@ public class InitialSearchTask extends AbstractAuthServletTask {
   }
 
   private void step6(ICountrySpecificDetailSearchProcessor countrySpecificDetailSearchProcessor,
-                     InitialSearchResult initialSearchResult, ErnbEidData eidData) throws TaskExecutionException {
+                     MergedRegisterSearchResult initialSearchResult, SimpleEidasData eidData)
+      throws TaskExecutionException {
     //6 country specific search
     CountrySpecificDetailSearchResult countrySpecificDetailSearchResult =
         countrySpecificDetailSearchProcessor.search(eidData);
@@ -196,19 +254,40 @@ public class InitialSearchTask extends AbstractAuthServletTask {
     }
   }
 
-  private void step7a(InitialSearchResult initialSearchResult,
-                      CountrySpecificDetailSearchResult countrySpecificDetailSearchResult, ErnbEidData eidData) {
+  private void step7a(MergedRegisterSearchResult initialSearchResult,
+                      CountrySpecificDetailSearchResult countrySpecificDetailSearchResult, SimpleEidasData eidData) {
     //TODO automerge
-
+    log.debug("Automerge " + initialSearchResult + " with " + eidData + " " + countrySpecificDetailSearchResult);
   }
 
-  private void step8(InitialSearchResult initialSearchResult, ErnbEidData eidData) {
-    //TODO MDS Suche
+  private void step8(MergedRegisterSearchResult initialSearchResult, SimpleEidasData eidData) {
+    MergedRegisterSearchResult mdsSearchResult = new MergedRegisterSearchResult();
+
+    ArrayList<RegisterResult> resultsZmr =
+        zmrClient.searchWithMds(eidData.getGivenName(), eidData.getFamilyName(), eidData.getFormatedDateOfBirth());
+    mdsSearchResult.setResultsZmr(resultsZmr);
+
+    ArrayList<RegisterResult> resultsErnb =
+        ernbClient.searchWithMds(eidData.getGivenName(), eidData.getFamilyName(), eidData.getFormatedDateOfBirth());
+    mdsSearchResult.setResultsErnb(resultsErnb);
+
+    log.debug("Automerge " + initialSearchResult + " with " + eidData + " " + mdsSearchResult);
+    //TODO
+
   }
 
-  private InitialSearchResult searchInZmrAndErnp(String personIdentifier) {
-    //search TODO
-    return new InitialSearchResult();//TODO
+  private MergedRegisterSearchResult searchInZmrAndErnp(String personIdentifier) {
+    MergedRegisterSearchResult initialSearchResult = new MergedRegisterSearchResult();
+
+    ArrayList<RegisterResult> resultsZmr =
+        zmrClient.searchWithPersonIdentifer(personIdentifier);
+    initialSearchResult.setResultsZmr(resultsZmr);
+
+    ArrayList<RegisterResult> resultsErnb =
+        ernbClient.searchWithPersonIdentifer(personIdentifier);
+    initialSearchResult.setResultsErnb(resultsErnb);
+
+    return initialSearchResult;
   }
 
   private Map<String, Object> convertEidasAttrToSimpleMap(
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
index ebd2ae78..c68a602b 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/EidasResponseUtils.java
@@ -30,6 +30,9 @@ import java.util.regex.Pattern;
 
 import javax.annotation.Nullable;
 
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException;
+import at.gv.e_government.reference.namespace.persondata._20020228.PostalAddressType;
 import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -169,4 +172,169 @@ public class EidasResponseUtils {
 
   }
 
+  /**
+   * Post-Process the eIDAS CurrentAddress attribute.
+   *
+   * @param currentAddressObj eIDAS current address information
+   * @return current address or null if no attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type
+   */
+  public static PostalAddressType processAddress(Object currentAddressObj) throws EidPostProcessingException,
+      EidasAttributeException {
+
+    if (currentAddressObj != null) {
+      if (currentAddressObj instanceof PostalAddress) {
+        final PostalAddressType result = new PostalAddressType();
+        result.setPostalCode(((PostalAddress) currentAddressObj).getPostCode());
+        result.setMunicipality(((PostalAddress) currentAddressObj).getPostName());
+
+        // TODO: add more mappings
+
+        return result;
+
+      } else {
+        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_CURRENTADDRESS + " is of WRONG type");
+        throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTADDRESS);
+
+      }
+
+    } else {
+      log.debug("NO '" + Constants.eIDAS_ATTR_CURRENTADDRESS + "' attribute. Post-Processing skipped ... ");
+    }
+
+    return null;
+
+  }
+
+  /**
+   * Post-Process the eIDAS BirthName attribute.
+   *
+   * @param birthNameObj eIDAS birthname information
+   * @return birthName or null if no attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type
+   */
+  public static String processBirthName(Object birthNameObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (birthNameObj != null) {
+      if (birthNameObj instanceof String) {
+        return (String) birthNameObj;
+
+      } else {
+        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_BIRTHNAME + " is of WRONG type");
+        throw new EidasAttributeException(Constants.eIDAS_ATTR_BIRTHNAME);
+
+      }
+
+    } else {
+      log.debug("NO '" + Constants.eIDAS_ATTR_BIRTHNAME + "' attribute. Post-Processing skipped ... ");
+    }
+
+    return null;
+
+  }
+
+  /**
+   * Post-Process the eIDAS PlaceOfBirth attribute.
+   *
+   * @param placeOfBirthObj eIDAS Place-of-Birth information
+   * @return place of Birth or null if no attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   * @throws EidasAttributeException    if eIDAS attribute is of a wrong type
+   */
+  public static String processPlaceOfBirth(Object placeOfBirthObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (placeOfBirthObj != null) {
+      if (placeOfBirthObj instanceof String) {
+        return (String) placeOfBirthObj;
+
+      } else {
+        log.warn("eIDAS attr: " + Constants.eIDAS_ATTR_PLACEOFBIRTH + " is of WRONG type");
+        throw new EidasAttributeException(Constants.eIDAS_ATTR_PLACEOFBIRTH);
+
+      }
+
+    } else {
+      log.debug("NO '" + Constants.eIDAS_ATTR_PLACEOFBIRTH + "' attribute. Post-Processing skipped ... ");
+    }
+
+    return null;
+
+  }
+
+  /**
+   * Post-Process the eIDAS DateOfBirth attribute.
+   *
+   * @param dateOfBirthObj eIDAS date-of-birth attribute information
+   * @return formated user's date-of-birth
+   * @throws EidasAttributeException    if NO attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   */
+  public static DateTime processDateOfBirth(Object dateOfBirthObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (dateOfBirthObj == null || !(dateOfBirthObj instanceof DateTime)) {
+      throw new EidasAttributeException(Constants.eIDAS_ATTR_DATEOFBIRTH);
+    }
+
+    return (DateTime) dateOfBirthObj;
+
+  }
+
+  /**
+   * Post-Process the eIDAS GivenName attribute.
+   *
+   * @param givenNameObj eIDAS givenName attribute information
+   * @return formated user's givenname
+   * @throws EidasAttributeException    if NO attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   */
+  public static String processGivenName(Object givenNameObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (givenNameObj == null || !(givenNameObj instanceof String)) {
+      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTGIVENNAME);
+    }
+
+    return (String) givenNameObj;
+
+  }
+
+  /**
+   * Post-Process the eIDAS FamilyName attribute.
+   *
+   * @param familyNameObj eIDAS familyName attribute information
+   * @return formated user's familyname
+   * @throws EidasAttributeException    if NO attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   */
+  public static String processFamilyName(Object familyNameObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (familyNameObj == null || !(familyNameObj instanceof String)) {
+      throw new EidasAttributeException(Constants.eIDAS_ATTR_CURRENTFAMILYNAME);
+    }
+
+    return (String) familyNameObj;
+
+  }
+
+  /**
+   * Post-Process the eIDAS pseudonym to ERnB unique identifier.
+   *
+   * @param personalIdObj eIDAS PersonalIdentifierAttribute
+   * @return Unique personal identifier without country-code information
+   * @throws EidasAttributeException    if NO attribute is available
+   * @throws EidPostProcessingException if post-processing fails
+   */
+  public static String processPseudonym(Object personalIdObj) throws EidPostProcessingException,
+      EidasAttributeException {
+    if (personalIdObj == null || !(personalIdObj instanceof String)) {
+      throw new EidasAttributeException(Constants.eIDAS_ATTR_PERSONALIDENTIFIER);
+    }
+
+    final Triple<String, String, String> eIdentifier =
+        EidasResponseUtils.parseEidasPersonalIdentifier((String) personalIdObj);
+
+    return eIdentifier.getThird();
+
+  }
 }
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java
new file mode 100644
index 00000000..9a7cc9b3
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/DummyZmrClient.java
@@ -0,0 +1,49 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+
+@Service("ZmrClientForeIDAS")
+public class DummyZmrClient implements IZmrClient {
+
+  @Override
+  public ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer) {
+    switch (personIdentifer) {
+      case "a12345":
+      case "a12345-":
+        return result1();
+      case "a123456":
+        return result2();
+      default:
+        return resultEmpty();
+    }
+  }
+
+  @Override
+  public ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth) {
+    return resultEmpty();//TODO will I only receive matches where all three values match perfectly?
+  }
+
+  private ArrayList<RegisterResult> resultEmpty() {
+    return new ArrayList<RegisterResult>();//Nobody found
+  }
+
+  private ArrayList<RegisterResult> result1() {
+    ArrayList<RegisterResult> results = new ArrayList<>();
+    RegisterResult result1 = new RegisterResult("12345", "Tom", "Mustermann", "1950-01-01", "Wien");
+    results.add(result1);
+    RegisterResult result2 = new RegisterResult("12345-", "Tom", "Mustermann", "1950-01-01", "Wien");
+    results.add(result2);
+    return results;
+  }
+
+  private ArrayList<RegisterResult> result2() {
+    ArrayList<RegisterResult> results = new ArrayList<>();
+    RegisterResult result = new RegisterResult("123456", "Max", "Mustermann", "2000-01-01", "Wien");
+    results.add(result);
+    return results;
+  }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java
new file mode 100644
index 00000000..1f7e4949
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/zmr/IZmrClient.java
@@ -0,0 +1,12 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.RegisterResult;
+
+import java.util.ArrayList;
+
+public interface IZmrClient {
+
+  ArrayList<RegisterResult> searchWithPersonIdentifer(String personIdentifer);
+
+  ArrayList<RegisterResult> searchWithMds(String givenName, String familyName, String dateOfBirth);
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
index 9c28bf07..0f6277c0 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
@@ -17,6 +17,12 @@
   <bean id="SZRClientForeIDAS"
     class="at.asitplus.eidas.specific.modules.auth.eidas.v2.szr.SzrClient" />
 
+  <bean id="ErnbClientForeIDAS"
+        class="at.asitplus.eidas.specific.modules.auth.eidas.v2.ernb.DummyErnbClient" />
+
+  <bean id="ZmrClientForeIDAS"
+        class="at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.DummyZmrClient" />
+
   <bean id="specificConnectorAttributesFile"
     class="java.lang.String">
     <constructor-arg value="eidas-attributes.xml" />
-- 
cgit v1.2.3