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 d8f2b1673ddb069a7e65e387f3455b0a7b45fa59..f85b8fbdedc1577e081efd92c57976a7161bfa84 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
@@ -191,13 +191,15 @@ public class ImageUtil
     /**
      * Loads the specified <var>page</var> from the image from the tiven </var>inputStream</var>.
      * Supported images formats are GIF, JPG, PNG, and TIFF. The input stream will be closed after
-     * loading. Note that only for TIFF files a <var>page</var> other than 0 may be specified.
+     * loading. Note that only for TIFF files a <var>page</var> other than 0 (or null which is
+     * equivalent) may be specified.
      * 
      * @throws IllegalArgumentException if the input stream doesn't start with a magic number
      *             identifying supported image format.
      */
-    public static BufferedImage loadImage(IContent content, int page)
+    public static BufferedImage loadImage(IContent content, Integer pageOrNull)
     {
+        int page = pageOrNull == null ? 0 : pageOrNull.intValue();
         InputStream markSupportingInputStream = content.getInputStream();
         if (markSupportingInputStream.markSupported() == false)
         {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageDatasetLoaderFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageDatasetLoaderFactory.java
index 25b21d981f3c5335bfc0e8ada0ab66f2f91f20b8..a907afba38de28cccd5e725b87f0f5141f14963e 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageDatasetLoaderFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSImageDatasetLoaderFactory.java
@@ -31,6 +31,13 @@ public class HCSImageDatasetLoaderFactory
     private static final Map<String, IContentRepositoryFactory> repositoryFactories =
             createFactories();
 
+    /** the loader has to be closed when it is not used any more to free database resources! */
+    public static final IImagingDatasetLoader create(File datasetRootDir, String datasetCode)
+    {
+        IContentRepository repository = createContentRepository(datasetRootDir);
+        return new ImagingDatasetLoader(DssScreeningUtils.getQuery(), datasetCode, repository);
+    }
+
     private static Map<String, IContentRepositoryFactory> createFactories()
     {
         Map<String, IContentRepositoryFactory> factories =
@@ -39,16 +46,9 @@ public class HCSImageDatasetLoaderFactory
         return factories;
     }
 
-    /** the loader has to be closed when it is not used any more to free database resources! */
-    public static final IImagingDatasetLoader create(File datasetRootDir, String datasetCode)
-    {
-        return createImageDBLoader(datasetRootDir, datasetCode);
-    }
-
-    private static ImagingDatasetLoader createImageDBLoader(File datasetRootDir, String datasetCode)
+    public static IContentRepository createContentRepository(File datasetRootDir)
     {
-        IContentRepository repository = new ContentRepository(datasetRootDir, repositoryFactories);
-        return new ImagingDatasetLoader(DssScreeningUtils.getQuery(), datasetCode, repository);
+        return new ContentRepository(datasetRootDir, repositoryFactories);
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java
index d27f9e8f21da655ebe7b9d5b76062dcef7c6f05c..2eeb96d4361310a0034fe8a47f82bc5dd291f12c 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/ImagingDatabaseVersionHolder.java
@@ -28,7 +28,7 @@ public class ImagingDatabaseVersionHolder implements IDatabaseVersionHolder
 
     public String getDatabaseVersion()
     {
-        return "009"; // changed in S96
+        return "010"; // changed in S102
     }
 
 }
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 4348e6bfb240f222da0de87272e88af4e43b8a5d..54268f601a0f8872d7cf39a45e82be92fd950218 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
@@ -470,13 +470,7 @@ public class ImageChannelsUtils
 
     private static BufferedImage loadImage(AbsoluteImageReference imageReference)
     {
-        IContent content = imageReference.getContent();
-
-        // extracts the correct page if necessary
-        int page = (imageReference.tryGetPage() != null) ? imageReference.tryGetPage() : 0;
-
-        BufferedImage image = ImageUtil.loadImage(content, page);
-        return image;
+        return ImageUtil.loadImage(imageReference.getContent(), imageReference.tryGetPage());
     }
 
     /**
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 ee825310f453748da5ec15663e99dfcf35d83b24..bb7d43982d7e0a13a46bc5e049920a04dceb06c4 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
@@ -120,9 +120,8 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
 
     public DssServiceRpcScreening(String storeRootDir)
     {
-        this(storeRootDir, null, QueryTool.getQuery(ServiceProvider.getDataSourceProvider()
-                .getDataSource(ScreeningConstants.IMAGING_DATA_SOURCE),
-                IImagingTransformerDAO.class), ServiceProvider.getOpenBISService(), null, true);
+        this(storeRootDir, null, DssScreeningUtils.createImagingTransformerDAO(), ServiceProvider
+                .getOpenBISService(), null, true);
     }
 
     DssServiceRpcScreening(String storeRootDir, IImagingReadonlyQueryDAO dao,
@@ -218,8 +217,8 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
     {
         final IImagingDatasetLoader imageAccessor =
                 createImageLoader(dataset.getDatasetCode(), datasetRoot);
-        final Size imageSize = getImageSize(dataset, imageAccessor);
-        final Size thumbnailSize = getThumbnailImageSize(dataset, imageAccessor);
+        final Size imageSize = getImageSize(dataset, imageAccessor, false);
+        final Size thumbnailSize = getImageSize(dataset, imageAccessor, true);
         final ImageDatasetParameters params = imageAccessor.getImageParameters();
         return new ImageDatasetMetadata(dataset, params.getChannelsCodes(),
                 params.getChannelsLabels(), params.getTileRowsNum(), params.getTileColsNum(),
@@ -228,96 +227,73 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
     }
 
     private static Size getImageSize(IImageDatasetIdentifier dataset,
-            IImagingDatasetLoader imageAccessor)
+            IImagingDatasetLoader imageAccessor, boolean thumbnailsRequired)
     {
-        IContent imageFile = getAnyImagePath(imageAccessor, dataset);
+        IContent imageFile = getAnyImagePath(imageAccessor, dataset, thumbnailsRequired);
         BufferedImage image = ImageUtil.loadImage(imageFile);
         Size imageSize = new Size(image.getWidth(), image.getHeight());
         return imageSize;
     }
 
-    /**
-     * Returns the size of the thumbnails, or {@link NULL_SIZE}.
-     */
-    private static Size getThumbnailImageSize(IImageDatasetIdentifier dataset,
-            IImagingDatasetLoader imageAccessor)
+    private static IContent getAnyImagePath(IImagingDatasetLoader imageAccessor,
+            IImageDatasetIdentifier dataset, boolean thumbnailsRequired)
     {
-        IContent imageFile = tryGetAnyThumbnailImagePath(imageAccessor, dataset);
-        if (imageFile == null)
+        if (imageAccessor.getImageParameters().tryGetRowsNum() == null)
         {
-            return NULL_SIZE;
+            return getAnyMicroscopyImagePath(imageAccessor, dataset, thumbnailsRequired);
+        } else
+        {
+            return getAnyHCSImagePath(imageAccessor, dataset, thumbnailsRequired);
         }
-        final BufferedImage image = ImageUtil.loadImage(imageFile);
-        final Size imageSize = new Size(image.getWidth(), image.getHeight());
-        return imageSize;
     }
 
-    // TODO 2010-12-09, Tomasz Pylak: replace this code by choosing the dataset representative
-    // Now it works only in HCS case.
-    private static IContent getAnyImagePath(IImagingDatasetLoader imageAccessor,
-            IImageDatasetIdentifier dataset)
+    private static IContent getAnyMicroscopyImagePath(IImagingDatasetLoader imageAccessor,
+            IImageDatasetIdentifier dataset, boolean thumbnailsRequired)
     {
         ImageDatasetParameters params = imageAccessor.getImageParameters();
-        for (int row = 1; row <= params.tryGetRowsNum(); row++)
+        RequestedImageSize originalOrThumbnail = createOriginalOrThumbnail(thumbnailsRequired);
+        for (String channelCode : params.getChannelsCodes())
         {
-            for (int col = 1; col <= params.tryGetColsNum(); col++)
+            AbsoluteImageReference image =
+                    imageAccessor.tryGetRepresentativeImage(channelCode, null, originalOrThumbnail);
+            if (image != null)
             {
-                for (int tileRow = 1; tileRow <= params.getTileRowsNum(); tileRow++)
-                {
-                    for (int tileCol = 1; tileCol <= params.getTileColsNum(); tileCol++)
-                    {
-                        for (String channelCode : params.getChannelsCodes())
-                        {
-                            ImageChannelStackReference channelStackReference =
-                                    ImageChannelStackReference.createHCSFromLocations(new Location(
-                                            col, row), Location.createLocationFromRowAndColumn(
-                                            tileRow, tileCol));
-                            AbsoluteImageReference image =
-                                    imageAccessor.tryGetImage(channelCode, channelStackReference,
-                                            RequestedImageSize.createOriginal());
-                            if (image != null)
-                            {
-                                return image.getContent();
-                            }
-                        }
-                    }
-                }
+                return image.getContent();
             }
         }
         throw new IllegalStateException("Cannot find any image in a dataset: " + dataset);
     }
 
-    // TODO 2010-12-09, Tomasz Pylak: replace this code by choosing the dataset representative
-    // Now it works only in HCS case.
-    private static IContent tryGetAnyThumbnailImagePath(IImagingDatasetLoader imageAccessor,
-            IImageDatasetIdentifier dataset)
+    private static RequestedImageSize createOriginalOrThumbnail(boolean thumbnailsRequired)
+    {
+        // exact thumbnail size does not matter, we just want to mark that we do not want the
+        // original image
+        return thumbnailsRequired ? new RequestedImageSize(NULL_SIZE, false) : RequestedImageSize
+                .createOriginal();
+    }
+
+    private static IContent getAnyHCSImagePath(IImagingDatasetLoader imageAccessor,
+            IImageDatasetIdentifier dataset, boolean thumbnailsRequired)
     {
         ImageDatasetParameters params = imageAccessor.getImageParameters();
+        RequestedImageSize originalOrThumbnail = createOriginalOrThumbnail(thumbnailsRequired);
         for (int row = 1; row <= params.tryGetRowsNum(); row++)
         {
             for (int col = 1; col <= params.tryGetColsNum(); col++)
             {
-                for (int tileRow = 1; tileRow <= params.getTileRowsNum(); tileRow++)
+                for (String channelCode : params.getChannelsCodes())
                 {
-                    for (int tileCol = 1; tileCol <= params.getTileColsNum(); tileCol++)
+                    AbsoluteImageReference image =
+                            imageAccessor.tryGetRepresentativeImage(channelCode, new Location(col,
+                                    row), originalOrThumbnail);
+                    if (image != null)
                     {
-                        for (String channelCode : params.getChannelsCodes())
-                        {
-                            ImageChannelStackReference channelStackReference =
-                                    ImageChannelStackReference.createHCSFromLocations(new Location(
-                                            col, row), Location.createLocationFromRowAndColumn(
-                                            tileRow, tileCol));
-                            final IContent image =
-                                    imageAccessor.tryGetThumbnail(channelCode,
-                                            channelStackReference);
-                            // Either all images have a thumbnail or none has one.
-                            return image;
-                        }
+                        return image.getContent();
                     }
                 }
             }
         }
-        return null;
+        throw new IllegalStateException("Cannot find any image in a dataset: " + dataset);
     }
 
     public List<FeatureVectorDataset> loadFeatures(String sessionToken,
@@ -786,7 +762,8 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
     {
         if (isMergedChannel(channel))
         {
-            return getDAO().tryGetExperimentByPermId(experimentPermID).tryGetImageTransformerFactory();
+            return getDAO().tryGetExperimentByPermId(experimentPermID)
+                    .tryGetImageTransformerFactory();
         } else
         {
             return getDAO().tryGetChannelForExperimentPermId(experimentPermID, channel)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/shared/DssScreeningUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/shared/DssScreeningUtils.java
index 3eae016990a9e80953b8adb21da3edf07b5d9081..20e40fac3e176e2c354f02a7a813abc1db403637 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/shared/DssScreeningUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/shared/DssScreeningUtils.java
@@ -23,6 +23,7 @@ import net.lemnik.eodsql.QueryTool;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingReadonlyQueryDAO;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingTransformerDAO;
 
 /**
  * Utility methods for DSS.
@@ -32,7 +33,10 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImag
 public class DssScreeningUtils
 {
     private static final IImagingReadonlyQueryDAO query = createQuery();
-    
+
+    /**
+     * Returned query is reused and should NOT be closed.
+     */
     public static IImagingReadonlyQueryDAO getQuery()
     {
         return query;
@@ -52,4 +56,17 @@ public class DssScreeningUtils
                         ScreeningConstants.IMAGING_DATA_SOURCE);
         return QueryTool.getQuery(dataSource, IImagingReadonlyQueryDAO.class);
     }
+
+    /**
+     * Creates a new query each time when it is called. Returned query should be closed after all
+     * operations are done.
+     */
+    public static IImagingTransformerDAO createImagingTransformerDAO()
+    {
+        DataSource dataSource =
+                ServiceProvider.getDataSourceProvider().getDataSource(
+                        ScreeningConstants.IMAGING_DATA_SOURCE);
+        return QueryTool.getQuery(dataSource, IImagingTransformerDAO.class);
+    }
+
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ExampleImageTransformerFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ExampleImageTransformerFactory.java
index b1aa0de40a2d7579f58e2b6c05b3d3aa4bb60234..57253aea57ee33f622af4b9503a1ab7c4e72fc4a 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ExampleImageTransformerFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ExampleImageTransformerFactory.java
@@ -22,18 +22,18 @@ import ch.systemsx.cisd.base.image.IImageTransformer;
 import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 
 /**
- * 
- *
  * @author Franz-Josef Elmer
  */
 public class ExampleImageTransformerFactory implements IImageTransformerFactory
 {
     private static final long serialVersionUID = 1L;
-    
+
     private static final class Color
     {
         private int red;
+
         private int green;
+
         private int blue;
 
         Color(int rgb)
@@ -42,26 +42,43 @@ public class ExampleImageTransformerFactory implements IImageTransformerFactory
             green = (rgb >> 8) & 0xff;
             blue = rgb & 0xff;
         }
-        
+
         int getColor(char colorSymbol)
         {
             switch (colorSymbol)
             {
-                case 'r': return red;
-                case 'g': return green;
-                case 'b': return blue;
-                default: return 0;
+                case 'r':
+                    return red;
+                case 'g':
+                    return green;
+                case 'b':
+                    return blue;
+                default:
+                    return 0;
             }
         }
     }
-    
+
     private final String colorPattern;
-    
+
+    private final int brightnessDelta;
+
     public ExampleImageTransformerFactory(String colorPattern)
+    {
+        this(colorPattern, 0);
+    }
+
+    public ExampleImageTransformerFactory(int brightnessDelta)
+    {
+        this("rgb", brightnessDelta);
+    }
+
+    public ExampleImageTransformerFactory(String colorPattern, int brightnessDelta)
     {
         this.colorPattern = colorPattern;
+        this.brightnessDelta = brightnessDelta;
     }
-    
+
     public IImageTransformer createTransformer()
     {
         return new IImageTransformer()
@@ -70,26 +87,29 @@ public class ExampleImageTransformerFactory implements IImageTransformerFactory
                 {
                     int width = input.getWidth();
                     int height = input.getHeight();
-                    BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+                    BufferedImage output =
+                            new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                     for (int x = 0; x < width; x++)
                     {
                         for (int y = 0; y < height; y++)
                         {
                             int rgb = input.getRGB(x, y);
                             Color color = new Color(rgb);
-                            output.setRGB(
-                                    x,
-                                    y,
-                                    (color.getColor(colorPattern.charAt(0)) << 16)
-                                            + (color.getColor(colorPattern.charAt(1)) << 8)
-                                            + color.getColor(colorPattern.charAt(2)));
+                            output.setRGB(x, y,
+                                    (calcNewColor(color, 0) << 16) + (calcNewColor(color, 1) << 8)
+                                            + calcNewColor(color, 2));
                         }
                     }
                     return output;
                 }
+
+                private int calcNewColor(Color color, int colorIndex)
+                {
+                    return color.getColor(colorPattern.charAt(colorIndex)) + brightnessDelta;
+                }
             };
     }
-    
+
     @Override
     public String toString()
     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/plugin/.gitignore b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/plugin/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java
index b7b54fcb18c167147f1d7c32f2263b497025fb81..8e33b48e0187952cfac862318de230ca7fb53624 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingReadonlyQueryDAO.java
@@ -36,7 +36,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
     public static final int FETCH_SIZE = 1000;
 
     public static final String SQL_HCS_IMAGE =
-            "select i.* from CHANNEL_STACKS, SPOTS, ACQUIRED_IMAGES, IMAGES as i "
+            "select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+                    + "from CHANNEL_STACKS, SPOTS, ACQUIRED_IMAGES, IMAGES as i "
                     + "where                                                                "
                     + "ACQUIRED_IMAGES.CHANNEL_ID = ?{1} and CHANNEL_STACKS.DS_ID = ?{2} and "
                     + "CHANNEL_STACKS.x = ?{3.x} and CHANNEL_STACKS.y = ?{3.y} and "
@@ -46,7 +47,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
                     + "CHANNEL_STACKS.SPOT_ID = SPOTS.ID ";
 
     public static final String SQL_MICROSCOPY_IMAGE =
-            "select i.* from CHANNEL_STACKS, ACQUIRED_IMAGES, IMAGES as i "
+            "select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+                    + "from CHANNEL_STACKS, ACQUIRED_IMAGES, IMAGES as i "
                     + "where                                                                "
                     + "ACQUIRED_IMAGES.CHANNEL_ID = ?{1} and CHANNEL_STACKS.DS_ID = ?{2} and "
                     + "CHANNEL_STACKS.x = ?{3.x} and CHANNEL_STACKS.y = ?{3.y} and "
@@ -55,7 +57,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
                     + "ACQUIRED_IMAGES.CHANNEL_STACK_ID = CHANNEL_STACKS.ID ";
 
     public static final String SQL_HCS_IMAGE_REPRESENTATIVE =
-            "select i.* from CHANNEL_STACKS, SPOTS, ACQUIRED_IMAGES, IMAGES as i "
+            "select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+                    + "from CHANNEL_STACKS, SPOTS, ACQUIRED_IMAGES, IMAGES as i "
                     + "where                                        "
                     + "CHANNEL_STACKS.is_representative = 'T' and   "
                     + "CHANNEL_STACKS.DS_ID = ?{1} and              "
@@ -66,7 +69,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
                     + "CHANNEL_STACKS.SPOT_ID = SPOTS.ID ";
 
     public static final String SQL_MICROSCOPY_IMAGE_REPRESENTATIVE =
-            "select i.* from CHANNEL_STACKS, ACQUIRED_IMAGES, IMAGES as i "
+            "select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+                    + "from CHANNEL_STACKS, ACQUIRED_IMAGES, IMAGES as i "
                     + "where                                         "
                     + "CHANNEL_STACKS.is_representative = 'T' and    "
                     + "CHANNEL_STACKS.DS_ID = ?{1} and               "
@@ -117,6 +121,21 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
     public ImgImageDTO tryGetHCSRepresentativeThumbnail(long datasetId, Location wellLocation,
             long channelId);
 
+    /**
+     * @return all images of a given dataset and channel, every image is enriched with the
+     *         information about the spot to which it belongs.
+     */
+    @Select("select i.*, ai.image_transformer_factory as image_transformer_factory, "
+            +"s.id as spot_id, ai.id as acquired_image_id              "
+            + " from data_sets d                                       "
+            + " join channel_stacks cs on cs.ds_id = d.id              "
+            + " join spots s on cs.spot_id = s.id                      "
+            + " join acquired_images ai on ai.channel_stack_id = cs.id "
+            + " join channels ch on ai.channel_id = ch.id              "
+            + " join images i on i.id = ai.img_id                      "
+            + " where d.perm_id = ?{1} and ch.code = upper(?{2}) and s.id is NOT NULL")
+    public List<ImgImageEnrichedDTO> listHCSImages(String datasetPermId, String channelCode);
+
     // ---------------- Microscopy ---------------------------------
 
     /**
@@ -168,7 +187,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
     // ---------------- Generic ---------------------------------
 
     /** @return an image for the specified channel and channel stack or null */
-    @Select("select i.* from IMAGES as i "
+    @Select("select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+            + "from IMAGES as i                                      "
             + "join ACQUIRED_IMAGES on ACQUIRED_IMAGES.IMG_ID = i.ID "
             + "join CHANNEL_STACKS on ACQUIRED_IMAGES.CHANNEL_STACK_ID = CHANNEL_STACKS.ID "
             + "where                                                                "
@@ -179,7 +199,8 @@ public interface IImagingReadonlyQueryDAO extends BaseQuery
     public ImgImageDTO tryGetImage(long channelId, Long channelStackId, long datasetId);
 
     /** @return a thumbnail for the specified chanel and channel stack or null */
-    @Select("select i.* from IMAGES as i "
+    @Select("select i.*, ACQUIRED_IMAGES.image_transformer_factory as image_transformer_factory "
+            + "from IMAGES as i                                      "
             + "join ACQUIRED_IMAGES on ACQUIRED_IMAGES.THUMBNAIL_ID = i.ID "
             + "join CHANNEL_STACKS on ACQUIRED_IMAGES.CHANNEL_STACK_ID = CHANNEL_STACKS.ID "
             + "where                                                                "
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingTransformerDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingTransformerDAO.java
index f08a89140afb2167a9ee472cd45558577ac3a4aa..c9c45d9061666f7b934565fa8b501bb3c489789f 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingTransformerDAO.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingTransformerDAO.java
@@ -36,9 +36,10 @@ public interface IImagingTransformerDAO extends TransactionQuery
         { TransformerFactoryMapper.class, TypeMapper.class /* default */})
     public void saveTransformerFactoryForDataset(long datasetId, IImageTransformerFactory factory);
 
-    @Update(sql = "update images set image_transformer_factory = ?{2} where id = ?{1}", parameterBindings =
+    @Update(sql = "update acquired_images set image_transformer_factory = ?{2} where id = ?{1}", parameterBindings =
         { TransformerFactoryMapper.class, TypeMapper.class /* default */})
-    public void saveTransformerFactoryForImage(long imageId, IImageTransformerFactory factory);
+    public void saveTransformerFactoryForImage(long acquiredImageId,
+            IImageTransformerFactory factory);
 
     @Update(sql = "update channels set image_transformer_factory = ?{3} "
             + "where code = ?{2} and exp_id = ?{1}", parameterBindings =
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageDTO.java
index b3ccb8a864939d6876adee4b3734121a8a6a083f..631b59795552e9f4139732f9e5243c63f9398819 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageDTO.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageDTO.java
@@ -34,9 +34,8 @@ public class ImgImageDTO extends AbstractImageTransformerFactoryHolder
 
     @ResultColumn("COLOR")
     private String colorComponentOrNull;
-    
-    @SuppressWarnings("unused")
-    private ImgImageDTO()
+
+    protected ImgImageDTO()
     {
         // All Data-Object classes must have a default constructor.
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageEnrichedDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageEnrichedDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c9c20d7415ac2c32816790ebe88608750cbdc8b
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgImageEnrichedDTO.java
@@ -0,0 +1,57 @@
+/*
+ * 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.plugin.screening.shared.imaging.dataaccess;
+
+import net.lemnik.eodsql.ResultColumn;
+
+/**
+ * HCS image with additional information about the spot and acquired image id.
+ * 
+ * @author Tomasz Pylak
+ */
+public class ImgImageEnrichedDTO extends ImgImageDTO
+{
+    @ResultColumn("spot_id")
+    private long spotId;
+
+    @ResultColumn("acquired_image_id")
+    private long acquiredImageId;
+
+    @SuppressWarnings("unused")
+    private ImgImageEnrichedDTO()
+    {
+        // All Data-Object classes must have a default constructor.
+        super();
+    }
+
+    public ImgImageEnrichedDTO(long id, String filePath, Integer pageOrNull,
+            ColorComponent colorComponentOrNull)
+    {
+        super(id, filePath, pageOrNull, colorComponentOrNull);
+    }
+
+    public long getSpotId()
+    {
+        return spotId;
+    }
+
+    public long getAcquiredImageId()
+    {
+        return acquiredImageId;
+    }
+
+}
diff --git a/screening/source/sql/postgresql/010/schema-010.sql b/screening/source/sql/postgresql/010/schema-010.sql
index 681a48e7475b37745e2c199da0d840ea246cb176..d8cf0ea92b11a5dce9049cb6b03c1275b207b23f 100644
--- a/screening/source/sql/postgresql/010/schema-010.sql
+++ b/screening/source/sql/postgresql/010/schema-010.sql
@@ -139,7 +139,6 @@ CREATE TABLE IMAGES (
     PATH	FILE_PATH NOT NULL,
     PAGE	INTEGER,
     COLOR	COLOR_COMPONENT,
-    IMAGE_TRANSFORMER_FACTORY BYTEA,
     
     PRIMARY KEY (ID)
 );
@@ -149,6 +148,7 @@ CREATE TABLE ACQUIRED_IMAGES (
    
 		IMG_ID   TECH_ID NOT NULL,
 		THUMBNAIL_ID  TECH_ID,
+		IMAGE_TRANSFORMER_FACTORY BYTEA,
 
     CHANNEL_STACK_ID  TECH_ID NOT NULL,
     CHANNEL_ID  TECH_ID NOT NULL,
diff --git a/screening/source/sql/postgresql/migration/migration-009-010.sql b/screening/source/sql/postgresql/migration/migration-009-010.sql
index db3cf424f7c9734a1cbd670781f515b4eb433799..d182ca8cbc82a1dcdbb4268b9e2d864ab9e920fe 100644
--- a/screening/source/sql/postgresql/migration/migration-009-010.sql
+++ b/screening/source/sql/postgresql/migration/migration-009-010.sql
@@ -1,3 +1,3 @@
 -- Migration from 009 to 010
 
-ALTER TABLE images ADD COLUMN image_transformer_factory BYTEA;
\ No newline at end of file
+ALTER TABLE acquired_images ADD COLUMN image_transformer_factory BYTEA;
\ No newline at end of file
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java
index d7fae52662e581161656470db6b75aa8ef98ccfc..e3428dd866627daf9c57d35ea079856af0a09a90 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingQueryDAOTest.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgCh
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgContainerDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgDatasetDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageDTO;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgImageEnrichedDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgSpotDTO;
 
 /**
@@ -224,7 +225,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest
         addAcquiredImage(imageId1, channelStackId, datasetChannelId1);
         addAcquiredImage(imageId2, channelStackId, experimentChannelId2);
 
-        testGetHCSImage(datasetId, channelStackId, datasetChannelId1, experimentChannelId2);
+        testGetHCSImage(datasetId, channelStackId, datasetChannelId1, experimentChannelId2, spotId);
         testListChannelStacksAndSpots(datasetId, channelStackId, spotId);
     }
 
@@ -251,7 +252,7 @@ public class ImagingQueryDAOTest extends AbstractDBTest
     }
 
     private void testGetHCSImage(final long datasetId, final long channelStackId,
-            final long channelId1, final long channelId2)
+            final long channelId1, final long channelId2, long spotId)
     {
         Location tileLocation = new Location(X_TILE_COLUMN, Y_TILE_ROW);
         Location wellLocation = new Location(X_WELL_COLUMN, Y_WELL_ROW);
@@ -283,6 +284,10 @@ public class ImagingQueryDAOTest extends AbstractDBTest
 
         ImgImageDTO image2bis = dao.tryGetImage(channelId2, channelStackId, datasetId);
         assertEquals(image2, image2bis);
+
+        List<ImgImageEnrichedDTO> allImages = dao.listHCSImages(DS_PERM_ID, DS_CHANNEL);
+        assertEquals(1, allImages.size());
+        assertEquals(spotId, allImages.get(0).getSpotId());
     }
 
     private void testChannelMethods(final long experimentId, final long datasetId,