diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
index 4ef88f85c215824b8fb921ed230481618e818e08..3a88d1913ef84c3a71a0b7ccfedaa7f5e6890af2 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractDssServiceRpc.java
@@ -135,9 +135,9 @@ public abstract class AbstractDssServiceRpc
     /**
      * Asserts that specified data sets are all accessible by the user of the specified session.
      */
-    protected void assertDatasetsAreAccessible(String sessionToken, List<String> dataSetCodes)
+    protected void checkDatasetsAuthorization(String sessionToken, List<String> dataSetCodes)
     {
-        if (areDatasetsAccessible(sessionToken, dataSetCodes) == false)
+        if (isSessionAuthorizedForDatasets(sessionToken, dataSetCodes) == false)
         {
             throw new IllegalArgumentException(
                     "User is not allowed to access at least one of the following data sets: "
@@ -153,7 +153,7 @@ public abstract class AbstractDssServiceRpc
      * @param dataSetCodes The data set codes we want to check access for.
      * @return True if all the data sets are accessible, false if one or more are not accessible.
      */
-    protected boolean areDatasetsAccessible(String sessionToken, List<String> dataSetCodes)
+    protected boolean isSessionAuthorizedForDatasets(String sessionToken, List<String> dataSetCodes)
     {
         boolean access;
         if (operationLog.isInfoEnabled())
@@ -201,7 +201,7 @@ public abstract class AbstractDssServiceRpc
     protected Map<String, File> checkAccessAndGetRootDirectories(String sessionToken,
             List<String> dataSetCodes) throws IllegalArgumentException
     {
-        if (areDatasetsAccessible(sessionToken, dataSetCodes) == false)
+        if (isSessionAuthorizedForDatasets(sessionToken, dataSetCodes) == false)
         {
             throw new IllegalArgumentException("Path does not exist.");
         }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSImageDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSImageDatasetLoader.java
index ec93ee30c00da85bb7930d8780050d4c53b995f2..4cf24d106f04f919137f3d8c4f9c51eb00eff352 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSImageDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/HCSImageDatasetLoader.java
@@ -26,13 +26,21 @@ import javax.imageio.ImageIO;
 
 import org.apache.commons.lang.StringUtils;
 
+import com.sun.media.jai.codec.ImageCodec;
+import com.sun.media.jai.codec.ImageEncoder;
+import com.sun.media.jai.codec.TIFFEncodeParam;
+
 import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.bds.hcs.Location;
+import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
+import ch.systemsx.cisd.common.io.ByteArrayBasedContent;
 import ch.systemsx.cisd.common.io.IContent;
+import ch.systemsx.cisd.common.utilities.DataTypeUtil;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.IContentRepository;
 import ch.systemsx.cisd.openbis.dss.etl.IHCSImageDatasetLoader;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDatasetDownloadServlet.Size;
+import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtils;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtil;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.HCSDatasetLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingQueryDAO;
@@ -106,6 +114,21 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
             if (imageDTO != null)
             {
                 content = contentRepository.getContent(imageDTO.getFilePath());
+                final InputStream is = content.getInputStream();
+                final String fileType = DataTypeUtil.tryToFigureOutFileTypeOf(is);
+                if (DataTypeUtil.isTiff(fileType) == false || imageDTO.getColorComponent() != null
+                        || imageDTO.getPage() != null)
+                {
+                    final int page = (imageDTO.getPage() != null) ? imageDTO.getPage() : 0;
+                    BufferedImage image = ImageUtil.loadImage(is, fileType, page);
+                    if (imageDTO.getColorComponent() != null)
+                    {
+                        image =
+                                ImageChannelsUtils.transformToChannel(image, imageDTO
+                                        .getColorComponent());
+                    }
+                    content = asContent(image, fileType, content.getName(), content.getUniqueId());
+                }
             }
         }
         if (content != null && imageDTO != null)
@@ -118,6 +141,29 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
         }
     }
 
+    private static IContent asContent(BufferedImage image, String fileType, String name, String id)
+    {
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        final TIFFEncodeParam param = new TIFFEncodeParam();
+        param.setLittleEndian(true);
+        if (DataTypeUtil.isJpeg(fileType))
+        {
+            param.setCompression(TIFFEncodeParam.COMPRESSION_JPEG_TTN2);
+        } else
+        {
+            param.setCompression(TIFFEncodeParam.COMPRESSION_DEFLATE);
+        }
+        final ImageEncoder enc = ImageCodec.createImageEncoder("tiff", out, param);
+        try
+        {
+            enc.encode(image);
+            return new ByteArrayBasedContent(out.toByteArray(), name, id);
+        } catch (IOException ex)
+        {
+            throw EnvironmentFailureException.fromTemplate("Cannot encode image.", ex);
+        }
+    }
+
     private static final class ThumbnailContent implements IContent
     {
         private final IContent content;
@@ -166,6 +212,7 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
         {
             return content.getUniqueId();
         }
+
     }
 
 }
\ No newline at end of file
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 649a762c2f5c223fc1c142fdbe51584a53b59c67..c0a27640060a339101572332e3b0db8b9cb2b195 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
@@ -18,7 +18,9 @@ package ch.systemsx.cisd.openbis.dss.generic.server.images;
 
 import java.awt.Color;
 import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
 import java.io.File;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -82,9 +84,18 @@ public class ImageChannelsUtils
      */
     public static BufferedImage mergeImageChannels(TileImageReference params,
             List<AbsoluteImageReference> imageReferences)
+    {
+        return mergeImageChannels(imageReferences, params.isMergeAllChannels());
+    }
+
+    /**
+     * Creates an images of the specified tile and with requested channels merged.<br>
+     */
+    public static BufferedImage mergeImageChannels(List<AbsoluteImageReference> imageReferences,
+            boolean mergeChannels)
     {
         BufferedImage resultImage;
-        if (params.isMergeAllChannels())
+        if (mergeChannels)
         {
             resultImage = mergeAllChannels(imageReferences);
         } else
@@ -93,16 +104,26 @@ public class ImageChannelsUtils
                     + "but more have been specified: " + imageReferences;
             AbsoluteImageReference imageReference = imageReferences.get(0);
 
-            resultImage = selectSingleChannel(params, imageReference);
+            resultImage = selectSingleChannel(imageReference);
         }
         return resultImage;
     }
 
-    private static BufferedImage selectSingleChannel(TileImageReference params,
-            AbsoluteImageReference imageReference)
+    /**
+     * Reads the given content and selects a single channel from it.
+     */
+    public static BufferedImage selectSingleChannel(AbsoluteImageReference imageReference)
+    {
+        return selectSingleChannel(imageReference.getContent().getInputStream(), imageReference
+                .tryGetColorComponent());
+    }
+
+    /**
+     * Reads the given content and selects a single channel from it.
+     */
+    public static BufferedImage selectSingleChannel(InputStream input, ColorComponent colorComponent)
     {
-        BufferedImage image = ImageUtil.loadImage(imageReference.getContent().getInputStream());
-        ColorComponent colorComponent = imageReference.tryGetColorComponent();
+        BufferedImage image = ImageUtil.loadImage(input);
         if (colorComponent == null)
         {
             // TODO 2010-06-15 Izabela Adamczyk: We have to select a single channel from the (most
@@ -238,7 +259,10 @@ public class ImageChannelsUtils
         }
     }
 
-    private static BufferedImage transformToChannel(BufferedImage bufferedImage,
+    /**
+     * Transforms the given <var>bufferedImage</var> as 
+     */
+    public static BufferedImage transformToChannel(BufferedImage bufferedImage,
             ColorComponent colorComponent)
     {
         BufferedImage newImage = createNewImage(bufferedImage);
@@ -256,7 +280,7 @@ public class ImageChannelsUtils
         return newImage;
     }
 
-    private static BufferedImage createNewImage(BufferedImage bufferedImage)
+    private static BufferedImage createNewImage(RenderedImage bufferedImage)
     {
         BufferedImage newImage =
                 new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(),
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 f1970227f39756dbdca595dd1e62c1a748fa24c9..c1c0e96785444139a13915207f5215d4bbbe4d96 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
@@ -77,7 +77,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
     /**
      * The minor version of this service.
      */
-    private static final int MINOR_VERSION = 1;
+    public static final int MINOR_VERSION = 1;
 
     private IImagingQueryDAO dao;
 
@@ -114,7 +114,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
     public List<String> listAvailableFeatureNames(String sessionToken,
             List<? extends IFeatureVectorDatasetIdentifier> featureDatasets)
     {
-        assertDataSetsAreAccessible(sessionToken, featureDatasets);
+        checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, featureDatasets);
         List<String> result = new ArrayList<String>(); // keep the order
         for (IFeatureVectorDatasetIdentifier identifier : featureDatasets)
         {
@@ -135,6 +135,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
     public List<ImageDatasetMetadata> listImageMetadata(String sessionToken,
             List<? extends IImageDatasetIdentifier> imageDatasets)
     {
+        checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, imageDatasets);
         ArrayList<String> datasetCodes = new ArrayList<String>();
         for (IImageDatasetIdentifier dataset : imageDatasets)
         {
@@ -194,7 +195,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
     public List<FeatureVectorDataset> loadFeatures(String sessionToken,
             List<FeatureVectorDatasetReference> featureDatasets, List<String> featureNames)
     {
-        assertDataSetsAreAccessible(sessionToken, featureDatasets);
+        checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, featureDatasets);
         List<FeatureVectorDataset> result = new ArrayList<FeatureVectorDataset>();
         for (FeatureVectorDatasetReference dataset : featureDatasets)
         {
@@ -224,7 +225,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
             String sessionToken, List<FeatureVectorDatasetWellReference> datasetWellReferences,
             List<String> featureNames)
     {
-        assertDataSetsAreAccessible(sessionToken, datasetWellReferences);
+        checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, datasetWellReferences);
         final FeatureTableBuilder builder =
                 createFeatureTableBuilder(datasetWellReferences, featureNames);
         return createFeatureVectorList(builder);
@@ -265,26 +266,19 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
 
     public InputStream loadImages(String sessionToken, List<PlateImageReference> imageReferences)
     {
-        Map<String, IHCSImageDatasetLoader> imageLoadersMap =
+        checkDatasetsAuthorizationForIDatasetIdentifier(sessionToken, imageReferences);
+        final Map<String, IHCSImageDatasetLoader> imageLoadersMap =
                 getImageDatasetsMap(sessionToken, imageReferences);
-        List<IContent> imageFiles = new ArrayList<IContent>();
+        final List<IContent> imageFiles = new ArrayList<IContent>();
         try
         {
             for (PlateImageReference imageReference : imageReferences)
             {
-                IHCSImageDatasetLoader imageAccessor =
+                final IHCSImageDatasetLoader imageAccessor =
                         imageLoadersMap.get(imageReference.getDatasetCode());
                 assert imageAccessor != null : "imageAccessor not found for: " + imageReference;
-                AbsoluteImageReference image = tryGetImage(imageAccessor, imageReference);
-                if (image == null
-                        || (image.tryGetColorComponent() != null || image.tryGetPage() != null))
-                {
-                    // TODO 2010-06-01, Tomasz Pylak: support paging/merged channels images in API
-                    imageFiles.add(null);
-                } else
-                {
-                    imageFiles.add(image.getContent());
-                }
+                final AbsoluteImageReference imageRef = tryGetImage(imageAccessor, imageReference);
+                imageFiles.add((imageRef == null) ? null : imageRef.getContent());
             }
         } finally
         {
@@ -340,6 +334,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
                     .getChannel(), null);
         } catch (EnvironmentFailureException e)
         {
+            operationLog.error("Error reading image.", e);
             return null; // no image found
         }
     }
@@ -412,7 +407,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
         return getDAO().listFeatureDefsByDataSetId(dataSet.getId());
     }
 
-    private void assertDataSetsAreAccessible(String sessionToken,
+    private void checkDatasetsAuthorizationForIDatasetIdentifier(String sessionToken,
             List<? extends IDatasetIdentifier> identifiers)
     {
         List<String> dataSetCodes = new ArrayList<String>();
@@ -420,7 +415,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
         {
             dataSetCodes.add(identifier.getDatasetCode());
         }
-        assertDatasetsAreAccessible(sessionToken, dataSetCodes);
+        checkDatasetsAuthorization(sessionToken, dataSetCodes);
     }
 
     private IImagingQueryDAO getDAO()