diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java
index c2f10063a36d7b37deb2ae77f47ccd142ae613d1..8df3a40319bbfc7cf2f22b7bd625ec7dfa3736cd 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java
@@ -165,9 +165,15 @@ class UploadingCommand implements IDataSetCommand
             zipOutputStream = new ZipOutputStream(outputStream);
             for (String location : dataSetLocations)
             {
+                File dataSetFile = new File(store, location);
+                if (dataSetFile.exists() == false)
+                {
+                    notificationLog.error("Data set '" + location + "' does not exist.");
+                    return false;
+                }
                 try
                 {
-                    addTo(zipOutputStream, rootPath, new File(store, location));
+                    addTo(zipOutputStream, rootPath, dataSetFile);
                 } catch (IOException ex)
                 {
                     notificationLog.error("Couldn't add data set '" + location + "' to zip file.",
@@ -236,7 +242,7 @@ class UploadingCommand implements IDataSetCommand
         String smtpUser = mailClientParameters.getSmtpUser();
         String smtpPassword = mailClientParameters.getSmtpPassword();
         IMailClient mailClient = new MailClient(from, smtpHost, smtpUser, smtpPassword);
-        mailClient.sendMessage("[Data Set Server] Uploading failed", message, "", userEMail);
+        mailClient.sendMessage("[Data Set Server] Uploading failed", message, null, userEMail);
     }
 
 }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..34bc8e84a78b46a5cd6ea4761a24df0f47255181
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommandTest.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2009 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.dss.generic.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.log4j.Level;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.base.utilities.OSUtilities;
+import ch.systemsx.cisd.cifex.rpc.ICIFEXRPCService;
+import ch.systemsx.cisd.cifex.rpc.UploadState;
+import ch.systemsx.cisd.cifex.rpc.UploadStatus;
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.logging.BufferedAppender;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class UploadingCommandTest extends AssertJUnit
+{
+    private static final String INFO_UPLOAD_PREFIX = "INFO  OPERATION.UploadingCommand - ";
+    private static final String WARN_UPLOAD_PREFIX = "WARN  OPERATION.UploadingCommand - ";
+    private static final String INFO_MAIL_PREFIX = "INFO  OPERATION.MailClient - ";
+
+    private static final class ZipFileMatcher extends BaseMatcher<String[]>
+    {
+        private final List<String> expectedPaths;
+        
+        private String msg;
+
+        ZipFileMatcher(File... dataSets)
+        {
+            expectedPaths = new ArrayList<String>();
+            for (File file : dataSets)
+            {
+                addPaths(expectedPaths, file);
+            }
+            Collections.sort(expectedPaths);
+        }
+        
+        private void addPaths(List<String> paths, File file)
+        {
+            if (file.isFile())
+            {
+                paths.add(file.getPath().substring(STORE.getPath().length() + 1));
+            } else
+            {
+                File[] files = file.listFiles();
+                for (File child : files)
+                {
+                    addPaths(paths, child);
+                }
+            }
+        }
+        
+        public void describeTo(Description description)
+        {
+            description.appendText(msg);
+        }
+
+        public boolean matches(Object item)
+        {
+            String[] paths = (String[]) item;
+            if (paths.length != 1)
+            {
+                msg = "not one path but " + paths.length;
+                return false;
+            }
+            String zipFile = paths[0];
+            if (zipFile.endsWith(".zip") == false)
+            {
+                msg = "not a zip file: " + zipFile;
+                return false;
+            }
+            return checkContent(zipFile);
+        }
+        
+        private boolean checkContent(String file)
+        {
+            ZipFile zipFile = null;
+            try
+            {
+                List<String> paths = new ArrayList<String>();
+                zipFile = new ZipFile(file);
+                for (Enumeration<? extends ZipEntry> entries = zipFile.entries(); entries.hasMoreElements(); )
+                {
+                    ZipEntry entry = entries.nextElement();
+                    String name = entry.getName();
+                    paths.add(name);
+                }
+                Collections.sort(paths);
+                if (expectedPaths.equals(paths))
+                {
+                    return true;
+                }
+                msg = "Expected:\n" + expectedPaths + "\nActual:\n" + paths;
+            } catch (Exception ex)
+            {
+                ex.printStackTrace();
+                msg = ex.toString();
+            } finally
+            {
+                if (zipFile != null)
+                {
+                    try
+                    {
+                        zipFile.close();
+                    } catch (IOException ex)
+                    {
+                        // ignored
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    private static final File TEST_FOLDER = new File("targets/upload-test");
+    private static final File STORE = new File(TEST_FOLDER, "store");
+    private static final File TMP = new File(STORE, "tmp");
+    private static final File EMAILS = new File(TEST_FOLDER, "emails");
+    private static final String LOCATION1 = "ds1";
+    private static final String LOCATION2 = "ds2";
+    private static final String SESSION_TOKEN = "session42";
+    
+    private BufferedAppender logRecorder;
+    private Mockery context;
+    private ICIFEXRPCServiceFactory factory;
+    private ICIFEXRPCService cifexService;
+    private MailClientParameters mailClientParameters;
+    private DataSetUploadContext uploadContext;
+    private UploadingCommand command;
+    private File ds1;
+    private File ds2;
+
+    @BeforeMethod
+    public void setup()
+    {
+        logRecorder = new BufferedAppender("%-5p %c - %m%n", Level.INFO);
+        context = new Mockery();
+        factory = context.mock(ICIFEXRPCServiceFactory.class);
+        cifexService = context.mock(ICIFEXRPCService.class);
+        mailClientParameters = new MailClientParameters();
+        mailClientParameters.setFrom("a@bc.de");
+        mailClientParameters.setSmtpHost("file://" + EMAILS);
+        FileUtilities.deleteRecursively(TEST_FOLDER);
+        STORE.mkdirs();
+        uploadContext = new DataSetUploadContext();
+        uploadContext.setCifexURL("cifexURL");
+        uploadContext.setUserID("user");
+        uploadContext.setPassword("pwd");
+        uploadContext.setUserEMail("user@bc.de");
+        List<String> locations = Arrays.asList(LOCATION1, LOCATION2);
+        ds1 = createTestData(LOCATION1);
+        ds2 = createTestData(LOCATION2);
+        command = new UploadingCommand(factory, mailClientParameters, locations, uploadContext);
+    }
+    
+    private File createTestData(String location)
+    {
+        File dataSet = new File(STORE, location);
+        dataSet.mkdir();
+        FileUtilities.writeToFile(new File(dataSet, "README.TXT"), "Data set " + location);
+        File dataFolder = new File(dataSet, "data");
+        dataFolder.mkdir();
+        FileUtilities.writeToFile(new File(dataFolder, "data.txt"), "1 2 3 for " + location);
+        return dataSet;
+    }
+    
+    private void checkEmail(String messageStart)
+    {
+        File[] emails = EMAILS.listFiles();
+        assertEquals("One email expected", 1, emails.length);
+        List<String> email = FileUtilities.loadToStringList(emails[0]);
+        assertEquals("Subj: [Data Set Server] Uploading failed", email.get(0));
+        assertEquals("From: a@bc.de", email.get(1));
+        assertEquals("To:   user@bc.de", email.get(2));
+        assertTrue("Actual: " + email.get(5), email.get(5).startsWith(messageStart));
+    }
+    
+    private String getNormalizedLogContent()
+    {
+        return logRecorder.getLogContent().replaceAll(" [^ ]*\\.zip", " <zipfile>");
+    }
+    
+    @AfterMethod
+    public void tearDown()
+    {
+        logRecorder.reset();
+        // To following line of code should also be called at the end of each test method.
+        // Otherwise one do not known which test failed.
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testExecute()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(factory).createService();
+                    will(returnValue(cifexService));
+                    
+                    one(cifexService).login(uploadContext.getUserID(), uploadContext.getPassword());
+                    will(returnValue(SESSION_TOKEN));
+                    
+                    allowing(cifexService).getVersion();
+                    will(returnValue(ICIFEXRPCService.VERSION));
+                    
+                    one(cifexService).checkSession(SESSION_TOKEN);
+                    
+                    one(cifexService).getUploadStatus(SESSION_TOKEN);
+                    UploadStatus uploadStatus = new UploadStatus();
+                    uploadStatus.setUploadState(UploadState.INITIALIZED);
+                    will(returnValue(uploadStatus));
+                    
+                    one(cifexService).defineUploadParameters(with(equal(SESSION_TOKEN)),
+                            with(new ZipFileMatcher(ds1, ds2)), with(equal("id:user")),
+                            with(aNull(String.class)));
+                    
+                    one(cifexService).getUploadStatus(SESSION_TOKEN);
+                    uploadStatus = new UploadStatus();
+                    uploadStatus.setUploadState(UploadState.FINISHED);
+                    will(returnValue(uploadStatus));
+                    
+                    one(cifexService).finish(SESSION_TOKEN, true);
+                }
+            });
+        
+        logRecorder.resetLogContent();
+        command.execute(STORE);
+        
+        assertEquals("no emails expected", false, EMAILS.exists());
+        assertEquals("Empty tmp folder expected", 0, TMP.listFiles().length);
+        assertEquals(INFO_UPLOAD_PREFIX
+                + "Zip file <zipfile> with 2 data sets has been successfully created."
+                + OSUtilities.LINE_SEPARATOR + INFO_UPLOAD_PREFIX
+                + "Zip file <zipfile> has been successfully uploaded.", getNormalizedLogContent());        
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testExecuteWithFailedZipFileCreation()
+    {
+        FileUtilities.deleteRecursively(ds2);
+        command.execute(STORE);
+    
+        checkEmail("Couldn't create zip file");
+        assertEquals("Empty tmp folder expected", 0, TMP.listFiles().length);
+        assertEquals("ERROR NOTIFY.UploadingCommand - Data set 'ds2' does not exist."
+                + OSUtilities.LINE_SEPARATOR + INFO_MAIL_PREFIX
+                + "Sending message from 'a@bc.de' to recipients '[user@bc.de]'",
+                getNormalizedLogContent());        
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testExecuteWithFailedUpload()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    one(factory).createService();
+                    will(returnValue(cifexService));
+
+                    one(cifexService).login(uploadContext.getUserID(), uploadContext.getPassword());
+                    will(returnValue(SESSION_TOKEN));
+
+                    allowing(cifexService).getVersion();
+                    will(returnValue(ICIFEXRPCService.VERSION));
+
+                    one(cifexService).checkSession(SESSION_TOKEN);
+
+                    one(cifexService).getUploadStatus(SESSION_TOKEN);
+                    UploadStatus uploadStatus = new UploadStatus();
+                    uploadStatus.setUploadState(UploadState.ABORTED);
+                    will(returnValue(uploadStatus));
+
+                    one(cifexService).finish(SESSION_TOKEN, false);
+                }
+            });
+
+        command.execute(STORE);
+        
+        checkEmail("Uploading of zip file");
+        assertEquals("Empty tmp folder expected", 0, TMP.listFiles().length);
+        assertEquals(INFO_UPLOAD_PREFIX
+                + "Zip file <zipfile> with 2 data sets has been successfully created."
+                + OSUtilities.LINE_SEPARATOR + WARN_UPLOAD_PREFIX
+                + "Uploading of zip file <zipfile> has been aborted or failed."
+                + OSUtilities.LINE_SEPARATOR + INFO_MAIL_PREFIX
+                + "Sending message from 'a@bc.de' to recipients '[user@bc.de]'",
+                getNormalizedLogContent());        
+        context.assertIsSatisfied();
+    }
+}