diff --git a/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContent.java b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f623c619d3405202539cd465178d67e073cd54a3
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContent.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 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.common.io;
+
+import java.util.List;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ * @author Piotr Buczek
+ */
+public interface IHierarchicalContent
+{
+    IHierarchicalContentNode getRootNode();
+
+    IHierarchicalContentNode getNode(String relativePath);
+
+    List<IHierarchicalContentNode> listMatchingNodes(String pattern);
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentFactory.java b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..846433420d37c63f42482e8212d40fb5ea2556f7
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2011 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.common.io;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ * @author Piotr Buczek
+ */
+public interface IHierarchicalContentFactory
+{
+    public IHierarchicalContent asHierarchicalContent(java.io.File file);
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..83b262f877a8740249fcb332416192b30441d998
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/io/IHierarchicalContentNode.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 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.common.io;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
+import ch.systemsx.cisd.base.io.IRandomAccessFile;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ * @author Piotr Buczek
+ */
+public interface IHierarchicalContentNode
+{
+    /** @throws UnsupportedOperationException if the backing store is not a file. */
+    java.io.File getFile() throws UnsupportedOperationException;
+
+    /** @throws IOExceptionUnchecked if an I/O error occurs. */
+    IRandomAccessFile getFileContent() throws IOExceptionUnchecked;
+
+    /** @throws IOExceptionUnchecked if an I/O error occurs. */
+    InputStream getInputStream() throws IOExceptionUnchecked;
+
+    /** @throws IOExceptionUnchecked if an I/O error occurs. */
+    OutputStream getOutputStream() throws IOExceptionUnchecked;
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/io/SimpleFileBasedHierarchicalContent.java b/common/source/java/ch/systemsx/cisd/common/io/SimpleFileBasedHierarchicalContent.java
new file mode 100644
index 0000000000000000000000000000000000000000..77c535598586678d721d29e318c6871d44535fea
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/io/SimpleFileBasedHierarchicalContent.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011 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.common.io;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
+import ch.systemsx.cisd.base.io.IRandomAccessFile;
+import ch.systemsx.cisd.base.io.RandomAccessFileImpl;
+
+/**
+ * {@link IHierarchicalContent} implementation for normal {@link java.io.File}.
+ * 
+ * @author Chandrasekhar Ramakrishnan
+ * @author Piotr Buczek
+ */
+class SimpleFileBasedHierarchicalContent implements IHierarchicalContent
+{
+    private final File root;
+
+    class SimpleFileBasedHierarchicalContentNode implements IHierarchicalContentNode
+    {
+        private final SimpleFileBasedHierarchicalContent parent; // TODO do we need this?
+
+        private final File file;
+
+        private SimpleFileBasedHierarchicalContentNode(SimpleFileBasedHierarchicalContent parent,
+                File file)
+        {
+            this.parent = parent;
+            this.file = file;
+        }
+
+        public File getFile()
+        {
+            return file;
+        }
+
+        public IRandomAccessFile getFileContent()
+        {
+            return new RandomAccessFileImpl(file, "r");
+        }
+
+        public InputStream getInputStream()
+        {
+            try
+            {
+                return new FileInputStream(file);
+            } catch (FileNotFoundException ex)
+            {
+                throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+            }
+        }
+
+        public OutputStream getOutputStream()
+        {
+            try
+            {
+                return new FileOutputStream(file);
+            } catch (FileNotFoundException ex)
+            {
+                throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+            }
+        }
+
+        // TODO Implement hash/equals
+    }
+
+    SimpleFileBasedHierarchicalContent(File file)
+    {
+        this.root = file;
+    }
+
+    public IHierarchicalContentNode getRootNode()
+    {
+        return getNode("/");
+    }
+
+    public IHierarchicalContentNode getNode(String relativePath)
+    {
+        return new SimpleFileBasedHierarchicalContentNode(this, new File(root, relativePath));
+    }
+
+    public List<IHierarchicalContentNode> listMatchingNodes(final String pattern)
+    {
+        File[] files = root.listFiles(new FilenameFilter()
+            {
+                // boolean accept(String filename)
+                // {
+                // return filename.matches(pattern);
+                // }
+
+                public boolean accept(File dir, String name)
+                {
+                    final String filename = new File(dir, name).getAbsolutePath(); // TODO absolute?
+                    return filename.matches(pattern);
+                }
+            });
+
+        List<IHierarchicalContentNode> nodes = new ArrayList<IHierarchicalContentNode>();
+        for (File file : files)
+        {
+            nodes.add(new SimpleFileBasedHierarchicalContentNode(this, file));
+        }
+        return nodes;
+    }
+
+    // TODO Implement hash/equals
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataSetHierarchicalContentFactory.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataSetHierarchicalContentFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..f936a9e25ffe2b99855c177a3d836f818cb239de
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataSetHierarchicalContentFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 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 ch.systemsx.cisd.common.io.IHierarchicalContent;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public abstract class DataSetHierarchicalContentFactory
+{
+    protected final EncapsulatedOpenBISService service;
+
+    // public static DataSetHierarchicalContentFactory getSharedFactory();
+
+    DataSetHierarchicalContentFactory(EncapsulatedOpenBISService service)
+    {
+        this.service = service;
+    }
+
+    public abstract IHierarchicalContent asContent(String dataSetCode);
+
+    public abstract IHierarchicalContent asContent(ExternalData externalData);
+
+    public abstract IHierarchicalContent asContent(DatasetDescription dataset);
+}
\ No newline at end of file