diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetAndPathInfoDBConsistencyCheckProcessingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetAndPathInfoDBConsistencyCheckProcessingPlugin.java
index 91076bf6750322781a2fba22b51b9a4308a15608..f27722bc00f8678e37bf07b4170e65d9fa1766e2 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetAndPathInfoDBConsistencyCheckProcessingPlugin.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/DataSetAndPathInfoDBConsistencyCheckProcessingPlugin.java
@@ -46,6 +46,8 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.HierarchicalContentProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IHierarchicalContentProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ProcessingStatus;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.content.DssServiceRpcGenericFactory;
+import ch.systemsx.cisd.openbis.dss.generic.shared.content.IDssServiceRpcGenericFactory;
 import ch.systemsx.cisd.openbis.dss.generic.shared.content.PathInfoDBOnlyHierarchicalContentFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
 
@@ -62,6 +64,8 @@ public class DataSetAndPathInfoDBConsistencyCheckProcessingPlugin implements IPr
 
     private transient IHierarchicalContentProvider pathInfoProvider;
 
+    private transient IDssServiceRpcGenericFactory serviceFactory;
+
     private static final long serialVersionUID = 1L;
 
     public DataSetAndPathInfoDBConsistencyCheckProcessingPlugin(Properties properties,
@@ -604,7 +608,8 @@ public class DataSetAndPathInfoDBConsistencyCheckProcessingPlugin implements IPr
                     new HierarchicalContentProvider(ServiceProvider.getOpenBISService(),
                             ServiceProvider.getShareIdManager(),
                             ServiceProvider.getConfigProvider(), ServiceProvider.getContentCache(),
-                            new DefaultFileBasedHierarchicalContentFactory(), null, null);
+                            new DefaultFileBasedHierarchicalContentFactory(), getServiceFactory(),
+                            null, null);
         }
         return fileProvider;
     }
@@ -625,9 +630,19 @@ public class DataSetAndPathInfoDBConsistencyCheckProcessingPlugin implements IPr
                         new HierarchicalContentProvider(ServiceProvider.getOpenBISService(),
                                 ServiceProvider.getShareIdManager(),
                                 ServiceProvider.getConfigProvider(),
-                                ServiceProvider.getContentCache(), pathInfoDBFactory, null, null);
+                                ServiceProvider.getContentCache(), pathInfoDBFactory,
+                                getServiceFactory(), null, null);
             }
         }
         return pathInfoProvider;
     }
+
+    private IDssServiceRpcGenericFactory getServiceFactory()
+    {
+        if (serviceFactory == null)
+        {
+            serviceFactory = new DssServiceRpcGenericFactory();
+        }
+        return serviceFactory;
+    }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java
index 1526f8f6dd706efb3ba9865f093be2be83750c46..6f3fd59e1588353c9e652791afd29b328d7eb3ec 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProvider.java
@@ -32,7 +32,8 @@ import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer;
 import ch.systemsx.cisd.common.ssl.SslCertificateHelper;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.IHierarchicalContentFactory;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContent;
-import ch.systemsx.cisd.openbis.dss.generic.shared.content.ContentCache;
+import ch.systemsx.cisd.openbis.dss.generic.shared.content.IContentCache;
+import ch.systemsx.cisd.openbis.dss.generic.shared.content.IDssServiceRpcGenericFactory;
 import ch.systemsx.cisd.openbis.dss.generic.shared.content.PathInfoDBAwareHierarchicalContentFactory;
 import ch.systemsx.cisd.openbis.dss.generic.shared.content.RemoteHierarchicalContent;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.PathInfoDataSourceProvider;
@@ -63,42 +64,47 @@ public class HierarchicalContentProvider implements IHierarchicalContentProvider
 
     private final boolean trustAllCertificates;
 
-    private final ContentCache cache;
+    private final IContentCache cache;
+
+    private final IDssServiceRpcGenericFactory serviceFactory;
 
     public HierarchicalContentProvider(IEncapsulatedOpenBISService openbisService,
-            IShareIdManager shareIdManager, IConfigProvider configProvider, ContentCache contentCache,
+            IShareIdManager shareIdManager, IConfigProvider configProvider,
+            IContentCache contentCache, IDssServiceRpcGenericFactory serviceFactory,
             ISessionTokenProvider sessionTokenProvider,
             ExposablePropertyPlaceholderConfigurer infoProvider)
     {
         this(openbisService, new DataSetDirectoryProvider(configProvider.getStoreRoot(),
-                shareIdManager), null, contentCache, sessionTokenProvider, configProvider.getDataStoreCode(),
-                infoProvider);
+                shareIdManager), null, serviceFactory, contentCache, sessionTokenProvider,
+                configProvider.getDataStoreCode(), infoProvider);
     }
 
     public HierarchicalContentProvider(IEncapsulatedOpenBISService openbisService,
-            IShareIdManager shareIdManager, IConfigProvider configProvider, ContentCache contentCache,
-            IHierarchicalContentFactory hierarchicalContentFactory,
+            IShareIdManager shareIdManager, IConfigProvider configProvider,
+            IContentCache contentCache, IHierarchicalContentFactory hierarchicalContentFactory,
+            IDssServiceRpcGenericFactory serviceFactory,
             ISessionTokenProvider sessionTokenProvider,
             ExposablePropertyPlaceholderConfigurer infoProvider)
     {
         this(openbisService, new DataSetDirectoryProvider(configProvider.getStoreRoot(),
-                shareIdManager), hierarchicalContentFactory, contentCache, sessionTokenProvider, configProvider
-                .getDataStoreCode(), infoProvider);
+                shareIdManager), hierarchicalContentFactory, serviceFactory, contentCache,
+                sessionTokenProvider, configProvider.getDataStoreCode(), infoProvider);
     }
 
     @Private
     public HierarchicalContentProvider(IEncapsulatedOpenBISService openbisService,
             IDataSetDirectoryProvider directoryProvider,
             IHierarchicalContentFactory hierarchicalContentFactory,
-            ContentCache contentCache, ISessionTokenProvider session,
-            String dataStoreCode,
+            IDssServiceRpcGenericFactory serviceFactory, IContentCache contentCache,
+            ISessionTokenProvider sessionTokenProvider, String dataStoreCode,
             ExposablePropertyPlaceholderConfigurer infoProvider)
     {
         this.openbisService = openbisService;
         this.directoryProvider = directoryProvider;
         this.hierarchicalContentFactory = hierarchicalContentFactory;
+        this.serviceFactory = serviceFactory;
         this.cache = contentCache;
-        this.sessionTokenProvider = session;
+        this.sessionTokenProvider = sessionTokenProvider;
         this.dataStoreCode = dataStoreCode;
         if (infoProvider != null)
         {
@@ -160,9 +166,9 @@ public class HierarchicalContentProvider implements IHierarchicalContentProvider
             {
                 IDataSetPathInfoProvider dataSetPathInfoProvider =
                         ServiceProvider.getDataSetPathInfoProvider();
-                provider = dataSetPathInfoProvider.tryGetSingleDataSetPathInfoProvider(locationNode
-                        .getLocation()
-                        .getDataSetCode());
+                provider =
+                        dataSetPathInfoProvider.tryGetSingleDataSetPathInfoProvider(locationNode
+                                .getLocation().getDataSetCode());
             }
 
             if (trustAllCertificates)
@@ -170,8 +176,8 @@ public class HierarchicalContentProvider implements IHierarchicalContentProvider
                 SslCertificateHelper.trustAnyCertificate(locationNode.getLocation()
                         .getDataStoreUrl());
             }
-            return new RemoteHierarchicalContent(locationNode, provider, sessionTokenProvider,
-                    cache);
+            return new RemoteHierarchicalContent(locationNode, provider, serviceFactory,
+                    sessionTokenProvider, cache);
         }
     }
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
index 3830f3e3e0b04b30a9b82672048ff94ad55b5490..772e7995d49ccb4942d7f1dd022c61e37154f450 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ServiceProvider.java
@@ -26,7 +26,7 @@ import com.marathon.util.spring.StreamSupportingHttpInvokerServiceExporter;
 
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.openbis.dss.generic.shared.content.ContentCache;
+import ch.systemsx.cisd.openbis.dss.generic.shared.content.IContentCache;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 import ch.systemsx.cisd.openbis.generic.shared.dto.OpenBISSessionHolder;
 
@@ -189,9 +189,9 @@ public class ServiceProvider
         return result;
     }
     
-    public static ContentCache getContentCache()
+    public static IContentCache getContentCache()
     {
-        return (ContentCache) getApplicationContext().getBean("content-cache");
+        return (IContentCache) getApplicationContext().getBean("content-cache");
     }
 
     private ServiceProvider()
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java
index 27be63515e75521351109d29b137f5682aa503b6..d199f91c4ce2f2baa5d0677c5b0f61f01c78e374 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/ContentCache.java
@@ -45,7 +45,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation;
  * 
  * @author Franz-Josef Elmer
  */
-public class ContentCache
+public class ContentCache implements IContentCache
 {
     public static final String CACHE_WORKSPACE_FOLDER_KEY = "cache-workspace-folder";
 
@@ -93,29 +93,28 @@ public class ContentCache
         fileLockManager = new LockManager();
     }
 
-    public IDssServiceRpcGeneric getDssService(IDatasetLocation dataSetLocation)
-    {
-        return serviceFactory.getService(dataSetLocation.getDataStoreUrl());
-    }
-
+    @Override
     public void lockDataSet(String sessionToken, String dataSetCode)
     {
         String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode);
         dataSetLockManager.lock(dataSetPath);
     }
 
+    @Override
     public void unlockDataSet(String sessionToken, String dataSetCode)
     {
         String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode);
         dataSetLockManager.unlock(dataSetPath);
     }
     
+    @Override
     public boolean isDataSetLocked(String sessionToken, String dataSetCode)
     {
         String dataSetPath = createDataSetPath(sessionToken, CACHE_FOLDER, dataSetCode);
         return dataSetLockManager.isLocked(dataSetPath);
     }
 
+    @Override
     public File getFile(String sessionToken, IDatasetLocation dataSetLocation,
             DataSetPathInfo path)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/IContentCache.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/IContentCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..41694ef82cf6bc61edf4e30eaf89f1aa2d60927b
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/IContentCache.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 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.shared.content;
+
+import java.io.File;
+
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetPathInfo;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation;
+
+/**
+ * Interface for cache for files remotely retrieved from Data Store Servers.
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IContentCache
+{
+
+    public void lockDataSet(String sessionToken, String dataSetCode);
+
+    public void unlockDataSet(String sessionToken, String dataSetCode);
+
+    public boolean isDataSetLocked(String sessionToken, String dataSetCode);
+
+    public File getFile(String sessionToken, IDatasetLocation dataSetLocation, DataSetPathInfo path);
+
+}
\ No newline at end of file
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java
index 1639b3cedd59c70fe3a554dc3024ae94bc9237d1..7c6133da295518a7f647f100b2c21d90b5b4ca6e 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContent.java
@@ -40,14 +40,18 @@ public class RemoteHierarchicalContent implements IHierarchicalContent
 
     private final ISessionTokenProvider sessionTokenProvider;
 
-    private final ContentCache cache;
+    private final IContentCache cache;
+
+    private final IDssServiceRpcGenericFactory serviceFactory;
 
     public RemoteHierarchicalContent(IDatasetLocationNode location,
-            ISingleDataSetPathInfoProvider pathInfoProvider, ISessionTokenProvider sessionTokenProvider,
-            ContentCache cache)
+            ISingleDataSetPathInfoProvider pathInfoProvider,
+            IDssServiceRpcGenericFactory serviceFactory,
+            ISessionTokenProvider sessionTokenProvider, IContentCache cache)
     {
         this.location = location;
         this.provider = pathInfoProvider;
+        this.serviceFactory = serviceFactory;
         this.sessionTokenProvider = sessionTokenProvider;
         this.cache = cache;
         cache.lockDataSet(sessionTokenProvider.getSessionToken(), location.getLocation().getDataSetCode());
@@ -146,7 +150,7 @@ public class RemoteHierarchicalContent implements IHierarchicalContent
     private IHierarchicalContentNode createNode(DataSetPathInfo info)
     {
         return new RemoteHierarchicalContentNode(location.getLocation(), info,
-                provider, sessionTokenProvider, cache);
+                provider, serviceFactory, sessionTokenProvider, cache);
     }
 
     private List<IHierarchicalContentNode> createNodes(List<DataSetPathInfo> paths)
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java
index a7eae9a3c0d2542a18c3a1b5ba51b759552265da..416bf1be83c217b1dcd9749d01f60fbcea732072 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNode.java
@@ -52,28 +52,30 @@ public class RemoteHierarchicalContentNode implements IHierarchicalContentNode
 
     private String parentRelativePath;
 
-    private final ContentCache cache;
+    private final IContentCache cache;
 
     private final IDatasetLocation dataSetLocation;
 
+    private final IDssServiceRpcGenericFactory serviceFactory;
+
     public RemoteHierarchicalContentNode(IDatasetLocation dataSetetLocation, DataSetPathInfo path,
-            ISingleDataSetPathInfoProvider provider, 
-            ISessionTokenProvider sessionTokenProvider, ContentCache contentCache)
+            ISingleDataSetPathInfoProvider provider, IDssServiceRpcGenericFactory serviceFactory,
+            ISessionTokenProvider sessionTokenProvider, IContentCache contentCache)
     {
-        this(dataSetetLocation, path, provider, sessionTokenProvider, contentCache, null);
+        this(dataSetetLocation, path, provider, serviceFactory, sessionTokenProvider, contentCache,
+                null);
     }
 
-    private RemoteHierarchicalContentNode(IDatasetLocation dataSetetLocation,
-            DataSetPathInfo path,
-            ISingleDataSetPathInfoProvider provider,
-            ISessionTokenProvider sessionTokenProvider,
-            ContentCache contentCache,
+    private RemoteHierarchicalContentNode(IDatasetLocation dataSetetLocation, DataSetPathInfo path,
+            ISingleDataSetPathInfoProvider provider, IDssServiceRpcGenericFactory serviceFactory,
+            ISessionTokenProvider sessionTokenProvider, IContentCache contentCache,
             String parentRelativePath)
     {
         this.dataSetLocation = dataSetetLocation;
         this.path = path;
         this.provider = provider;
         this.sessionTokenProvider = sessionTokenProvider;
+        this.serviceFactory = serviceFactory;
         this.cache = contentCache;
         this.parentRelativePath = parentRelativePath;
     }
@@ -148,11 +150,12 @@ public class RemoteHierarchicalContentNode implements IHierarchicalContentNode
             for (DataSetPathInfo childPath : provider.listChildrenPathInfos(path))
             {
                 children.add(new RemoteHierarchicalContentNode(dataSetLocation, childPath,
-                        provider, sessionTokenProvider, cache, relativePath));
+                        provider, serviceFactory, sessionTokenProvider, cache, relativePath));
             }
         } else
         {
-            IDssServiceRpcGeneric service = cache.getDssService(dataSetLocation);
+            IDssServiceRpcGeneric service =
+                    serviceFactory.getService(dataSetLocation.getDataStoreUrl());
             String sessionToken = sessionTokenProvider.getSessionToken();
             String dataSetCode = dataSetLocation.getDataSetCode();
             FileInfoDssDTO[] files =
@@ -167,7 +170,7 @@ public class RemoteHierarchicalContentNode implements IHierarchicalContentNode
                 info.setSizeInBytes(file.getFileSize());
                 info.setLastModified(new Date(0L));
                 children.add(new RemoteHierarchicalContentNode(dataSetLocation, info, provider,
-                        sessionTokenProvider, cache, relativePath));
+                        serviceFactory, sessionTokenProvider, cache, relativePath));
             }
         }
         return children;
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetDownloadServletTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetDownloadServletTest.java
index 171615f3980175b4e51fe68da2e710ae9f195dc0..7213129c3f7f978132edf325f5000491cbb81f25 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetDownloadServletTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DatasetDownloadServletTest.java
@@ -172,7 +172,7 @@ public class DatasetDownloadServletTest
                 new MockDataSetDirectoryProvider(TEST_FOLDER, DEFAULT_SHARE_ID, shareIdManager);
         hierarchicalContentProvider =
                 new HierarchicalContentProvider(openbisService, dummyDirectoryProvider,
-                        fileBasedContentFactory, null, null, "STANDARD", null);
+                        fileBasedContentFactory, null, null, null, "STANDARD", null);
         httpSession = context.mock(HttpSession.class);
         TEST_FOLDER.mkdirs();
         EXAMPLE_DATA_SET_FOLDER.mkdirs();
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
index 8e699d1d1187ab2587fecddcdb379d88c574847e..3a12a452ea5f8951894885bd9cd5a657240913bf 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/DssServiceRpcV1Test.java
@@ -186,7 +186,7 @@ public class DssServiceRpcV1Test extends AbstractFileSystemTestCase
                 new MockDataSetDirectoryProvider(storeDir, SHARE_ID, shareIdManager);
         contentProvider =
                 new HierarchicalContentProvider(openBisService, dummyDirectoryProvider,
-                        fileBasedContentFactory, null, null, "STANDARD", null);
+                        fileBasedContentFactory, null, null, null, "STANDARD", null);
 
         setupGetExpectations();
 
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProviderTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProviderTest.java
index 4c05631c301ad7cd451ef5e10e1683285f484516..015d2beb8a62aa7c4d7870a6789dbfcc999f0d87 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProviderTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/HierarchicalContentProviderTest.java
@@ -73,7 +73,7 @@ public class HierarchicalContentProviderTest extends AssertJUnit
         openbisService = context.mock(IEncapsulatedOpenBISService.class);
         hierarchicalContentProvider =
                 new HierarchicalContentProvider(openbisService, directoryProvider,
-                        hierarchicalContentFactory, null, null, "STANDARD", null);
+                        hierarchicalContentFactory, null, null, null, "STANDARD", null);
     }
 
     @AfterMethod
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/AbstractRemoteHierarchicalContentTestCase.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/AbstractRemoteHierarchicalContentTestCase.java
new file mode 100644
index 0000000000000000000000000000000000000000..62a33336b2fec7e24e0a0d02ebe4ba64ac0fc83b
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/AbstractRemoteHierarchicalContentTestCase.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2013 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.shared.content;
+
+import java.io.File;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+
+import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.filesystem.IFileOperations;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ISingleDataSetPathInfoProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatasetLocation;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation;
+import ch.systemsx.cisd.openbis.generic.shared.dto.OpenBISSessionHolder;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractRemoteHierarchicalContentTestCase extends AbstractFileSystemTestCase
+{
+    protected static final String DATA_STORE_URL = "http://a.b.c";
+
+    protected static final String SESSION_TOKEN = "token";
+    
+    private static final String DATA_STORE_CODE = "DSS";
+    
+    protected static final String DATA_SET_CODE = "DS-123";
+    
+    protected static final IDatasetLocation DATA_SET_LOCATION = new DatasetLocation(
+            DATA_SET_CODE, "a/b/c", DATA_STORE_CODE, DATA_STORE_URL);
+    
+    protected static final String STARTED_MESSAGE = "started";
+
+    protected static final String FINISHED_MESSAGE = "finished";
+
+    protected static final String FILE1_CONTENT = "hello file one";
+
+    protected static final String FILE2_CONTENT = "hello file two";
+
+    protected Mockery context;
+
+    protected IFileOperations fileOperations;
+
+    protected IDssServiceRpcGenericFactory serviceFactory;
+
+    protected IDssServiceRpcGeneric remoteDss;
+
+    protected ISingleDataSetPathInfoProvider pathInfoProvider;
+
+    protected OpenBISSessionHolder sessionHolder;
+    
+    protected File workSpace;
+
+    protected File remoteFile1;
+    
+    protected File remoteFile2;
+    
+    @BeforeMethod
+    public void setUpBasicFixture()
+    {
+        context = new Mockery();
+        fileOperations = context.mock(IFileOperations.class);
+        serviceFactory = context.mock(IDssServiceRpcGenericFactory.class);
+        remoteDss = context.mock(IDssServiceRpcGeneric.class, "remote DSS");
+        pathInfoProvider = context.mock(ISingleDataSetPathInfoProvider.class);
+        workSpace = new File(workingDirectory, "workspace");
+        sessionHolder = new OpenBISSessionHolder();
+        sessionHolder.setSessionToken(SESSION_TOKEN);
+        context.checking(new Expectations()
+        {
+            {
+                allowing(serviceFactory).getService(DATA_STORE_URL);
+                will(returnValue(remoteDss));
+            }
+        });
+        File remoteStore = new File(workingDirectory, "remote-store");
+        File remoteDataSetFolder = new File(remoteStore, DATA_SET_CODE);
+        remoteDataSetFolder.mkdirs();
+        remoteFile1 = new File(remoteDataSetFolder, "file1.txt");
+        FileUtilities.writeToFile(remoteFile1, FILE1_CONTENT);
+        remoteFile2 = new File(remoteDataSetFolder, "file2.txt");
+        FileUtilities.writeToFile(remoteFile2, FILE2_CONTENT);
+    }
+    
+    @AfterMethod
+    public void tearDown()
+    {
+        // 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();
+    }
+
+    protected ContentCache createCache(boolean sessionCache)
+    {
+        if (sessionCache == false)
+        {
+            context.checking(new Expectations()
+                {
+                    {
+                        one(fileOperations).removeRecursivelyQueueing(
+                                new File(workSpace, ContentCache.DOWNLOADING_FOLDER));
+                    }
+                });
+        }
+        return new ContentCache(serviceFactory, workSpace, sessionCache, fileOperations);
+    }
+
+
+}
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java
index d96e6517eb9fe813b8c91ba83503721b0bcc92aa..5826fcc637f7619bc8c8d7bd2084decc32203b15 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeMultiThreadTest.java
@@ -19,104 +19,22 @@ package ch.systemsx.cisd.openbis.dss.generic.shared.content;
 import java.io.File;
 
 import org.jmock.Expectations;
-import org.jmock.Mockery;
 import org.jmock.internal.NamedSequence;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase;
 import ch.systemsx.cisd.common.concurrent.MessageChannel;
 import ch.systemsx.cisd.common.concurrent.MessageChannelBuilder;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
-import ch.systemsx.cisd.common.filesystem.IFileOperations;
 import ch.systemsx.cisd.common.logging.ConsoleLogger;
 import ch.systemsx.cisd.common.test.ProxyAction;
 import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContentNode;
-import ch.systemsx.cisd.openbis.dss.generic.shared.ISingleDataSetPathInfoProvider;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.IDssServiceRpcGeneric;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetPathInfo;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatasetLocation;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation;
-import ch.systemsx.cisd.openbis.generic.shared.dto.OpenBISSessionHolder;
 
 /**
  * @author Franz-Josef Elmer
  */
-public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSystemTestCase
+public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractRemoteHierarchicalContentTestCase
 {
-    private static final String STARTED_MESSAGE = "started";
-
-    private static final String FINISHED_MESSAGE = "finished";
-
-    private static final String FILE1_CONTENT = "hello file one";
-
-    private static final String FILE2_CONTENT = "hello file two";
-
-    private static final String SESSION_TOKEN = "token";
-
-    private static final String DATA_STORE_URL = "http://a.b.c";
-
-    private static final String DATA_STORE_CODE = "DSS";
-    
-    private static final String DATA_SET_CODE = "DS-123";
-    
-    private static final IDatasetLocation DATA_SET_LOCATION = new DatasetLocation(
-            DATA_SET_CODE, "a/b/c", DATA_STORE_CODE, DATA_STORE_URL);
-
-    private Mockery context;
-
-    private IFileOperations fileOperations;
-    
-    private ISingleDataSetPathInfoProvider provider;
-
-    private IDssServiceRpcGeneric remoteDss;
-
-    private OpenBISSessionHolder sessionHolder;
-
-    private File workSpace;
-
-    private File remoteFile1;
-
-    private File remoteFile2;
-
-    private IDssServiceRpcGenericFactory serviceFactory;
-
-    @BeforeMethod
-    public void setUpFixture()
-    {
-        context = new Mockery();
-        fileOperations = context.mock(IFileOperations.class);
-        provider = context.mock(ISingleDataSetPathInfoProvider.class);
-        remoteDss = context.mock(IDssServiceRpcGeneric.class, "remote DSS");
-        sessionHolder = new OpenBISSessionHolder();
-        sessionHolder.setSessionToken(SESSION_TOKEN);
-        File remoteStore = new File(workingDirectory, "remote-store");
-        File remoteDataSetFolder = new File(remoteStore, DATA_SET_CODE);
-        remoteDataSetFolder.mkdirs();
-        remoteFile1 = new File(remoteDataSetFolder, "file1.txt");
-        FileUtilities.writeToFile(remoteFile1, FILE1_CONTENT);
-        remoteFile2 = new File(remoteDataSetFolder, "file2.txt");
-        FileUtilities.writeToFile(remoteFile2, FILE2_CONTENT);
-        workSpace = new File(workingDirectory, "workspace");
-        serviceFactory = context.mock(IDssServiceRpcGenericFactory.class);
-        context.checking(new Expectations()
-            {
-                {
-                    allowing(serviceFactory).getService(DATA_STORE_URL);
-                    will(returnValue(remoteDss));
-                }
-            });
-    }
-    
-    @AfterMethod
-    public void tearDown()
-    {
-        // 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 testGetTwoDifferentFilesInSequence() throws Exception
     {
@@ -417,25 +335,10 @@ public class RemoteHierarchicalContentNodeMultiThreadTest extends AbstractFileSy
         context.assertIsSatisfied();
     }
     
-    private ContentCache createCache(boolean sessionCache)
-    {
-        if (sessionCache == false)
-        {
-            context.checking(new Expectations()
-                {
-                    {
-                        one(fileOperations).removeRecursivelyQueueing(
-                                new File(workSpace, ContentCache.DOWNLOADING_FOLDER));
-                    }
-                });
-        }
-        return new ContentCache(serviceFactory, workSpace, sessionCache, fileOperations);
-    }
-
     private IHierarchicalContentNode createRemoteNode(DataSetPathInfo pathInfo, ContentCache cache)
     {
-        return new RemoteHierarchicalContentNode(DATA_SET_LOCATION, pathInfo, provider, 
-                sessionHolder, cache);
+        return new RemoteHierarchicalContentNode(DATA_SET_LOCATION, pathInfo, pathInfoProvider, 
+                serviceFactory, sessionHolder, cache);
     }
 
     private static interface IRunnableWithResult<T> extends Runnable
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java
index 09183291403707667259c59845489171ba876c42..13a5567d93005b8fcf9a9d30cb5351700282e936 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentNodeTest.java
@@ -77,6 +77,8 @@ public class RemoteHierarchicalContentNodeTest
 
     File fileInSessionWorkspace;
 
+    private IDssServiceRpcGenericFactory serviceFactory;
+
     @BeforeMethod
     public void fixture() throws Exception
     {
@@ -99,7 +101,7 @@ public class RemoteHierarchicalContentNodeTest
                         + CACHED_DATASET_LOCATION.getDataSetCode() + "/already-downloaded-file.txt");
         create(remoteFile);
         create(fileInSessionWorkspace);
-        final IDssServiceRpcGenericFactory serviceFactory = context.mock(IDssServiceRpcGenericFactory.class);
+        serviceFactory = context.mock(IDssServiceRpcGenericFactory.class);
         context.checking(new Expectations()
             {
                 {
@@ -123,7 +125,7 @@ public class RemoteHierarchicalContentNodeTest
 
         IHierarchicalContentNode node =
                 new RemoteHierarchicalContentNode(REMOTE_DATASET_LOCATION, pathInfo, provider,
-                        sessionHolder, cache);
+                        serviceFactory, sessionHolder, cache);
 
         context.checking(new Expectations()
             {
@@ -150,7 +152,7 @@ public class RemoteHierarchicalContentNodeTest
 
         IHierarchicalContentNode node =
                 new RemoteHierarchicalContentNode(CACHED_DATASET_LOCATION, pathInfo, provider,
-                        sessionHolder, cache);
+                        serviceFactory, sessionHolder, cache);
 
         File file = node.getFile();
         assertThat(file.getAbsolutePath(), is(fileInSessionWorkspace.getAbsolutePath()));
@@ -168,7 +170,7 @@ public class RemoteHierarchicalContentNodeTest
 
         IHierarchicalContentNode node =
                 new RemoteHierarchicalContentNode(CACHED_DATASET_LOCATION, pathInfo, provider,
-                        sessionHolder, cache);
+                        serviceFactory, sessionHolder, cache);
 
         context.checking(new Expectations()
             {
@@ -192,7 +194,7 @@ public class RemoteHierarchicalContentNodeTest
 
         IHierarchicalContentNode node =
                 new RemoteHierarchicalContentNode(CACHED_DATASET_LOCATION, pathInfo, null,
-                        sessionHolder, cache);
+                        serviceFactory, sessionHolder, cache);
 
         context.checking(new Expectations()
             {
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d29d9ed06b7d1e239aadd5062b3caee6aaf57a8
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/content/RemoteHierarchicalContentTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 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.shared.content;
+
+import java.io.File;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.openbis.common.io.hierarchical_content.api.IHierarchicalContentNode;
+import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetPathInfo;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatasetLocationNode;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class RemoteHierarchicalContentTest extends AbstractRemoteHierarchicalContentTestCase
+{
+
+    @Test
+    public void testLockingUnlockingDataSet()
+    {
+        ContentCache cache = createCache(false);
+        RemoteHierarchicalContent content = createContent(cache);
+
+        assertEquals(true, cache.isDataSetLocked(SESSION_TOKEN, DATA_SET_CODE));
+
+        content.close();
+
+        assertEquals(false, cache.isDataSetLocked(SESSION_TOKEN, DATA_SET_CODE));
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testGetDefaultRootNode() throws Exception
+    {
+        ContentCache cache = createCache(false);
+        RemoteHierarchicalContent content = createContent(cache);
+
+        context.checking(new Expectations()
+            {
+                {
+                    one(pathInfoProvider).getRootPathInfo();
+                }
+            });
+
+        IHierarchicalContentNode rootNode = content.getRootNode();
+        
+        assertEquals(true, rootNode.isDirectory());
+        assertEquals("", rootNode.getRelativePath());
+        assertEquals(null, rootNode.getParentRelativePath());
+        assertEquals("", rootNode.getName());
+        context.assertIsSatisfied();
+    }
+    
+    @Test
+    public void testGetRootNode() throws Exception
+    {
+        ContentCache cache = createCache(false);
+        RemoteHierarchicalContent content = createContent(cache);
+        
+        context.checking(new Expectations()
+        {
+            {
+                one(pathInfoProvider).getRootPathInfo();
+                DataSetPathInfo pathInfo = new DataSetPathInfo();
+                pathInfo.setDirectory(true);
+                pathInfo.setRelativePath(remoteFile1.getName());
+                pathInfo.setFileName("root");
+                will(returnValue(pathInfo));
+                
+                one(remoteDss).getDownloadUrlForFileForDataSet(SESSION_TOKEN, DATA_SET_CODE,
+                        pathInfo.getRelativePath());
+                will(returnValue(remoteFile1.toURI().toURL().toString()));
+            }
+        });
+        
+        IHierarchicalContentNode rootNode = content.getRootNode();
+
+        File file = rootNode.getFile();
+        assertEquals(new File(workSpace, ContentCache.CACHE_FOLDER + "/" + DATA_SET_CODE + "/"
+                + remoteFile1.getName()).getAbsolutePath(), file.getAbsolutePath());
+        assertEquals(FILE1_CONTENT, FileUtilities.loadToString(file).trim());
+        context.assertIsSatisfied();
+    }
+
+    private RemoteHierarchicalContent createContent(ContentCache cache)
+    {
+        return new RemoteHierarchicalContent(new DatasetLocationNode(DATA_SET_LOCATION),
+                pathInfoProvider, serviceFactory, sessionHolder, cache);
+    }
+
+}