diff --git a/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java
index 5e9627f18e79407fbff0870e57ff270bf3e8fe32..9ba45c46f3f27077bf6bd49f30996c0fe2cc8366 100644
--- a/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java
+++ b/common/source/java/ch/systemsx/cisd/common/io/ByteArrayBasedContent.java
@@ -18,6 +18,10 @@ package ch.systemsx.cisd.common.io;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+import ch.systemsx.cisd.common.filesystem.ByteBufferRandomAccessFile;
+import ch.systemsx.cisd.common.filesystem.IRandomAccessFile;
 
 /**
  * Content based on an array of bytes.
@@ -69,4 +73,9 @@ public class ByteArrayBasedContent implements IContent
     {
         return new ByteArrayInputStream(byteArray);
     }
+
+    public IRandomAccessFile getReadOnlyRandomAccessFile()
+    {
+        return new ByteBufferRandomAccessFile(ByteBuffer.wrap(byteArray));
+    }
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java
index 647e96f9937b250b66e8d249ab2054120ca53e1e..8ff889b3de31b7965db4c554c4ef0c816978b56e 100644
--- a/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java
+++ b/common/source/java/ch/systemsx/cisd/common/io/ContentProviderBasedContent.java
@@ -18,6 +18,8 @@ package ch.systemsx.cisd.common.io;
 
 import java.io.InputStream;
 
+import ch.systemsx.cisd.common.filesystem.IRandomAccessFile;
+
 /**
  * Content based on a {@link IContentProvider}.
  *
@@ -56,6 +58,11 @@ public class ContentProviderBasedContent implements IContent
         return getContent().getInputStream();
     }
     
+    public IRandomAccessFile getReadOnlyRandomAccessFile()
+    {
+        return getContent().getReadOnlyRandomAccessFile();
+    }
+    
     private IContent getContent()
     {
         if (content == null)
@@ -64,5 +71,5 @@ public class ContentProviderBasedContent implements IContent
         }
         return content;
     }
-    
+
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java b/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java
index b76e440084379932ec71fe1ae81a6712218f3087..4442ae357fba4f2e815b9733a9e8fada29aed116 100644
--- a/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java
+++ b/common/source/java/ch/systemsx/cisd/common/io/FileBasedContent.java
@@ -20,9 +20,13 @@ import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.RandomAccessFile;
 
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
+import ch.systemsx.cisd.common.filesystem.IRandomAccessFile;
+import ch.systemsx.cisd.common.filesystem.RandomAccessFileImpl;
 
 /**
  * File content. Wraps an instance of {@link File}.
@@ -78,4 +82,15 @@ public class FileBasedContent implements IContent
             throw CheckedExceptionTunnel.wrapIfNecessary(ex);
         }
     }
+
+    public IRandomAccessFile getReadOnlyRandomAccessFile()
+    {
+        try
+        {
+            return new RandomAccessFileImpl(new RandomAccessFile(file, "r"));
+        } catch (IOException ex)
+        {
+            throw CheckedExceptionTunnel.wrapIfNecessary(ex);
+        }
+    }
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/io/IContent.java b/common/source/java/ch/systemsx/cisd/common/io/IContent.java
index e2b6037273f64861b0ab2a897d2477e7769710f6..cf4b6b330456233031f4d57ee71f24e4abbd4f53 100644
--- a/common/source/java/ch/systemsx/cisd/common/io/IContent.java
+++ b/common/source/java/ch/systemsx/cisd/common/io/IContent.java
@@ -18,8 +18,10 @@ package ch.systemsx.cisd.common.io;
 
 import java.io.InputStream;
 
+import ch.systemsx.cisd.common.filesystem.IRandomAccessFile;
+
 /**
- * Abstract of streamable binary content with name and known size.
+ * Abstract of streamable and random-accessible binary content with name and known size.
  * 
  * @author Franz-Josef Elmer
  */
@@ -40,6 +42,11 @@ public interface IContent
      */
     public boolean exists();
 
+    /**
+     * Returns a random access file object for read-only use.
+     */
+    public IRandomAccessFile getReadOnlyRandomAccessFile();
+    
     /**
      * Returns a new instance of an input stream over the complete content. Note that the returned
      * {@link InputStream} is expected to have {@link InputStream#markSupported()}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java
index 52521107b7437e7f3021674922efaa7e8e8be5e7..9a1f18c3cdeb009c5a69d75b88b0f6394b91a95d 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtil.java
@@ -37,12 +37,13 @@ import javax.imageio.ImageIO;
 
 import org.apache.commons.io.IOUtils;
 
-import com.sun.media.jai.codec.FileSeekableStream;
 import com.sun.media.jai.codec.ImageCodec;
 import com.sun.media.jai.codec.ImageDecoder;
 
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.io.FileBasedContent;
+import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.common.utilities.DataTypeUtil;
 
 /**
@@ -182,9 +183,9 @@ public class ImageUtil
      * @throws IllegalArgumentException if the input stream doesn't start with a magic number
      *             identifying supported image format.
      */
-    public static BufferedImage loadImage(InputStream inputStream)
+    public static BufferedImage loadImage(IContent content)
     {
-        return loadImage(inputStream, 0);
+        return loadImage(content, 0);
     }
 
     /**
@@ -195,12 +196,12 @@ public class ImageUtil
      * @throws IllegalArgumentException if the input stream doesn't start with a magic number
      *             identifying supported image format.
      */
-    public static BufferedImage loadImage(InputStream inputStream, int page)
+    public static BufferedImage loadImage(IContent content, int page)
     {
-        InputStream markSupportingInputStream = inputStream;
-        if (inputStream.markSupported() == false)
+        InputStream markSupportingInputStream = content.getInputStream();
+        if (markSupportingInputStream.markSupported() == false)
         {
-            markSupportingInputStream = new BufferedInputStream(inputStream);
+            markSupportingInputStream = new BufferedInputStream(markSupportingInputStream);
         }
         String fileType = DataTypeUtil.tryToFigureOutFileTypeOf(markSupportingInputStream);
         return loadImage(markSupportingInputStream, fileType, page);
@@ -214,7 +215,7 @@ public class ImageUtil
      * @throws IllegalArgumentException if the input stream doesn't start with a magic number
      *             identifying supported image format.
      */
-    public static BufferedImage loadImage(InputStream inputStream, String fileType, int page)
+    private static BufferedImage loadImage(InputStream inputStream, String fileType, int page)
     {
         try
         {
@@ -251,15 +252,7 @@ public class ImageUtil
         {
             throw new IllegalArgumentException("File does not exist: " + file.getAbsolutePath());
         }
-        try
-        {
-            FileSeekableStream inStream = new FileSeekableStream(file);
-            return loadImage(inStream);
-        } catch (IOException ex)
-        {
-            throw new IllegalArgumentException("Isn't a valid image file: "
-                    + file.getAbsolutePath() + ". Error: " + ex.getMessage());
-        }
+        return loadImage(new FileBasedContent(file));
     }
 
     /**
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java
index 2d8e8ac588c9c9d1b590b09a24739b803ff6a831..22b9bbcae4b03e6c04c6c1b46e1f8f8af6816efa 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/ImageUtilTest.java
@@ -18,8 +18,6 @@ package ch.systemsx.cisd.openbis.dss.generic.shared.utils;
 
 import java.awt.image.BufferedImage;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -27,7 +25,9 @@ import org.testng.AssertJUnit;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
+import ch.systemsx.cisd.common.filesystem.IRandomAccessFile;
+import ch.systemsx.cisd.common.io.FileBasedContent;
+import ch.systemsx.cisd.common.io.IContent;
 
 /**
  * 
@@ -36,6 +36,37 @@ import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
  */
 public class ImageUtilTest extends AssertJUnit
 {
+    private static class MockIContent implements IContent
+    {
+        final MockInputStream is = new MockInputStream();
+        
+        public String tryGetName()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public long getSize()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean exists()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public IRandomAccessFile getReadOnlyRandomAccessFile()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        public InputStream getInputStream()
+        {
+            return is;
+        }
+        
+    }
+    
     private static class MockInputStream extends InputStream
     {
         boolean closeInvoked;
@@ -100,17 +131,17 @@ public class ImageUtilTest extends AssertJUnit
     @Test
     public void testInputStreamAutomaticallyClosed()
     {
-        MockInputStream inputStream = new MockInputStream();
+        MockIContent content = new MockIContent();
         try
         {
-            ImageUtil.loadImage(inputStream);
+            ImageUtil.loadImage(content);
             fail("IllegalArgumentException expected");
         } catch (IllegalArgumentException ex)
         {
             assertEquals("File type of an image input stream couldn't be determined.", ex.getMessage());
         }
         
-        assertEquals(true, inputStream.closeInvoked);
+        assertEquals(true, content.is.closeInvoked);
     }
 
     private BufferedImage loadImageByFile(String fileName)
@@ -123,15 +154,7 @@ public class ImageUtilTest extends AssertJUnit
     private BufferedImage loadImageByInputStream(String fileName)
     {
         File file = new File(dir, fileName);
-        BufferedImage image;
-        try
-        {
-            image = ImageUtil.loadImage(new FileInputStream(file));
-        } catch (FileNotFoundException ex)
-        {
-            throw CheckedExceptionTunnel.wrapIfNecessary(ex);
-        }
-        return image;
+        return ImageUtil.loadImage(new FileBasedContent(file));
     }
     
     private void assertImageSize(int expectedWith, int expectedHeight, BufferedImage image)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
index 4e4ab5dc8979dc19a9c4139486f7a74937f62d4b..6b22e8228d4fedabb45026766c70e9fe898e3f75 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtils.java
@@ -24,7 +24,6 @@ import java.awt.image.RenderedImage;
 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.List;
@@ -470,12 +469,11 @@ public class ImageChannelsUtils
     private static BufferedImage loadImage(AbsoluteImageReference imageReference)
     {
         IContent content = imageReference.getContent();
-        InputStream inputStream = content.getInputStream();
 
         // extracts the correct page if necessary
         int page = (imageReference.tryGetPage() != null) ? imageReference.tryGetPage() : 0;
 
-        BufferedImage image = ImageUtil.loadImage(inputStream, page);
+        BufferedImage image = ImageUtil.loadImage(content, page);
         return image;
     }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
index ed4cf6cb7ace14b5bad31a26709a98ee11c97856..ad6ef6d49e67738051f1a56c49f464cffad508ed 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreening.java
@@ -219,7 +219,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
             IImagingDatasetLoader imageAccessor)
     {
         IContent imageFile = getAnyImagePath(imageAccessor, dataset);
-        BufferedImage image = ImageUtil.loadImage(imageFile.getInputStream());
+        BufferedImage image = ImageUtil.loadImage(imageFile);
         Size imageSize = new Size(image.getWidth(), image.getHeight());
         return imageSize;
     }
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
index 00b25a1caac2e399b112dabecfac5d45baef6d20..db7cc1938fe1c4c4fc7454668f8314875506ba7b 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
@@ -242,7 +242,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit
 
     private String getImageContentDescription(IContent image)
     {
-        BufferedImage bufferedImage = ImageUtil.loadImage(image.getInputStream());
+        BufferedImage bufferedImage = ImageUtil.loadImage(image);
         return getImageContentDescription(bufferedImage);
     }
 
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
index 4abfe1dda2c313b6a4d24746f5182a0de891deb0..2269ffb0c839c7124fe03f59b8a2f5e04ddf878d 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
@@ -17,7 +17,6 @@
 package ch.systemsx.cisd.openbis.dss.screening.server;
 
 import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
@@ -42,6 +41,7 @@ import ch.systemsx.cisd.base.image.IImageTransformer;
 import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 import ch.systemsx.cisd.base.mdarray.MDFloatArray;
 import ch.systemsx.cisd.bds.hcs.Location;
+import ch.systemsx.cisd.common.io.ByteArrayBasedContent;
 import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter;
 import ch.systemsx.cisd.common.io.FileBasedContent;
 import ch.systemsx.cisd.common.io.IContent;
@@ -333,7 +333,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
     {
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         imagesWriter.writeNextBlock(outputStream);
-        return ImageUtil.loadImage(new ByteArrayInputStream(outputStream.toByteArray()));
+        return ImageUtil
+                .loadImage(new ByteArrayBasedContent(outputStream.toByteArray(), "UNKNOWN"));
     }
 
     @Test
@@ -448,14 +449,14 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
                     ImgDatasetDTO dataset = createDataset(datasetId);
                     dataset.setContainerId(containerId);
                     dataset.setPermId(DATASET_CODE);
-                    
+
                     long experimentId = 888;
                     ImgContainerDTO container = new ImgContainerDTO(null, null, null, experimentId);
                     container.setId(containerId);
 
                     one(dao).tryGetDatasetByPermId(DATASET_CODE);
                     will(returnValue(dataset));
-                    
+
                     allowing(dao).hasDatasetChannels(DATASET_CODE);
                     will(returnValue(false));
 
@@ -601,7 +602,8 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
 
     private FeatureVectorDatasetReference createFeatureVectorDatasetReference(String dataSetCode)
     {
-        return new FeatureVectorDatasetReference(dataSetCode, "", null, null, null, null, null, null);
+        return new FeatureVectorDatasetReference(dataSetCode, "", null, null, null, null, null,
+                null);
     }
 
     // Used for the authorization test