diff --git a/datastore_server/.classpath b/datastore_server/.classpath
index a8761230b090677691d7476bfe0302f72e3b5a7c..02d5a51470eca3fb2ad7ea1dd745c7bbc4a1ea20 100644
--- a/datastore_server/.classpath
+++ b/datastore_server/.classpath
@@ -51,5 +51,7 @@
 	<classpathentry kind="lib" path="/libraries/jai/jai_core.jar"/>
 	<classpathentry kind="lib" path="/libraries/spring/spring-aop.jar" sourcepath="/libraries/spring/src.jar"/>
 	<classpathentry kind="lib" path="/libraries/jhdf5/cisd-jhdf5-batteries_included_lin_win_mac.jar" sourcepath="/libraries/jhdf5/cisd-jhdf5-src.zip"/>
+	<classpathentry kind="lib" path="/libraries/spring/test/spring-test.jar" sourcepath="/libraries/spring/test/src.jar"/>
+	<classpathentry kind="lib" path="/libraries/spring/webmvc/spring-webmvc.jar" sourcepath="/libraries/spring/webmvc/src.jar"/>
 	<classpathentry kind="output" path="targets/classes"/>
 </classpath>
diff --git a/datastore_server/etc/service.properties b/datastore_server/etc/service.properties
index ffe80ed617f438ffeef43720f5de93875ca86139..cc8108eb51c342cb4ecaf3b1028b1414a988435f 100644
--- a/datastore_server/etc/service.properties
+++ b/datastore_server/etc/service.properties
@@ -1,11 +1,13 @@
 # Unique code of this Data Store Server. Not more than 40 characters.
 data-store-server-code = standard
 
+root-dir = targets
+
 # The root directory of the data store
-storeroot-dir = targets/store
+storeroot-dir = ${root-dir}/store
 
 # The directory for incoming files over rpc
-rpc-incoming-dir = targets/incoming-rpc
+rpc-incoming-dir = ${root-dir}/incoming-rpc
 
 # The directory where the command queue file is located; defaults to storeroot-dir 
 commandqueue-dir =
@@ -70,7 +72,7 @@ cifex-admin-password =
 download-url = http://localhost:8889
 
 # SMTP properties (must start with 'mail' to be considered).
-mail.smtp.host = file://targets/email
+mail.smtp.host = file://${root-dir}/email
 mail.from = datastore_server@localhost
 mail.smtp.user = 
 mail.smtp.password = 
@@ -173,14 +175,14 @@ validator.site.value-range = [0,Infinity)
 
 # Comma separated names of processing threads. Each thread should have configuration properties prefixed with its name.
 # E.g. 'code-extractor' property for the thread 'my-etl' should be specified as 'my-etl.code-extractor'
-inputs=main-thread, tsv-thread, csv-thread, simple-thread, hdf5-thread
+inputs=main-thread, tsv-thread, csv-thread, simple-thread, hdf5-thread, dss-system-test-thread
 
 # ---------------------------------------------------------------------------
 # Dataset uploader 'main-thread' configuration
 # ---------------------------------------------------------------------------
 
 # The directory to watch for incoming data.
-main-thread.incoming-dir = targets/incoming
+main-thread.incoming-dir = ${root-dir}/incoming
 
 # Specifies what should happen if an error occurs during dataset processing. 
 # By default this flag is set to false and user has to modify the 'faulty paths file' 
@@ -225,7 +227,7 @@ main-thread.storage-processor.well_geometry = 3x3
 main-thread.storage-processor.file-extractor = ch.systemsx.cisd.etlserver.imsb.HCSImageFileExtractor
 
 # The directory to watch for incoming data.
-tsv-thread.incoming-dir = targets/incoming-tsv
+tsv-thread.incoming-dir = ${root-dir}/incoming-tsv
 tsv-thread.incoming-data-completeness-condition = auto-detection
 tsv-thread.strip-file-extension = true
 tsv-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor
@@ -243,7 +245,7 @@ tsv-thread.type-extractor.file-format-type = TSV
 tsv-thread.type-extractor.locator-type = RELATIVE_LOCATION
 tsv-thread.type-extractor.data-set-type = TSV
 
-csv-thread.incoming-dir = targets/incoming-csv
+csv-thread.incoming-dir = ${root-dir}/incoming-csv
 csv-thread.incoming-data-completeness-condition = auto-detection
 csv-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor
 # The extractor plugin class to use for code extraction
@@ -260,7 +262,7 @@ csv-thread.type-extractor.locator-type = RELATIVE_LOCATION
 csv-thread.type-extractor.data-set-type = CSV
 
 # The directory to watch for incoming data.
-simple-thread.incoming-dir = targets/incoming-simple
+simple-thread.incoming-dir = ${root-dir}/incoming-simple
 simple-thread.incoming-data-completeness-condition = auto-detection
 simple-thread.strip-file-extension = true
 simple-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor
@@ -277,7 +279,7 @@ simple-thread.type-extractor.locator-type = RELATIVE_LOCATION
 simple-thread.type-extractor.data-set-type = HCS_IMAGE
 
 # The directory to watch for incoming data.
-hdf5-thread.incoming-dir = targets/incoming-hdf5
+hdf5-thread.incoming-dir = ${root-dir}/incoming-hdf5
 hdf5-thread.incoming-data-completeness-condition = auto-detection
 hdf5-thread.strip-file-extension = true
 hdf5-thread.storage-processor = ch.systemsx.cisd.etlserver.hdf5.Hdf5StorageProcessor
@@ -293,6 +295,24 @@ hdf5-thread.type-extractor.file-format-type = HDF5
 hdf5-thread.type-extractor.locator-type = RELATIVE_LOCATION
 hdf5-thread.type-extractor.data-set-type = HCS_IMAGE
 
+dss-system-test-thread.incoming-dir = ${root-dir}/incoming-simple
+dss-system-test-thread.incoming-data-completeness-condition = auto-detection
+dss-system-test-thread.strip-file-extension = true
+dss-system-test-thread.storage-processor = ch.systemsx.cisd.etlserver.DefaultStorageProcessor
+# The extractor plugin class to use for code extraction
+dss-system-test-thread.data-set-info-extractor = ch.systemsx.cisd.etlserver.DefaultDataSetInfoExtractor
+# Separator used to extract the barcode in the data set file name
+dss-system-test-thread.data-set-info-extractor.entity-separator = ${data-set-file-name-entity-separator}
+dss-system-test-thread.data-set-info-extractor.strip-file-extension = true
+dss-system-test-thread.data-set-info-extractor.space-code = CISD
+dss-system-test-thread.data-set-info-extractor.data-set-properties-file-name = data-set.properties
+
+dss-system-test-thread.type-extractor = ch.systemsx.cisd.etlserver.SimpleTypeExtractor
+dss-system-test-thread.type-extractor.file-format-type = TIFF
+dss-system-test-thread.type-extractor.locator-type = RELATIVE_LOCATION
+dss-system-test-thread.type-extractor.data-set-type = HCS_IMAGE
+
+
 # ---------------------------------------------------------------------------
 # (optional) archiver configuration
 # ---------------------------------------------------------------------------
diff --git a/datastore_server/etc/web-client.properties b/datastore_server/etc/web-client.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java
index f262dc1d3b3406e4d7d3e205828fb3d9feb352a3..85f91b8bd191ba21225dba3eeadb0a1f20bcc841 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/ETLDaemon.java
@@ -461,6 +461,11 @@ public final class ETLDaemon
     public final static void main(final String[] args)
     {
         final Parameters parameters = new Parameters(args);
+        run(parameters);
+    }
+
+    private static void run(final Parameters parameters)
+    {
         TimingParameters.setDefault(parameters.getTimingParameters());
         if (QueueingPathRemoverService.isRunning() == false)
         {
@@ -476,4 +481,21 @@ public final class ETLDaemon
         operationLog.info("Data Store Server ready and waiting for data.");
     }
 
+    /**
+     * Runs ETL Daemon for system testing: Replaces default {@link IExitHandler} by a one which
+     * throws an {@link AssertionError}.
+     */
+    public static void runForTesting(String[] args)
+    {
+        exitHandler = new IExitHandler()
+            {
+                public void exit(int exitCode)
+                {
+                    throw new AssertionError("Unexpected exit: " + exitCode);
+                }
+            };
+        Parameters parameters = new Parameters(args, exitHandler);
+        run(parameters);
+    }
+
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
index 268bee65d4958040e4154ca76bc97c3ba35cba45..6c69e1e09e08ef2c40b19467d46d9f2cc97f1b20 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java
@@ -17,7 +17,9 @@
 package ch.systemsx.cisd.openbis.dss.generic.shared.utils;
 
 import java.io.File;
+import java.util.Map.Entry;
 import java.util.Properties;
+import java.util.Set;
 
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
@@ -31,6 +33,9 @@ import ch.systemsx.cisd.common.utilities.PropertyUtils;
  */
 public class DssPropertyParametersUtil
 {
+    /** Prefix of system properties which may override service.properties. */
+    public static final String OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX = "openbis.dss.";
+
     @Private
     static final String DSS_CODE_KEY = "data-store-server-code";
 
@@ -39,7 +44,8 @@ public class DssPropertyParametersUtil
 
     public static final String DOWNLOAD_URL_KEY = "download-url";
 
-    private static final String SERVICE_PROPERTIES_FILE = "etc/service.properties";
+    /** Location of service properties file. */
+    public static final String SERVICE_PROPERTIES_FILE = "etc/service.properties";
 
     /** loads server configuration */
     public static ExtendedProperties loadServiceProperties()
@@ -50,6 +56,14 @@ public class DssPropertyParametersUtil
     public static ExtendedProperties loadProperties(String filePath)
     {
         Properties properties = PropertyUtils.loadProperties(filePath);
+        Properties systemProperties = System.getProperties();
+        ExtendedProperties dssSystemProperties =
+                ExtendedProperties.getSubset(systemProperties, OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX, true);
+        Set<Entry<Object, Object>> entrySet = dssSystemProperties.entrySet();
+        for (Entry<Object, Object> entry : entrySet)
+        {
+            properties.put(entry.getKey(), entry.getValue());
+        }
         return ExtendedProperties.createWith(properties);
     }
 
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..c97a982d9f0c3691264f6228e0fa5a09d8d74d5c
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/DssComponentTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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.openbis.dss.systemtest;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.openbis.dss.client.api.v1.DssComponentFactory;
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss;
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IDssComponent;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssBuilder;
+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.generic.shared.dto.SimpleDataSetInformationDTO;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class DssComponentTest extends SystemTestCase
+{
+    private static final Comparator<FileInfoDssDTO> FILE_INFO_COMPARATOR =
+            new Comparator<FileInfoDssDTO>()
+                {
+                    public int compare(FileInfoDssDTO f1, FileInfoDssDTO f2)
+                    {
+                        return f1.getPathInDataSet().compareTo(f2.getPathInDataSet());
+                    }
+                };
+    private IDssComponent dss;
+
+    @BeforeMethod
+    public void beforeMethod()
+    {
+        dss = DssComponentFactory.tryCreate("test", "a", "http://localhost:8888");
+    }
+
+    @Test
+    public void testPutDataSet() throws Exception
+    {
+        DataSetOwner dataSetOwner = new DataSetOwner(DataSetOwnerType.SAMPLE, "CISD:/CISD/3VCP1");
+        File exampleDataSet = new File(workingDirectory, "my-data");
+        exampleDataSet.mkdirs();
+        FileUtilities.writeToFile(new File(exampleDataSet, "data.log"), "hello world");
+        FileUtilities.writeToFile(new File(exampleDataSet, "data-set.properties"),
+                "property\tvalue\nCOMMENT\thello");
+        File subFolder = new File(exampleDataSet, "data");
+        subFolder.mkdirs();
+        FileUtilities.writeToFile(new File(subFolder, "1.data"), "1 2 3");
+        FileUtilities.writeToFile(new File(subFolder, "2.data"), "4 5 6 7");
+        String rootPath = exampleDataSet.getCanonicalPath();
+        FileInfoDssBuilder builder = new FileInfoDssBuilder(rootPath, rootPath);
+        ArrayList<FileInfoDssDTO> list = new ArrayList<FileInfoDssDTO>();
+        builder.appendFileInfosForFile(exampleDataSet, list, true);
+        IDataSetDss dataSet = dss.putDataSet(new NewDataSetDTO(dataSetOwner, 
+                exampleDataSet.getName(), list), exampleDataSet);
+        checkDataSet(dataSet);
+    }
+    
+    @Test(dependsOnMethods = "testPutDataSet")
+    public void testGetDataSetGetFile() throws Exception
+    {
+        String code = getCodeOfLatestDataSet().getDataSetCode();
+        
+        IDataSetDss ds = dss.getDataSet(code);
+        
+        assertEquals(code, ds.getCode());
+        checkDataSet(ds);
+        FileInfoDssDTO[] files = ds.listFiles("/original/my-data/data", false);
+        Arrays.sort(files, FILE_INFO_COMPARATOR);
+        assertEquals("[FileInfoDssDTO[/original/my-data/data/1.data,5], "
+                + "FileInfoDssDTO[/original/my-data/data/2.data,7]]", Arrays.asList(files)
+                .toString());
+        files = ds.listFiles("/", true);
+        Arrays.sort(files, FILE_INFO_COMPARATOR);
+        assertEquals("[FileInfoDssDTO[/original,-1], FileInfoDssDTO[/original/my-data,-1], "
+                + "FileInfoDssDTO[/original/my-data/data,-1], "
+                + "FileInfoDssDTO[/original/my-data/data-set.properties,28], "
+                + "FileInfoDssDTO[/original/my-data/data.log,11], "
+                + "FileInfoDssDTO[/original/my-data/data/1.data,5], "
+                + "FileInfoDssDTO[/original/my-data/data/2.data,7]]", Arrays.asList(files)
+                .toString());
+    }
+
+    @Test(dependsOnMethods = "testPutDataSet")
+    public void testGetDataSetGetLink() throws Exception
+    {
+        SimpleDataSetInformationDTO dataSetInfo = getCodeOfLatestDataSet();
+        String code = dataSetInfo.getDataSetCode();
+        File fileIntoStore = new File(new File(rootDir, "store"), dataSetInfo.getDataSetLocation());
+        
+        IDataSetDss ds = dss.getDataSet(code);
+        
+        File link = ds.tryLinkToContents(null);
+        assertEquals(fileIntoStore.getAbsolutePath(), link.getAbsolutePath());
+        File file = ds.getLinkOrCopyOfContents(null, workingDirectory);
+        assertEquals(fileIntoStore.getAbsolutePath(), file.getAbsolutePath());
+    }
+
+    @Test(dependsOnMethods = "testPutDataSet")
+    public void testGetDataSetGetCopy() throws Exception
+    {
+        SimpleDataSetInformationDTO dataSetInfo = getCodeOfLatestDataSet();
+        String code = dataSetInfo.getDataSetCode();
+        
+        IDataSetDss ds = dss.getDataSet(code);
+        
+        assertEquals(null, ds.tryLinkToContents("blabla"));
+        File file = ds.getLinkOrCopyOfContents("blabla", workingDirectory);
+        assertContent("hello world", file, "data.log");
+        assertContent("1 2 3", file, "data/1.data");
+        assertContent("4 5 6 7", file, "data/2.data");
+    }
+
+    private void assertContent(String expectedContent, File root, String path)
+    {
+        assertEquals(expectedContent,
+                FileUtilities.loadToString(new File(root, "original/my-data/" + path)).trim());
+    }
+    
+    private SimpleDataSetInformationDTO getCodeOfLatestDataSet()
+    {
+        IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
+        List<SimpleDataSetInformationDTO> dataSets = openBISService.listDataSets();
+        Collections.sort(dataSets, new Comparator<SimpleDataSetInformationDTO>()
+            {
+                public int compare(SimpleDataSetInformationDTO d1, SimpleDataSetInformationDTO d2)
+                {
+                    return d2.getDataSetCode().compareTo(d1.getDataSetCode());
+                }
+            });
+        return dataSets.get(0);
+    }
+    
+    private void checkDataSet(IDataSetDss dataSet) throws IOException
+    {
+        assertEquals("hello world", getContent(dataSet, "data.log"));
+        assertEquals("1 2 3", getContent(dataSet, "data/1.data"));
+        assertEquals("4 5 6 7", getContent(dataSet, "data/2.data"));
+    }
+
+    private String getContent(IDataSetDss dataSet, String path) throws IOException
+    {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        InputStream inputStream = null;
+        try
+        {
+            inputStream = dataSet.getFile("/original/my-data/" + path);
+            IOUtils.copy(inputStream, output);
+        } finally
+        {
+            IOUtils.closeQuietly(inputStream);
+        }
+        return output.toString();
+    }
+
+}
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..854e2d0dbd5cc0fdf45fc36a2cbc1edc8d8f61c6
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/systemtest/SystemTestCase.java
@@ -0,0 +1,134 @@
+/*
+ * 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.openbis.dss.systemtest;
+
+import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX;
+import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.SERVICE_PROPERTIES_FILE;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.springframework.beans.factory.xml.XmlBeanFactory;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.GenericWebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeSuite;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.etlserver.ETLDaemon;
+import ch.systemsx.cisd.openbis.dss.generic.server.DataStoreServer;
+import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SystemTestCase extends AssertJUnit
+{
+    private static final String UNIT_TEST_WORKING_DIRECTORY = "unit-test-wd";
+    private static final String TARGETS_DIRECTORY = "targets";
+    private static final File UNIT_TEST_ROOT_DIRECTORY =
+            new File(TARGETS_DIRECTORY + File.separator + UNIT_TEST_WORKING_DIRECTORY);
+    private static final String ROOT_DIR_KEY = "root-dir";
+    private static final String ROOT_DIR_PREFIX = "${" + ROOT_DIR_KEY + "}/";
+    
+    protected File workingDirectory;
+    protected File rootDir;
+
+    SystemTestCase()
+    {
+        workingDirectory = new File(UNIT_TEST_ROOT_DIRECTORY, getClass().getName());
+        workingDirectory.mkdirs();
+        workingDirectory.deleteOnExit();
+    }
+
+    @BeforeSuite
+    public void beforeSuite() throws Exception
+    {
+        TestInitializer.init();
+        Server server = new Server();
+        Connector connector = new SelectChannelConnector();
+        connector.setPort(8888);
+        server.addConnector(connector);
+        DispatcherServlet dispatcherServlet = new DispatcherServlet()
+            {
+                private static final long serialVersionUID = 1L;
+
+                @Override
+                protected WebApplicationContext findWebApplicationContext()
+                {
+                    XmlBeanFactory f =
+                            new XmlBeanFactory(new FileSystemResource(
+                                    "../openbis/resource/server/spring-servlet.xml"));
+                    GenericWebApplicationContext wac = new GenericWebApplicationContext(f);
+                    wac.setParent(new ClassPathXmlApplicationContext(
+                            "classpath:applicationContext.xml"));
+                    wac.refresh();
+                    return wac;
+                }
+            };
+        ServletContextHandler sch =
+                new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
+        sch.addServlet(new ServletHolder(dispatcherServlet), "/*");
+        server.start();
+        
+        rootDir = new File(workingDirectory, "dss-root");
+        List<String> serviceProperties =
+                FileUtilities.loadToStringList(new File(SERVICE_PROPERTIES_FILE));
+        for (String property : serviceProperties)
+        {
+            int index = property.indexOf(ROOT_DIR_PREFIX);
+            if (index >= 0)
+            {
+                File folder =
+                        new File(rootDir, property.substring(index + ROOT_DIR_PREFIX.length()));
+                if (folder.exists())
+                {
+                    FileUtilities.deleteRecursively(folder);
+                }
+                assertEquals("Couldn't create folder " + folder.getAbsolutePath(), true,
+                        folder.mkdirs());
+            }
+        }
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + ROOT_DIR_KEY,
+                rootDir.getAbsolutePath());
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX + "dss-rpc.put-default",
+                "dss-system-test-thread");
+        DataStoreServer.main(new String[0]);
+        ETLDaemon.runForTesting(new String[0]);
+    }
+    
+    @BeforeClass
+    public void beforeClass() throws IOException
+    {
+        FileUtils.deleteDirectory(workingDirectory);
+        workingDirectory.mkdir();
+        assertTrue(workingDirectory.isDirectory() && workingDirectory.listFiles().length == 0);
+    }
+}