diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 35cea991e8a0c1cb66d17ca015d58cd8167f393e..048711ff0c150503a780a767d14c6d6dd6590830 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -277,23 +277,28 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
 {
     private final LastModificationState lastModificationState;
 
+    private final IDataStoreServiceRegistrator dataStoreServiceRegistrator;
+
     public CommonServer(final IAuthenticationService authenticationService,
             final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
             final ICommonBusinessObjectFactory businessObjectFactory,
+            IDataStoreServiceRegistrator dataStoreServiceRegistrator,
             final LastModificationState lastModificationState)
     {
         this(authenticationService, sessionManager, daoFactory, null, businessObjectFactory,
-                lastModificationState);
+                dataStoreServiceRegistrator, lastModificationState);
     }
 
     CommonServer(final IAuthenticationService authenticationService,
             final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
             IPropertiesBatchManager propertiesBatchManager,
             final ICommonBusinessObjectFactory businessObjectFactory,
+            IDataStoreServiceRegistrator dataStoreServiceRegistrator,
             final LastModificationState lastModificationState)
     {
         super(authenticationService, sessionManager, daoFactory, propertiesBatchManager,
                 businessObjectFactory);
+        this.dataStoreServiceRegistrator = dataStoreServiceRegistrator;
         this.lastModificationState = lastModificationState;
     }
 
@@ -1246,6 +1251,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         IEntityTypeBO entityTypeBO = businessObjectFactory.createEntityTypeBO(session);
         entityTypeBO.define(entityType);
         entityTypeBO.save();
+        dataStoreServiceRegistrator.register(entityType);
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a0bd90e0b3ee0e66a016f2f86e9215a198c2a03
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.collections.CollectionUtils;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataSetTypeDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class DataStoreServiceRegistrator implements IDataStoreServiceRegistrator
+{
+    private static Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY,
+            DataStoreServiceRegistrator.class);
+
+    private final IDAOFactory daoFactory;
+
+    private final Map<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>> dataStoreToServicesMap =
+            new HashMap<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>>();
+
+    public DataStoreServiceRegistrator(IDAOFactory daoFactory)
+    {
+        this.daoFactory = daoFactory;
+    }
+
+    @Override
+    public void setServiceDescriptions(DataStorePE dataStore,
+            DatastoreServiceDescriptions serviceDescriptions)
+    {
+        Set<DataStoreServicePE> dataStoreServices = createDataStoreServices(serviceDescriptions);
+        dataStore.setServices(dataStoreServices);
+        daoFactory.getDataStoreDAO().createOrUpdateDataStore(dataStore);
+        Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>> serviceKindToServicesMap =
+                new HashMap<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>();
+        serviceKindToServicesMap.put(DataStoreServiceKind.QUERIES,
+                extractMap(serviceDescriptions.getReportingServiceDescriptions()));
+        serviceKindToServicesMap.put(DataStoreServiceKind.PROCESSING,
+                extractMap(serviceDescriptions.getProcessingServiceDescriptions()));
+        dataStoreToServicesMap.put(dataStore.getCode(), serviceKindToServicesMap);
+    }
+
+    private Map<String, DatastoreServiceDescription> extractMap(
+            List<DatastoreServiceDescription> descriptions)
+    {
+        Map<String, DatastoreServiceDescription> map =
+                new HashMap<String, DatastoreServiceDescription>();
+        for (DatastoreServiceDescription description : descriptions)
+        {
+            map.put(description.getKey(), description);
+        }
+        return map;
+    }
+
+    private Set<DataStoreServicePE> createDataStoreServices(
+            DatastoreServiceDescriptions serviceDescriptions)
+    {
+        Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>();
+
+        Set<DataStoreServicePE> processing =
+                createDataStoreServices(serviceDescriptions.getProcessingServiceDescriptions(),
+                        DataStoreServiceKind.PROCESSING);
+        services.addAll(processing);
+
+        Set<DataStoreServicePE> queries =
+                createDataStoreServices(serviceDescriptions.getReportingServiceDescriptions(),
+                        DataStoreServiceKind.QUERIES);
+        services.addAll(queries);
+
+        return services;
+    }
+
+    private Set<DataStoreServicePE> createDataStoreServices(
+            List<DatastoreServiceDescription> serviceDescriptions, DataStoreServiceKind serviceKind)
+    {
+        Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>();
+        for (DatastoreServiceDescription desc : serviceDescriptions)
+        {
+            DataStoreServicePE service = new DataStoreServicePE();
+            service.setKey(desc.getKey());
+            service.setLabel(desc.getLabel());
+            service.setKind(serviceKind);
+            Set<DataSetTypePE> datasetTypes = extractDatasetTypes(desc.getDatasetTypeCodes(), desc);
+            service.setDatasetTypes(datasetTypes);
+            service.setReportingPluginTypeOrNull(desc.tryReportingPluginType());
+            services.add(service);
+        }
+        return services;
+    }
+
+    /**
+     * Find the data set type objects specified by the dataSetTypeCodes.
+     * 
+     * @return A set of DataSetTypePE objects.
+     */
+    private Set<DataSetTypePE> extractDatasetTypes(String[] dataSetTypeCodes,
+            DatastoreServiceDescription serviceDescription)
+    {
+        Set<DataSetTypePE> dataSetTypes = new HashSet<DataSetTypePE>();
+        Set<String> missingCodes = new HashSet<String>();
+        IDataSetTypeDAO dataSetTypeDAO = daoFactory.getDataSetTypeDAO();
+        List<DataSetTypePE> allDataSetTypes = dataSetTypeDAO.listAllEntities();
+
+        for (String dataSetTypeCode : dataSetTypeCodes)
+        {
+            boolean found = false;
+            // Try to find the specified data set type
+            for (DataSetTypePE dataSetType : allDataSetTypes)
+            {
+                if (dataSetType.getCode().matches(dataSetTypeCode))
+                {
+                    dataSetTypes.add(dataSetType);
+                    found = true;
+                }
+            }
+            if (false == found)
+            {
+                missingCodes.add(dataSetTypeCode);
+            }
+        }
+        if (missingCodes.size() > 0)
+        {
+            notifyDataStoreServerMisconfiguration(missingCodes, serviceDescription);
+        }
+        return dataSetTypes;
+    }
+
+    private void notifyDataStoreServerMisconfiguration(Set<String> missingCodes,
+            DatastoreServiceDescription serviceDescription)
+    {
+        String missingCodesText = CollectionUtils.abbreviate(missingCodes, -1);
+        notificationLog.warn(String.format("The Datastore Server Plugin '%s' is misconfigured. "
+                + "It refers to the dataset types which do not exist in openBIS: %s",
+                serviceDescription.toString(), missingCodesText));
+    }
+
+    @Override
+    public void register(DataSetType dataSetType)
+    {
+        IDataStoreDAO dataStoreDAO = daoFactory.getDataStoreDAO();
+
+        Set<Entry<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>>> entrySet =
+                dataStoreToServicesMap.entrySet();
+        for (Entry<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>> entry : entrySet)
+        {
+            String dataStoreCode = entry.getKey();
+            Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>> serviceKindToServicesMap =
+                    entry.getValue();
+            DataStorePE dataStore = dataStoreDAO.tryToFindDataStoreByCode(dataStoreCode);
+            Set<DataStoreServicePE> services = dataStore.getServices();
+            for (DataStoreServicePE service : services)
+            {
+                Set<DataSetTypePE> dataSetTypes = service.getDatasetTypes();
+                if (containsDataType(dataSetTypes, dataSetType))
+                {
+                    continue;
+                }
+                DatastoreServiceDescription description =
+                        serviceKindToServicesMap.get(service.getKind()).get(service.getKey());
+                if (description == null)
+                {
+                    continue;
+                }
+                if (matchesPattern(description, dataSetType))
+                {
+                    DataSetTypePE newDataSetType =
+                            daoFactory.getDataSetTypeDAO().tryToFindDataSetTypeByCode(
+                                    dataSetType.getCode());
+                    if (newDataSetType != null)
+                    {
+                        Set<DataSetTypePE> extendedDataSetTypes =
+                                new HashSet<DataSetTypePE>(dataSetTypes);
+                        extendedDataSetTypes.add(newDataSetType);
+                        service.setDatasetTypes(extendedDataSetTypes);
+                    }
+                }
+            }
+            dataStoreDAO.createOrUpdateDataStore(dataStore);
+        }
+    }
+
+    private boolean matchesPattern(DatastoreServiceDescription description, DataSetType dataSetType)
+    {
+        String[] datasetTypeCodePatterns = description.getDatasetTypeCodes();
+        for (String pattern : datasetTypeCodePatterns)
+        {
+            if (dataSetType.getCode().matches(pattern))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean containsDataType(Collection<DataSetTypePE> dataSetTypes, DataSetType dataSetType)
+    {
+        for (DataSetTypePE dataSetTypePE : dataSetTypes)
+        {
+            if (dataSetTypePE.getCode().equals(dataSetType.getCode()))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index c8cc973ffa1b868150bd993dc1cd5186e16aa461..944baa1c5b5939825801798cacd7df10004f2df8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -36,7 +36,6 @@ import ch.systemsx.cisd.authentication.DefaultSessionManager;
 import ch.systemsx.cisd.authentication.DummyAuthenticationService;
 import ch.systemsx.cisd.authentication.IAuthenticationService;
 import ch.systemsx.cisd.authentication.ISessionManager;
-import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.conversation.IConversationalRmiClient;
 import ch.systemsx.cisd.common.conversation.IProgressListener;
 import ch.systemsx.cisd.common.conversation.RmiServiceFactory;
@@ -94,9 +93,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletedDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
@@ -143,7 +140,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerInfo;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityCollectionForCreationOrUpdate;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityOperationsLogEntryPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
@@ -218,14 +214,17 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
 
     private IETLLIMSServiceConversational etlService;
 
+    private final IDataStoreServiceRegistrator dataStoreServiceRegistrator;
+
     public ETLService(IAuthenticationService authenticationService,
             ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
             ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory,
             TrustedCrossOriginDomainsProvider trustedOriginDomainProvider,
-            IETLEntityOperationChecker entityOperationChecker)
+            IETLEntityOperationChecker entityOperationChecker,
+            IDataStoreServiceRegistrator dataStoreServiceRegistrator)
     {
         this(authenticationService, sessionManager, daoFactory, null, boFactory, dssFactory,
-                trustedOriginDomainProvider, entityOperationChecker);
+                trustedOriginDomainProvider, entityOperationChecker, dataStoreServiceRegistrator);
     }
 
     ETLService(IAuthenticationService authenticationService,
@@ -233,13 +232,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
             IPropertiesBatchManager propertiesBatchManager, ICommonBusinessObjectFactory boFactory,
             IDataStoreServiceFactory dssFactory,
             TrustedCrossOriginDomainsProvider trustedOriginDomainProvider,
-            IETLEntityOperationChecker entityOperationChecker)
+            IETLEntityOperationChecker entityOperationChecker,
+            IDataStoreServiceRegistrator dataStoreServiceRegistrator)
     {
         super(authenticationService, sessionManager, daoFactory, propertiesBatchManager, boFactory);
         this.daoFactory = daoFactory;
         this.dssFactory = dssFactory;
         this.trustedOriginDomainProvider = trustedOriginDomainProvider;
         this.entityOperationChecker = entityOperationChecker;
+        this.dataStoreServiceRegistrator = dataStoreServiceRegistrator;
 
         sessionManagerForEntityOperation =
                 new DefaultSessionManager<Session>(new SessionFactory(),
@@ -332,8 +333,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         dataStore.setRemoteUrl(dssURL);
         dataStore.setSessionToken(dssSessionToken);
         dataStore.setArchiverConfigured(info.isArchiverConfigured());
-        setServices(dataStore, info.getServicesDescriptions(), dataStoreDAO);
+        dataStore.setServices(new HashSet<DataStoreServicePE>()); // services will be set by the
+                                                                  // dataStoreServiceRegistrator
+        // setServices(dataStore, info.getServicesDescriptions(), dataStoreDAO);
         dataStoreDAO.createOrUpdateDataStore(dataStore);
+        dataStoreServiceRegistrator.setServiceDescriptions(dataStore,
+                info.getServicesDescriptions());
     }
 
     private String checkVersion(DataStoreServerInfo info, Session session, String dssSessionToken)
@@ -368,105 +373,6 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
         }
     }
 
-    private void setServices(DataStorePE dataStore, DatastoreServiceDescriptions serviceDescs,
-            IDataStoreDAO dataStoreDAO)
-    {
-        // Clean services first and save the result.
-        // In general it should happen automatically, because services are annotated with
-        // "DELETE_ORPHANS".
-        // But hibernate does the orphans deletion at the flush time, and insertion of new services
-        // is performed before.
-        // So if it happens that services with the same keys are registered, we have a unique
-        // constraint violation. This is a recognized hibernate bug HHH-2421.
-        dataStore.setServices(new HashSet<DataStoreServicePE>());
-        dataStoreDAO.createOrUpdateDataStore(dataStore);
-
-        Set<DataStoreServicePE> dataStoreServices = createDataStoreServices(serviceDescs);
-        dataStore.setServices(dataStoreServices);
-    }
-
-    private Set<DataStoreServicePE> createDataStoreServices(
-            DatastoreServiceDescriptions serviceDescriptions)
-    {
-        Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>();
-
-        Set<DataStoreServicePE> processing =
-                createDataStoreServices(serviceDescriptions.getProcessingServiceDescriptions(),
-                        DataStoreServiceKind.PROCESSING);
-        services.addAll(processing);
-
-        Set<DataStoreServicePE> queries =
-                createDataStoreServices(serviceDescriptions.getReportingServiceDescriptions(),
-                        DataStoreServiceKind.QUERIES);
-        services.addAll(queries);
-
-        return services;
-    }
-
-    private Set<DataStoreServicePE> createDataStoreServices(
-            List<DatastoreServiceDescription> serviceDescriptions, DataStoreServiceKind serviceKind)
-    {
-        Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>();
-        for (DatastoreServiceDescription desc : serviceDescriptions)
-        {
-            DataStoreServicePE service = new DataStoreServicePE();
-            service.setKey(desc.getKey());
-            service.setLabel(desc.getLabel());
-            service.setKind(serviceKind);
-            Set<DataSetTypePE> datasetTypes = extractDatasetTypes(desc.getDatasetTypeCodes(), desc);
-            service.setDatasetTypes(datasetTypes);
-            service.setReportingPluginTypeOrNull(desc.tryReportingPluginType());
-            services.add(service);
-        }
-        return services;
-    }
-
-    /**
-     * Find the data set type objects specified by the dataSetTypeCodes.
-     * 
-     * @return A set of DataSetTypePE objects.
-     */
-    private Set<DataSetTypePE> extractDatasetTypes(String[] dataSetTypeCodes,
-            DatastoreServiceDescription serviceDescription)
-    {
-        Set<DataSetTypePE> dataSetTypes = new HashSet<DataSetTypePE>();
-        Set<String> missingCodes = new HashSet<String>();
-        IDataSetTypeDAO dataSetTypeDAO = daoFactory.getDataSetTypeDAO();
-        List<DataSetTypePE> allDataSetTypes = dataSetTypeDAO.listAllEntities();
-
-        for (String dataSetTypeCode : dataSetTypeCodes)
-        {
-            boolean found = false;
-            // Try to find the specified data set type
-            for (DataSetTypePE dataSetType : allDataSetTypes)
-            {
-                if (dataSetType.getCode().matches(dataSetTypeCode))
-                {
-                    dataSetTypes.add(dataSetType);
-                    found = true;
-                }
-            }
-            if (false == found)
-            {
-                missingCodes.add(dataSetTypeCode);
-            }
-        }
-        if (missingCodes.size() > 0)
-        {
-            notifyDataStoreServerMisconfiguration(missingCodes, serviceDescription);
-        }
-        return dataSetTypes;
-    }
-
-    private void notifyDataStoreServerMisconfiguration(Set<String> missingCodes,
-            DatastoreServiceDescription serviceDescription)
-    {
-        String missingCodesText = CollectionUtils.abbreviate(missingCodes, -1);
-        notificationLog.warn(String.format("The Datastore Server Plugin '%s' is misconfigured. "
-                + "It refers to the dataset types which do not exist in openBIS: %s",
-                serviceDescription.toString(), missingCodesText));
-    }
-
     @Override
     public String createPermId(String sessionToken) throws UserFailureException
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java
new file mode 100644
index 0000000000000000000000000000000000000000..5067e2f34d333602b6e11cd7dc5460c403695791
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public interface IDataStoreServiceRegistrator
+{
+    public void setServiceDescriptions(DataStorePE dataStore,
+            DatastoreServiceDescriptions serviceDescriptions);
+
+    /**
+     * Registers for the specified data set type DSS services where the data set type code matches
+     * one of the regular expression for which the service is appropriate.
+     */
+    public void register(DataSetType dataSetType);
+
+}
diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml
index cbec61d3330253721f02de438dfabaccd5a7aee2..5bfb0df9c49e92247d150bfe7882eb8f6ea75465 100644
--- a/openbis/source/java/genericApplicationContext.xml
+++ b/openbis/source/java/genericApplicationContext.xml
@@ -93,6 +93,11 @@
     <bean id="last-modification-state"
           class="ch.systemsx.cisd.openbis.generic.shared.basic.dto.LastModificationState" />
           
+    <bean id="data-store-service-registrator" 
+          class="ch.systemsx.cisd.openbis.generic.server.DataStoreServiceRegistrator">
+        <constructor-arg ref="dao-factory" />
+    </bean>
+          
     <!-- 
         // Common
     -->
@@ -102,6 +107,7 @@
         <constructor-arg ref="session-manager" />
         <constructor-arg ref="dao-factory" />
         <constructor-arg ref="common-business-object-factory" />
+        <constructor-arg ref="data-store-service-registrator" />
         <constructor-arg ref="last-modification-state" />
         <property name="userForAnonymousLogin" value="${user-for-anonymous-login}"/>
         <property name="CISDHelpdeskEmail" value="cisd.helpdesk@bsse.ethz.ch" />
@@ -158,6 +164,7 @@
         <constructor-arg ref="dss-factory" />
         <constructor-arg ref="trusted-origin-domain-provider" />
         <constructor-arg ref="etl-entity-operation-checker" />
+        <constructor-arg ref="data-store-service-registrator" />
         <property name = "etlService" ref="etl-service" />
     </bean>
     
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
index e06ddf2d1ecfe05d728653b6ab0fff63f228629b..caa1b97a2c5d810a3967badea366ff0de59f175c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
@@ -119,12 +119,14 @@ public final class CommonServerTest extends AbstractServerTestCase
 
     private IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin;
 
+    private IDataStoreServiceRegistrator dataStoreServiceRegistrator;
+
     private final ICommonServer createServer()
     {
         CommonServer server =
                 new CommonServer(authenticationService, sessionManager, daoFactory,
                         propertiesBatchManager, commonBusinessObjectFactory,
-                        new LastModificationState());
+                        dataStoreServiceRegistrator, new LastModificationState());
         server.setSampleTypeSlaveServerPlugin(sampleTypeSlaveServerPlugin);
         server.setDataSetTypeSlaveServerPlugin(dataSetTypeSlaveServerPlugin);
         server.setBaseIndexURL(SESSION_TOKEN, BASE_INDEX_URL);
@@ -144,6 +146,7 @@ public final class CommonServerTest extends AbstractServerTestCase
         commonBusinessObjectFactory = context.mock(ICommonBusinessObjectFactory.class);
         sampleTypeSlaveServerPlugin = context.mock(ISampleTypeSlaveServerPlugin.class);
         dataSetTypeSlaveServerPlugin = context.mock(IDataSetTypeSlaveServerPlugin.class);
+        dataStoreServiceRegistrator = context.mock(IDataStoreServiceRegistrator.class);
     }
 
     @Test
@@ -1178,6 +1181,8 @@ public final class CommonServerTest extends AbstractServerTestCase
 
                     one(entityTypeBO).define(type);
                     one(entityTypeBO).save();
+
+                    one(dataStoreServiceRegistrator).register(type);
                 }
             });
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
index d395812df69745f362d5143acf87cd2b39f27dd0..9f59d97882fdb9f63dd73c126ec7610e7dfe68ee 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
@@ -30,8 +30,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
 import org.jmock.Expectations;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -39,6 +37,7 @@ import org.testng.annotations.Test;
 import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.test.RecordingMatcher;
 import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
@@ -138,6 +137,8 @@ public class ETLServiceTest extends AbstractServerTestCase
 
     private IETLEntityOperationChecker entityOperationChecker;
 
+    private IDataStoreServiceRegistrator dataStoreServiceRegistrator;
+
     @Override
     @BeforeMethod
     public final void setUp()
@@ -147,6 +148,7 @@ public class ETLServiceTest extends AbstractServerTestCase
         dssfactory = context.mock(IDataStoreServiceFactory.class);
         dataStoreService = context.mock(IDataStoreService.class);
         entityOperationChecker = context.mock(IETLEntityOperationChecker.class);
+        dataStoreServiceRegistrator = context.mock(IDataStoreServiceRegistrator.class);
         MaterialConfigurationProvider.initializeForTesting(false);
     }
 
@@ -247,10 +249,16 @@ public class ETLServiceTest extends AbstractServerTestCase
     @Test
     public void testRegisterDataStoreServer()
     {
+        final DataStoreServerInfo info = createDSSInfo();
         prepareGetSession();
+        final RecordingMatcher<DataStorePE> dataStoreRecordingMatcher =
+                new RecordingMatcher<DataStorePE>();
         context.checking(new Expectations()
             {
                 {
+                    one(dataStoreServiceRegistrator).setServiceDescriptions(
+                            with(dataStoreRecordingMatcher), with(info.getServicesDescriptions()));
+
                     one(dataStoreDAO).tryToFindDataStoreByCode(DSS_CODE);
                     will(returnValue(null));
 
@@ -260,51 +268,24 @@ public class ETLServiceTest extends AbstractServerTestCase
                     one(dataStoreService).getVersion(DSS_SESSION_TOKEN);
                     will(returnValue(IDataStoreService.VERSION));
 
-                    allowing(daoFactory).getPersistencyResources();
-                    will(returnValue(new PersistencyResources(null, null, null, null)));
-
-                    prepareFindDatasetTypes(this);
-
-                    allowing(dataStoreDAO).createOrUpdateDataStore(
-                            with(new BaseMatcher<DataStorePE>()
-                                {
-                                    @Override
-                                    public void describeTo(Description description)
-                                    {
-                                    }
-
-                                    @Override
-                                    public boolean matches(Object item)
-                                    {
-                                        if (item instanceof DataStorePE)
-                                        {
-                                            DataStorePE store = (DataStorePE) item;
-                                            return DSS_CODE.equals(store.getCode())
-                                                    && URL.equals(store.getRemoteUrl())
-                                                    && DOWNLOAD_URL.equals(store.getDownloadUrl())
-                                                    && DSS_SESSION_TOKEN.equals(store
-                                                            .getSessionToken());
-                                        }
-                                        return false;
-                                    }
-
-                                }));
+                    allowing(dataStoreDAO).createOrUpdateDataStore(with(dataStoreRecordingMatcher));
                 }
             });
 
-        createService().registerDataStoreServer(SESSION_TOKEN, createDSSInfo());
-
+        createService().registerDataStoreServer(SESSION_TOKEN, info);
+
+        List<DataStorePE> recordedObjects = dataStoreRecordingMatcher.getRecordedObjects();
+        DataStorePE store1 = recordedObjects.get(0);
+        assertEquals(DSS_CODE, store1.getCode());
+        assertEquals(URL, store1.getRemoteUrl());
+        assertEquals(DOWNLOAD_URL, store1.getDownloadUrl());
+        assertEquals(DSS_SESSION_TOKEN, store1.getSessionToken());
+        DataStorePE store2 = recordedObjects.get(1);
+        assertSame(store1, store2);
+        assertEquals(2, recordedObjects.size());
         context.assertIsSatisfied();
     }
 
-    private void prepareFindDatasetTypes(Expectations exp)
-    {
-        ArrayList<DataSetTypePE> allDataSetTypes = getAllDataSetTypes();
-
-        exp.allowing(dataSetTypeDAO).listAllEntities();
-        exp.will(Expectations.returnValue(allDataSetTypes));
-    }
-
     protected ArrayList<DataSetTypePE> getAllDataSetTypes()
     {
         // Prepare the collection of data set types
@@ -330,103 +311,70 @@ public class ETLServiceTest extends AbstractServerTestCase
     {
         final String reportingPluginTypes = ".*";
         final String processingPluginTypes = "dataSet.*";
+        final DataStoreServerInfo info =
+                createDSSInfoWithWildcards(reportingPluginTypes, processingPluginTypes);
+        final RecordingMatcher<DataStorePE> dataStoreRecordingMatcher =
+                new RecordingMatcher<DataStorePE>();
         prepareGetSession();
-        prepareGetVersion();
         context.checking(new Expectations()
             {
                 {
+                    one(dataStoreServiceRegistrator).setServiceDescriptions(
+                            with(dataStoreRecordingMatcher), with(info.getServicesDescriptions()));
+
                     one(dataStoreDAO).tryToFindDataStoreByCode(DSS_CODE);
                     will(returnValue(new DataStorePE()));
 
-                    prepareFindDatasetTypes(this);
+                    one(dssfactory).create(URL);
+                    will(returnValue(dataStoreService));
 
-                    allowing(daoFactory).getPersistencyResources();
-                    will(returnValue(new PersistencyResources(null, null, null, null)));
+                    one(dataStoreService).getVersion(DSS_SESSION_TOKEN);
+                    will(returnValue(IDataStoreService.VERSION));
 
-                    allowing(dataStoreDAO).createOrUpdateDataStore(
-                            with(new BaseMatcher<DataStorePE>()
-                                {
-                                    @Override
-                                    public void describeTo(Description description)
-                                    {
-                                    }
-
-                                    @Override
-                                    public boolean matches(Object item)
-                                    {
-                                        if (item instanceof DataStorePE)
-                                        {
-                                            DataStorePE store = (DataStorePE) item;
-                                            boolean basicMatch =
-                                                    DSS_CODE.equals(store.getCode())
-                                                            && URL.equals(store.getRemoteUrl())
-                                                            && DOWNLOAD_URL.equals(store
-                                                                    .getDownloadUrl())
-                                                            && DSS_SESSION_TOKEN.equals(store
-                                                                    .getSessionToken());
-                                            // To workaround a hibernate bug, data stores are once
-                                            // registered with no services
-                                            if (false == basicMatch
-                                                    || store.getServices().isEmpty())
-                                            {
-                                                return basicMatch;
-                                            }
-
-                                            for (DataStoreServicePE service : store.getServices())
-                                            {
-                                                // Check that the types found match those specified
-                                                if (service.getKind() == DataStoreServiceKind.PROCESSING)
-                                                {
-                                                    // expect 2 matches
-                                                    if (false == isDataSetTypeMatch(service,
-                                                            processingPluginTypes, 2))
-                                                    {
-                                                        return false;
-                                                    }
-                                                }
-                                                if (service.getKind() == DataStoreServiceKind.QUERIES)
-                                                {
-                                                    // expect 3 matches
-                                                    if (false == isDataSetTypeMatch(service,
-                                                            reportingPluginTypes, 3))
-                                                    {
-                                                        return false;
-                                                    }
-                                                }
-                                            }
-
-                                            return true;
-                                        }
-                                        return false;
-                                    }
-
-                                    private boolean isDataSetTypeMatch(DataStoreServicePE service,
-                                            String typeRegex, int numberExpected)
-                                    {
-                                        Set<DataSetTypePE> datasetTypes = service.getDatasetTypes();
-                                        if (datasetTypes.isEmpty())
-                                        {
-                                            return false;
-                                        }
-                                        for (DataSetTypePE types : datasetTypes)
-                                        {
-                                            if (false == types.getCode().matches(typeRegex))
-                                            {
-                                                return false;
-                                            }
-                                        }
-                                        return datasetTypes.size() == numberExpected;
-                                    }
-
-                                }));
+                    allowing(dataStoreDAO).createOrUpdateDataStore(with(dataStoreRecordingMatcher));
                 }
             });
-        createService().registerDataStoreServer(SESSION_TOKEN,
-                createDSSInfoWithWildcards(reportingPluginTypes, processingPluginTypes));
 
+        createService().registerDataStoreServer(SESSION_TOKEN, info);
+
+        List<DataStorePE> recordedObjects = dataStoreRecordingMatcher.getRecordedObjects();
+        DataStorePE store1 = recordedObjects.get(0);
+        assertEquals(DSS_CODE, store1.getCode());
+        assertEquals(URL, store1.getRemoteUrl());
+        assertEquals(DOWNLOAD_URL, store1.getDownloadUrl());
+        assertEquals(DSS_SESSION_TOKEN, store1.getSessionToken());
+        for (DataStoreServicePE service : store1.getServices())
+        {
+            // Check that the types found match those specified
+            if (service.getKind() == DataStoreServiceKind.PROCESSING)
+            {
+                // expect 2 matches
+                assertDataSetTypeMatch(service, processingPluginTypes, 2);
+            }
+            if (service.getKind() == DataStoreServiceKind.QUERIES)
+            {
+                // expect 3 matches
+                assertDataSetTypeMatch(service, reportingPluginTypes, 3);
+            }
+        }
+        DataStorePE store2 = recordedObjects.get(1);
+        assertSame(store1, store2);
+        assertEquals(2, recordedObjects.size());
         context.assertIsSatisfied();
     }
 
+    private void assertDataSetTypeMatch(DataStoreServicePE service, String typeRegex,
+            int numberExpected)
+    {
+        Set<DataSetTypePE> datasetTypes = service.getDatasetTypes();
+        for (DataSetTypePE types : datasetTypes)
+        {
+            assertEquals("'" + types.getCode() + "' doesnot match '" + typeRegex + "'.", true,
+                    types.getCode().matches(typeRegex));
+        }
+        assertEquals(numberExpected, datasetTypes.size());
+    }
+
     @Test
     public void testRegisterDataStoreServerWithWrongVersion()
     {
@@ -447,11 +395,6 @@ public class ETLServiceTest extends AbstractServerTestCase
         context.assertIsSatisfied();
     }
 
-    private void prepareGetVersion()
-    {
-        prepareGetVersion(VERSION);
-    }
-
     private void prepareGetVersion(final int version)
     {
         context.checking(new Expectations()
@@ -1424,7 +1367,8 @@ public class ETLServiceTest extends AbstractServerTestCase
     private IETLLIMSService createService()
     {
         return new ETLService(authenticationService, sessionManager, daoFactory,
-                propertiesBatchManager, boFactory, dssfactory, null, entityOperationChecker);
+                propertiesBatchManager, boFactory, dssfactory, null, entityOperationChecker,
+                dataStoreServiceRegistrator);
     }
 
     private DataStoreServerInfo createDSSInfo()