diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java
deleted file mode 100644
index 469e743854bcde173a3ce66dbbeab40aa3edced9..0000000000000000000000000000000000000000
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright 2010 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.etlserver.api.v1;
-
-import java.io.File;
-import java.util.concurrent.locks.Lock;
-
-import org.apache.log4j.Logger;
-
-import ch.systemsx.cisd.common.filesystem.FileOperations;
-import ch.systemsx.cisd.common.filesystem.IFileOperations;
-import ch.systemsx.cisd.common.mail.IMailClient;
-import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult;
-import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm;
-import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor;
-import ch.systemsx.cisd.etlserver.IDataStrategyStore;
-import ch.systemsx.cisd.etlserver.IETLServerPlugin;
-import ch.systemsx.cisd.etlserver.IStorageProcessor;
-import ch.systemsx.cisd.etlserver.ITypeExtractor;
-import ch.systemsx.cisd.etlserver.validation.IDataSetValidator;
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
-
-/**
- * @author Chandrasekhar Ramakrishnan
- */
-class DataSetRegistrationHelper extends DataSetRegistrationAlgorithm
-{
-
-    private final PutDataSetService service;
-
-    private final IETLServerPlugin plugin;
-
-    /**
-     * @param incomingDataSetFile
-     * @param cleanAftrewardsAction
-     */
-    public DataSetRegistrationHelper(PutDataSetService service, IETLServerPlugin plugin,
-            File incomingDataSetFile, IDelegatedActionWithResult<Boolean> cleanAftrewardsAction)
-    {
-        super(incomingDataSetFile, cleanAftrewardsAction);
-        this.service = service;
-        this.plugin = plugin;
-    }
-
-    @Override
-    protected IDataSetInfoExtractor getDataSetInfoExtractor()
-    {
-        return plugin.getDataSetInfoExtractor();
-    }
-
-    @Override
-    protected IDataSetValidator getDataSetValidator()
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    protected String getDataStoreCode()
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    protected IDataStrategyStore getDataStrategyStore()
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    protected String getEmailSubjectTemplate()
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    protected IFileOperations getFileOperations()
-    {
-        return FileOperations.getMonitoredInstanceForCurrentThread();
-    }
-
-    @Override
-    protected DatabaseInstance getHomeDatabaseInstance()
-    {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    protected IMailClient getMailClient()
-    {
-        return service.getMailClient();
-    }
-
-    @Override
-    protected Logger getNotificationLog()
-    {
-        return service.getOperationLog();
-    }
-
-    @Override
-    protected IEncapsulatedOpenBISService getOpenBisService()
-    {
-        return service.getOpenBisService();
-    }
-
-    @Override
-    protected Logger getOperationLog()
-    {
-        return service.getOperationLog();
-    }
-
-    @Override
-    protected Lock getRegistrationLock()
-    {
-        return service.getRegistrationLock();
-    }
-
-    @Override
-    protected IStorageProcessor getStorageProcessor()
-    {
-        return plugin.getStorageProcessor();
-    }
-
-    @Override
-    protected ITypeExtractor getTypeExtractor()
-    {
-        return plugin.getTypeExtractor();
-    }
-
-    @Override
-    protected void rollback(Throwable ex)
-    {
-        rollbackStorageProcessor(ex);
-    }
-
-    @Override
-    protected boolean shouldDeleteUnidentified()
-    {
-        return true;
-    }
-
-    @Override
-    protected boolean shouldNotifySuccessfulRegistration()
-    {
-        return false;
-    }
-
-}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
index 7b4f1d761f4a8eb4338dba929fedc01c394ec41b..9e36df1baca29baa393a2b3ad2e0fc99e1447fcb 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
@@ -23,19 +23,33 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.concurrent.locks.Lock;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.filesystem.FileOperations;
+import ch.systemsx.cisd.common.filesystem.IFileOperations;
 import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter;
+import ch.systemsx.cisd.common.mail.IMailClient;
+import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult;
+import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm;
+import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor;
+import ch.systemsx.cisd.etlserver.IDataStrategyStore;
 import ch.systemsx.cisd.etlserver.IETLServerPlugin;
+import ch.systemsx.cisd.etlserver.IStorageProcessor;
+import ch.systemsx.cisd.etlserver.ITypeExtractor;
+import ch.systemsx.cisd.etlserver.TransferredDataSetHandler;
+import ch.systemsx.cisd.etlserver.validation.IDataSetValidator;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
@@ -72,6 +86,10 @@ class PutDataSetExecutor
         this.newDataSet = newDataSet;
         this.inputStream = inputStream;
         this.dataSetDir = new File(service.getIncomingDir(), newDataSet.getDataSetFolderName());
+        if (dataSetDir.exists())
+        {
+            deleteDataSetDir();
+        }
         if (false == this.dataSetDir.mkdir())
         {
             throw new EnvironmentFailureException("Could not create directory for data set "
@@ -94,16 +112,25 @@ class PutDataSetExecutor
 
         writeDataSetToTempDirectory();
 
-        // TODO: When registering, set the registrator to the session owner; only an admin on
-        // the space or an ETL server can override.
-
-        // Register data set
-        DataSetRegistrationHelper helper =
-                new DataSetRegistrationHelper(service, plugin, dataSetDir, null);
-        helper.prepare();
-        helper.registerDataSet();
-
-        deleteDataSetDir();
+        // Register the data set
+        try
+        {
+            DataSetRegistrationHelper helper =
+                    new DataSetRegistrationHelper(service, plugin, dataSetDir);
+            helper.prepare();
+            if (helper.hasDataSetBeenIdentified())
+            {
+                helper.registerDataSet();
+            } else
+            {
+                helper.dealWithUnidentifiedDataSet();
+                throw new UserFailureException("Could not find owner:\n\t"
+                        + newDataSet.getDataSetOwner() + "\nfor data set:\n\t" + newDataSet);
+            }
+        } finally
+        {
+            deleteDataSetDir();
+        }
     }
 
     private void writeDataSetToTempDirectory() throws IOException
@@ -114,6 +141,8 @@ class PutDataSetExecutor
         {
             OutputStream output = getOutputStream(fileInfo);
             imagesWriter.writeNextBlock(output);
+            output.flush();
+            output.close();
         }
     }
 
@@ -148,24 +177,65 @@ class PutDataSetExecutor
 
     private SpaceIdentifier getSpaceIdentifierForNewDataSet()
     {
-        SpaceIdentifier spaceId;
+        SpaceIdentifier spaceId = null;
         DataSetOwner owner = newDataSet.getDataSetOwner();
-        if (DataSetOwnerType.EXPERIMENT == owner.getType())
-        {
-            ExperimentIdentifier experimentId =
-                    new ExperimentIdentifierFactory(owner.getIdentifier()).createIdentifier();
-            spaceId =
-                    new SpaceIdentifier(experimentId.getDatabaseInstanceCode(), experimentId
-                            .getSpaceCode());
-        } else
+        switch (owner.getType())
         {
-            SampleIdentifier sampleId =
-                    new SampleIdentifierFactory(owner.getIdentifier()).createIdentifier();
-            spaceId = sampleId.getSpaceLevel();
+            case EXPERIMENT:
+            {
+                ExperimentIdentifier experimentId = tryExperimentIdentifier();
+                spaceId =
+                        new SpaceIdentifier(experimentId.getDatabaseInstanceCode(), experimentId
+                                .getSpaceCode());
+                break;
+            }
+            case SAMPLE:
+            {
+                SampleIdentifier sampleId = trySampleIdentifier();
+                spaceId = sampleId.getSpaceLevel();
+                break;
+            }
         }
         return spaceId;
     }
 
+    private ExperimentIdentifier tryExperimentIdentifier()
+    {
+        DataSetOwner owner = newDataSet.getDataSetOwner();
+        switch (owner.getType())
+        {
+            case EXPERIMENT:
+            {
+                return new ExperimentIdentifierFactory(owner.getIdentifier()).createIdentifier();
+            }
+            case SAMPLE:
+            {
+                return null;
+            }
+        }
+
+        return null;
+    }
+
+    private SampleIdentifier trySampleIdentifier()
+    {
+        DataSetOwner owner = newDataSet.getDataSetOwner();
+        switch (owner.getType())
+        {
+            case EXPERIMENT:
+            {
+                return null;
+            }
+            case SAMPLE:
+            {
+                return new SampleIdentifierFactory(owner.getIdentifier()).createIdentifier();
+
+            }
+        }
+
+        return null;
+    }
+
     private IEncapsulatedOpenBISService getOpenBisService()
     {
         return service.getOpenBisService();
@@ -175,4 +245,175 @@ class PutDataSetExecutor
     {
         return service.getOperationLog();
     }
+
+    private static class CleanAfterwardsAction implements IDelegatedActionWithResult<Boolean>
+    {
+        public Boolean execute()
+        {
+            return true; // do nothing
+        }
+    }
+
+    /**
+     * An implementation of the registration algorithm that gets its state from the executor.
+     * 
+     * @author Chandrasekhar Ramakrishnan
+     */
+    private class DataSetRegistrationHelper extends DataSetRegistrationAlgorithm
+    {
+        /**
+         * @param service The provider of global state for the data set registration algorithm
+         * @param plugin The provider of the storage processor
+         * @param incomingDataSetFile The data set to register
+         */
+        public DataSetRegistrationHelper(PutDataSetService service, IETLServerPlugin plugin,
+                File incomingDataSetFile)
+        {
+            super(incomingDataSetFile, new CleanAfterwardsAction());
+        }
+
+        @Override
+        protected IDataSetInfoExtractor getDataSetInfoExtractor()
+        {
+            return plugin.getDataSetInfoExtractor();
+        }
+
+        @Override
+        protected IDataSetValidator getDataSetValidator()
+        {
+            return service.getDataSetValidator();
+        }
+
+        @Override
+        protected String getDataStoreCode()
+        {
+            return service.getDataStoreCode();
+        }
+
+        @Override
+        protected IDataStrategyStore getDataStrategyStore()
+        {
+            return service.getDataStrategyStore();
+        }
+
+        @Override
+        protected String getEmailSubjectTemplate()
+        {
+            return TransferredDataSetHandler.EMAIL_SUBJECT_TEMPLATE;
+        }
+
+        @Override
+        protected IFileOperations getFileOperations()
+        {
+            return FileOperations.getMonitoredInstanceForCurrentThread();
+        }
+
+        @Override
+        protected DatabaseInstance getHomeDatabaseInstance()
+        {
+            return service.getHomeDatabaseInstance();
+        }
+
+        @Override
+        protected IMailClient getMailClient()
+        {
+            return service.getMailClient();
+        }
+
+        @Override
+        protected Logger getNotificationLog()
+        {
+            return service.getOperationLog();
+        }
+
+        @Override
+        protected IEncapsulatedOpenBISService getOpenBisService()
+        {
+            return service.getOpenBisService();
+        }
+
+        @Override
+        protected Logger getOperationLog()
+        {
+            return service.getOperationLog();
+        }
+
+        @Override
+        protected Lock getRegistrationLock()
+        {
+            return service.getRegistrationLock();
+        }
+
+        @Override
+        protected IStorageProcessor getStorageProcessor()
+        {
+            return plugin.getStorageProcessor();
+        }
+
+        @Override
+        protected ITypeExtractor getTypeExtractor()
+        {
+            return plugin.getTypeExtractor();
+        }
+
+        @Override
+        protected void rollback(Throwable ex)
+        {
+            rollbackStorageProcessor(ex);
+            if (ex instanceof UserFailureException)
+            {
+                throw (UserFailureException) ex;
+            }
+            throw new EnvironmentFailureException("Could not register data set " + newDataSet, ex);
+        }
+
+        @Override
+        protected boolean shouldDeleteUnidentified()
+        {
+            return true;
+        }
+
+        @Override
+        protected boolean shouldNotifySuccessfulRegistration()
+        {
+            return false;
+        }
+
+        @Override
+        protected DataSetInformation extractDataSetInformation(final File incomingDataSetPath)
+        {
+            DataSetInformation dataSetInfo = super.extractDataSetInformation(incomingDataSetPath);
+            if (null == dataSetInfo)
+            {
+                return dataSetInfo;
+            }
+            DataSetOwner owner = newDataSet.getDataSetOwner();
+            switch (owner.getType())
+            {
+                case EXPERIMENT:
+                    dataSetInfo.setExperimentIdentifier(tryExperimentIdentifier());
+                    break;
+                case SAMPLE:
+                    SampleIdentifier sampleId = trySampleIdentifier();
+
+                    dataSetInfo.setSampleCode(sampleId.getSampleCode());
+                    dataSetInfo.setSpaceCode(sampleId.getSpaceLevel().getSpaceCode());
+                    dataSetInfo.setInstanceCode(sampleId.getSpaceLevel().getDatabaseInstanceCode());
+                    break;
+            }
+
+            // TODO: Get the session owner's email address from OpenBIS
+            // dataSetInfo.setUploadingUserEmail()
+
+            // TODO: When registering, set the registrator to the session owner; only an admin on
+            // the space or an ETL server can override.
+            return dataSetInfo;
+        }
+
+        @Override
+        protected DataSetType extractDataSetType()
+        {
+            return new DataSetType(newDataSet.getDataSetType());
+        }
+    }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java
index 849baa5468ef09c71daea18a3005a6c9a91b8379..a5323289a196e44644f740c15cbcffdca8460509 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java
@@ -32,8 +32,12 @@ import ch.systemsx.cisd.etlserver.DataStrategyStore;
 import ch.systemsx.cisd.etlserver.IETLServerPlugin;
 import ch.systemsx.cisd.etlserver.Parameters;
 import ch.systemsx.cisd.etlserver.ThreadParameters;
+import ch.systemsx.cisd.etlserver.validation.DataSetValidator;
+import ch.systemsx.cisd.etlserver.validation.IDataSetValidator;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
+import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
 
 /**
  * Helper class that maintains the state for handling put requests. The requests themselves are
@@ -51,6 +55,12 @@ public class PutDataSetService
 
     private final DataStrategyStore dataStrategyStore;
 
+    // These are all initialized only once, but it is not possible to initialize them at
+    // construction time, since this causes a dependency loop that causes problems in Spring.
+    private File storeDirectory;
+
+    private String dataStoreCode;
+
     private boolean isInitialized = false;
 
     private MailClient mailClient;
@@ -59,6 +69,10 @@ public class PutDataSetService
 
     private File incomingDir;
 
+    private IDataSetValidator dataSetValidator;
+
+    private DatabaseInstance homeDatabaseInstance;
+
     public PutDataSetService(IEncapsulatedOpenBISService openBisService, Logger operationLog)
     {
         this.openBisService = openBisService;
@@ -80,7 +94,6 @@ public class PutDataSetService
         try
         {
             new PutDataSetExecutor(this, plugin, sessionToken, newDataSet, inputStream).execute();
-
         } catch (UserFailureException e)
         {
             throw new IllegalArgumentException(e);
@@ -108,9 +121,16 @@ public class PutDataSetService
         incomingDir.mkdir();
 
         plugin = initializer.getPlugin();
+        plugin.getStorageProcessor().setStoreRootDirectory(storeDirectory);
 
         mailClient = new MailClient(initializer.getMailProperties());
 
+        this.dataStoreCode = initializer.getDataStoreCode();
+
+        homeDatabaseInstance = openBisService.getHomeDatabaseInstance();
+
+        dataSetValidator = initializer.getDataSetValidator();
+
         isInitialized = true;
     }
 
@@ -134,16 +154,41 @@ public class PutDataSetService
         return operationLog;
     }
 
-    public Lock getRegistrationLock()
+    Lock getRegistrationLock()
     {
         return registrationLock;
     }
 
-    public DataStrategyStore getDataStrategyStore()
+    DataStrategyStore getDataStrategyStore()
     {
         return dataStrategyStore;
     }
 
+    String getDataStoreCode()
+    {
+        return dataStoreCode;
+    }
+
+    IDataSetValidator getDataSetValidator()
+    {
+        return dataSetValidator;
+    }
+
+    DatabaseInstance getHomeDatabaseInstance()
+    {
+        return homeDatabaseInstance;
+    }
+
+    public File getStoreRootDirectory()
+    {
+        return storeDirectory;
+    }
+
+    public void setStoreDirectory(File storeDirectory)
+    {
+        this.storeDirectory = storeDirectory;
+    }
+
 }
 
 /**
@@ -176,4 +221,13 @@ class PutDataSetServiceInitializer
         return threadParams[0].getPlugin();
     }
 
+    String getDataStoreCode()
+    {
+        return DssPropertyParametersUtil.getDataStoreCode(params.getProperties());
+    }
+
+    DataSetValidator getDataSetValidator()
+    {
+        return new DataSetValidator(params.getProperties());
+    }
 }