diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSImageDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSImageDatasetLoader.java
index 65bfd6d728ebf7897f97ab50cf946c45646ede1b..4ac9f4aa60abfaa1d732d0204efa2043c8baa847 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSImageDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/IHCSImageDatasetLoader.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.dss.etl;
 
-import ch.systemsx.cisd.bds.hcs.Location;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDatasetDownloadServlet.Size;
+import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSDatasetLoader;
 
 /**
@@ -29,6 +29,6 @@ public interface IHCSImageDatasetLoader extends IHCSDatasetLoader
      * @param chosenChannel start from 1
      * @return image (with absolute path, page and color)
      */
-    AbsoluteImageReference tryGetImage(String chosenChannel, Location wellLocation,
-            Location tileLocation, Size thumbnailSizeOrNull);
+    AbsoluteImageReference tryGetImage(String chosenChannel,
+            ImageChannelStackReference channelStackReference, Size thumbnailSizeOrNull);
 }
\ No newline at end of file
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 4cf24d106f04f919137f3d8c4f9c51eb00eff352..05f96a3579f3a379a51ebb3be1cbc3f48f2cde4e 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
@@ -31,7 +31,6 @@ 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;
@@ -40,7 +39,9 @@ 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.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtils;
+import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelStackReference.LocationImageChannelStackReference;
 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;
@@ -67,14 +68,20 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
      * @param chosenChannel start from 1
      * @return image (with absolute path, page and color)
      */
-    public AbsoluteImageReference tryGetImage(String chosenChannel, Location wellLocation,
-            Location tileLocation, Size thumbnailSizeOrNull)
+    public AbsoluteImageReference tryGetImage(String chosenChannel,
+            ImageChannelStackReference channelStackReference, Size thumbnailSizeOrNull)
     {
         assert StringUtils.isBlank(chosenChannel) == false;
-        assert tileLocation.getX() <= getDataset().getFieldNumberOfColumns();
-        assert tileLocation.getY() <= getDataset().getFieldNumberOfRows();
-        assert wellLocation.getX() <= getContainer().getNumberOfColumns();
-        assert wellLocation.getY() <= getContainer().getNumberOfRows();
+        LocationImageChannelStackReference stackLocations =
+                channelStackReference.tryGetChannelStackLocations();
+        if (stackLocations != null)
+        {
+            assert stackLocations.getTileLocation().getX() <= getDataset()
+                    .getFieldNumberOfColumns();
+            assert stackLocations.getTileLocation().getY() <= getDataset().getFieldNumberOfRows();
+            assert stackLocations.getWellLocation().getX() <= getContainer().getNumberOfColumns();
+            assert stackLocations.getWellLocation().getY() <= getContainer().getNumberOfRows();
+        }
 
         Long chosenChannelId =
                 query.tryGetChannelIdByChannelNameDatasetIdOrExperimentId(getDataset().getId(),
@@ -86,16 +93,13 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
 
         ImgImageDTO imageDTO;
         IContent content = null;
+        long datasetId = getDataset().getId();
         if (thumbnailSizeOrNull != null)
         {
-            imageDTO =
-                    query.tryGetThumbnail(chosenChannelId, getDataset().getId(), tileLocation,
-                            wellLocation);
+            imageDTO = tryGetThumbnail(chosenChannelId, channelStackReference, datasetId);
             if (imageDTO == null)
             {
-                imageDTO =
-                        query.tryGetImage(chosenChannelId, getDataset().getId(), tileLocation,
-                                wellLocation);
+                imageDTO = tryGetImage(chosenChannelId, channelStackReference, datasetId);
                 if (imageDTO != null)
                 {
                     content =
@@ -108,9 +112,7 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
             }
         } else
         {
-            imageDTO =
-                    query.tryGetImage(chosenChannelId, getDataset().getId(), tileLocation,
-                            wellLocation);
+            imageDTO = tryGetImage(chosenChannelId, channelStackReference, datasetId);
             if (imageDTO != null)
             {
                 content = contentRepository.getContent(imageDTO.getFilePath());
@@ -141,6 +143,42 @@ public class HCSImageDatasetLoader extends HCSDatasetLoader implements IHCSImage
         }
     }
 
+    private ImgImageDTO tryGetImage(long channelId,
+            ImageChannelStackReference channelStackReference, long datasetId)
+    {
+        LocationImageChannelStackReference locations =
+                channelStackReference.tryGetChannelStackLocations();
+        if (locations != null)
+        {
+            return query.tryGetImage(channelId, datasetId, locations.getTileLocation(), locations
+                    .getWellLocation());
+        } else
+        {
+            Long channelStackId = channelStackReference.tryGetChannelStackId();
+            assert channelStackId != null : "invalid specification of the channel stack: "
+                    + channelStackReference;
+            return query.tryGetImage(channelId, channelStackId, datasetId);
+        }
+    }
+
+    private ImgImageDTO tryGetThumbnail(long channelId,
+            ImageChannelStackReference channelStackReference, long datasetId)
+    {
+        LocationImageChannelStackReference locations =
+                channelStackReference.tryGetChannelStackLocations();
+        if (locations != null)
+        {
+            return query.tryGetThumbnail(channelId, datasetId, locations.getTileLocation(),
+                    locations.getWellLocation());
+        } else
+        {
+            Long channelStackId = channelStackReference.tryGetChannelStackId();
+            assert channelStackId != null : "invalid specification of the channel stack: "
+                    + channelStackReference;
+            return query.tryGetThumbnail(channelId, channelStackId, datasetId);
+        }
+    }
+
     private static IContent asContent(BufferedImage image, String fileType, String name, String id)
     {
         final ByteArrayOutputStream out = new ByteArrayOutputStream();
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java
index f576fccca8b7231cb1e54775052d868c7ecf325f..20d46f6f18af940d10248e032b3b7b99b0da1738 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/AbstractImagesDownloadServlet.java
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpSession;
 import ch.systemsx.cisd.bds.hcs.Location;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.TileImageReference;
 
 /**
@@ -55,6 +56,8 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ
 
         private final static String DATASET_CODE_PARAM = "dataset";
 
+        private final static String CHANNEL_STACK_ID_PARAM = "channelStackId";
+
         private final static String WELL_ROW_PARAM = "wellRow";
 
         private final static String WELL_COLUMN_PARAM = "wellCol";
@@ -77,15 +80,8 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ
             String displayModeText = request.getParameter(DISPLAY_MODE_PARAM);
             String displayMode = displayModeText == null ? "" : displayModeText;
             this.thumbnailSizeOrNull = tryAsThumbnailDisplayMode(displayMode);
-
             this.datasetCode = getParam(request, DATASET_CODE_PARAM);
-
-            int wellRow = getIntParam(request, WELL_ROW_PARAM);
-            int wellCol = getIntParam(request, WELL_COLUMN_PARAM);
-            int tileRow = getIntParam(request, TILE_ROW_PARAM);
-            int tileCol = getIntParam(request, TILE_COL_PARAM);
-            this.wellLocation = new Location(wellCol, wellRow);
-            this.tileLocation = new Location(tileCol, tileRow);
+            this.channelStackReference = getImageChannelStackReference(request);
 
             this.channel = getParam(request, CHANNEL_PARAM);
             String mergeChannelsText = request.getParameter(MERGE_CHANNELS_PARAM);
@@ -94,7 +90,37 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ
                             .equalsIgnoreCase("true");
         }
 
+        private ImageChannelStackReference getImageChannelStackReference(HttpServletRequest request)
+        {
+            Integer channelStackId = tryGetIntParam(request, CHANNEL_STACK_ID_PARAM);
+            if (channelStackId == null)
+            {
+                int wellRow = getIntParam(request, WELL_ROW_PARAM);
+                int wellCol = getIntParam(request, WELL_COLUMN_PARAM);
+                int tileRow = getIntParam(request, TILE_ROW_PARAM);
+                int tileCol = getIntParam(request, TILE_COL_PARAM);
+                Location wellLocation = new Location(wellCol, wellRow);
+                Location tileLocation = new Location(tileCol, tileRow);
+                return ImageChannelStackReference.createFromLocations(wellLocation, tileLocation);
+            } else
+            {
+                return ImageChannelStackReference.createFromId(channelStackId);
+            }
+        }
+
         private static int getIntParam(HttpServletRequest request, String paramName)
+        {
+
+            Integer value = tryGetIntParam(request, paramName);
+            if (value == null)
+            {
+                throw new UserFailureException("parameter " + paramName
+                        + " should be an integer, but is: " + value);
+            }
+            return value.intValue();
+        }
+
+        private static Integer tryGetIntParam(HttpServletRequest request, String paramName)
         {
             String value = getParam(request, paramName);
             try
@@ -102,8 +128,7 @@ abstract class AbstractImagesDownloadServlet extends AbstractDatasetDownloadServ
                 return Integer.valueOf(value);
             } catch (NumberFormatException e)
             {
-                throw new UserFailureException("parameter " + paramName
-                        + " should be an integer, but is: " + value);
+                return null;
             }
         }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelStackReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelStackReference.java
new file mode 100644
index 0000000000000000000000000000000000000000..5bf2953aeb4a8235b0c0f151cb7e88fa72205139
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelStackReference.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 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.images;
+
+import ch.systemsx.cisd.bds.hcs.Location;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+
+/**
+ * Identifies one channel stack, by well and tile location or by the technical id.
+ * 
+ * @author Tomasz Pylak
+ */
+public class ImageChannelStackReference extends AbstractHashable
+{
+    public static final class LocationImageChannelStackReference
+    {
+        protected Location wellLocation;
+
+        protected Location tileLocation;
+
+        public LocationImageChannelStackReference(Location wellLocation, Location tileLocation)
+        {
+            this.wellLocation = wellLocation;
+            this.tileLocation = tileLocation;
+        }
+
+        public Location getWellLocation()
+        {
+            return wellLocation;
+        }
+
+        public Location getTileLocation()
+        {
+            return tileLocation;
+        }
+    }
+
+    public static final ImageChannelStackReference createFromLocations(Location wellLocation,
+            Location tileLocation)
+    {
+        return new ImageChannelStackReference(new LocationImageChannelStackReference(wellLocation,
+                tileLocation), null);
+    }
+
+    public static final ImageChannelStackReference createFromId(long channelStackId)
+    {
+        return new ImageChannelStackReference(null, channelStackId);
+    }
+
+    private final LocationImageChannelStackReference locationRefOrNull;
+
+    private final Long idRefOrNull;
+
+    private ImageChannelStackReference(LocationImageChannelStackReference locationRefOrNull,
+            Long idRefOrNull)
+    {
+        assert locationRefOrNull == null || idRefOrNull == null;
+        assert locationRefOrNull != null || idRefOrNull != null;
+        this.locationRefOrNull = locationRefOrNull;
+        this.idRefOrNull = idRefOrNull;
+    }
+
+    public Long tryGetChannelStackId()
+    {
+        return idRefOrNull;
+    }
+
+    public LocationImageChannelStackReference tryGetChannelStackLocations()
+    {
+        return locationRefOrNull;
+    }
+
+}
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 a17e752863fc69e26787c97498b18a4a28c1d795..a7448c1b1560cfd1a9b998bd29a882f8dd8c8a6e 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.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
 
-import ch.systemsx.cisd.bds.hcs.Location;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
@@ -53,8 +52,6 @@ public class ImageChannelsUtils
     {
         IHCSImageDatasetLoader imageAccessor =
                 HCSImageDatasetLoaderFactory.create(datasetRoot, datasetCode);
-        Location wellLocation = params.getWellLocation();
-        Location tileLocation = params.getTileLocation();
         List<AbsoluteImageReference> images = new ArrayList<AbsoluteImageReference>();
 
         Size thumbnailSizeOrNull = params.tryGetThumbnailSize();
@@ -63,14 +60,14 @@ public class ImageChannelsUtils
             for (String chosenChannel : imageAccessor.getChannelsNames())
             {
                 AbsoluteImageReference image =
-                        getImage(imageAccessor, wellLocation, tileLocation, chosenChannel,
+                        getImage(imageAccessor, params.getChannelStack(), chosenChannel,
                                 thumbnailSizeOrNull);
                 images.add(image);
             }
         } else
         {
             AbsoluteImageReference image =
-                    getImage(imageAccessor, wellLocation, tileLocation, params.getChannel(),
+                    getImage(imageAccessor, params.getChannelStack(), params.getChannel(),
                             thumbnailSizeOrNull);
             images.add(image);
         }
@@ -242,12 +239,12 @@ public class ImageChannelsUtils
      * @throw {@link EnvironmentFailureException} when image does not exist
      */
     public static AbsoluteImageReference getImage(IHCSImageDatasetLoader imageAccessor,
-            Location wellLocation, Location tileLocation, String chosenChannel,
+            ImageChannelStackReference channelStackReference, String chosenChannel,
             Size thumbnailSizeOrNull)
     {
         AbsoluteImageReference image =
-                imageAccessor.tryGetImage(chosenChannel, wellLocation, tileLocation,
-                        thumbnailSizeOrNull);
+                imageAccessor
+                        .tryGetImage(chosenChannel, channelStackReference, thumbnailSizeOrNull);
         if (image != null)
         {
             return image;
@@ -255,7 +252,7 @@ public class ImageChannelsUtils
         {
             throw EnvironmentFailureException.fromTemplate("No "
                     + (thumbnailSizeOrNull != null ? "thumbnail" : "image")
-                    + " found for well %s, tile %s and channel %s", wellLocation, tileLocation,
+                    + " found for channel stack %s and channel %s", channelStackReference,
                     chosenChannel);
         }
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/TileImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/TileImageReference.java
index 79dc87914e6626d563ed4786ce9e0e85e2add149..e2c45bb876eb318a570858f68ced87d9bbd8cd33 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/TileImageReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/images/TileImageReference.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.dss.generic.server.images;
 
-import ch.systemsx.cisd.bds.hcs.Location;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDatasetDownloadServlet.Size;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
 
@@ -34,9 +33,7 @@ public class TileImageReference
 
     protected String datasetCode;
 
-    protected Location wellLocation;
-
-    protected Location tileLocation;
+    protected ImageChannelStackReference channelStackReference;
 
     protected boolean mergeAllChannels;
 
@@ -68,13 +65,8 @@ public class TileImageReference
         return channel;
     }
 
-    public Location getWellLocation()
-    {
-        return wellLocation;
-    }
-
-    public Location getTileLocation()
+    public ImageChannelStackReference getChannelStack()
     {
-        return tileLocation;
+        return channelStackReference;
     }
 }
\ No newline at end of file
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 c1c0e96785444139a13915207f5215d4bbbe4d96..391dced14b4b3dd7d784d63024b9d1eb56145c97 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
@@ -41,6 +41,7 @@ import ch.systemsx.cisd.openbis.dss.etl.IHCSImageDatasetLoader;
 import ch.systemsx.cisd.openbis.dss.generic.server.AbstractDssServiceRpc;
 import ch.systemsx.cisd.openbis.dss.generic.server.FeatureTableBuilder;
 import ch.systemsx.cisd.openbis.dss.generic.server.FeatureTableRow;
+import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.ImageChannelsUtils;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
@@ -179,9 +180,10 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
                 AbsoluteImageReference image;
                 for (String channelName : imageAccessor.getChannelsNames())
                 {
-                    image =
-                            imageAccessor.tryGetImage(channelName, new Location(col, row),
-                                    new Location(1, 1), null);
+                    ImageChannelStackReference channelStackReference =
+                            ImageChannelStackReference.createFromLocations(new Location(col, row),
+                                    new Location(1, 1));
+                    image = imageAccessor.tryGetImage(channelName, channelStackReference, null);
                     if (image != null)
                     {
                         return image.getContent();
@@ -330,7 +332,9 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc implements
                 getTileLocation(imageRef.getTile(), imageAccessor.getWellGeometry());
         try
         {
-            return ImageChannelsUtils.getImage(imageAccessor, wellLocation, tileLocation, imageRef
+            ImageChannelStackReference channelStackReference =
+                    ImageChannelStackReference.createFromLocations(wellLocation, tileLocation);
+            return ImageChannelsUtils.getImage(imageAccessor, channelStackReference, imageRef
                     .getChannel(), null);
         } catch (EnvironmentFailureException e)
         {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java
index 1979258268d57c7395a3184d30a0dc7bad121707..d9e8ebd3a3e6ebc132f4b5add99a133197314f45 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientService.java
@@ -103,7 +103,7 @@ public interface IScreeningClientService extends IClientService
             throws UserFailureException;
 
     /** Lists all images for a given well in the given dataset */
-    public List<ChannelStackImageReference> listChannelStackImages(String datasetCode,
+    public List<ChannelStackImageReference> listImageChannelStacks(String datasetCode,
             String datastoreCode, WellLocation wellLocation);
 
     /**
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java
index 085d93d67816a57b263208317e9ed678076af9c5..1f2f678291b251ee95ac0423d47dfd36175c9bd0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/IScreeningClientServiceAsync.java
@@ -88,9 +88,9 @@ public interface IScreeningClientServiceAsync extends IClientServiceAsync
             AsyncCallback<String> callback);
 
     /**
-     * @see IScreeningClientService#listChannelStackImages
+     * @see IScreeningClientService#listImageChannelStacks(String, String, WellLocation)
      */
-    public void listChannelStackImages(String datasetCode, String datastoreCode,
+    public void listImageChannelStacks(String datasetCode, String datastoreCode,
             WellLocation wellLocation,
             AsyncCallback<List<ChannelStackImageReference>> abstractAsyncCallback);
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
index e8a2bfbc17d3d30791d3038b9bd6459c3dd32e53..18f83c1663e571c27c8723a918fc3f271ffbba32 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
@@ -108,7 +108,7 @@ public class WellContentDialog extends Dialog
             final WellData wellData, final WellImages images,
             final DefaultChannelState channelState, final ScreeningViewContext viewContext)
     {
-        viewContext.getService().listChannelStackImages(images.getDatasetCode(),
+        viewContext.getService().listImageChannelStacks(images.getDatasetCode(),
                 images.getDatastoreCode(), images.getWellLocation(),
                 new AbstractAsyncCallback<List<ChannelStackImageReference>>(viewContext)
                     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java
index 4ca292062b986522a8f772c233630787307d9203..a65574ac2c2bd00bfb397cdf2459e0dd39fd101d 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/ScreeningClientService.java
@@ -16,7 +16,6 @@
 
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.server;
 
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -284,10 +283,11 @@ public final class ScreeningClientService extends AbstractClientService implemen
         return server.getVocabulary(sessionToken, ScreeningConstants.PLATE_GEOMETRY);
     }
 
-    public List<ChannelStackImageReference> listChannelStackImages(String datasetCode,
+    public List<ChannelStackImageReference> listImageChannelStacks(String datasetCode,
             String datastoreCode, WellLocation wellLocation)
     {
-        // TODO 2010-08-16, Tomasz Pylak: implement me!!!!!!!!!!!!
-        return new ArrayList<ChannelStackImageReference>();
+        final String sessionToken = getSessionToken();
+        return server
+                .listImageChannelStacks(sessionToken, datasetCode, datastoreCode, wellLocation);
     }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java
index b825235d185358589b5744c8cdce8713a8024fee..37db09a57dbd900ad202d26b33ffbcb36a832158 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/IScreeningBusinessObjectFactory.java
@@ -24,7 +24,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSDatasetLoader;
 
@@ -35,7 +34,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSDatasetLoade
  */
 public interface IScreeningBusinessObjectFactory
 {
-    public IHCSDatasetLoader createHCSDatasetLoader(final ExternalData dataSet);
+    public IHCSDatasetLoader createHCSDatasetLoader(String datasetCode, String datastoreCode);
 
     public ISampleBO createSampleBO(final Session session);
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java
index e778633e3b2598b87a26ffca55919f2e92bb9ab8..bdc3d77c9c48d50ea73b27b97a839fb57f16e5fb 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningBusinessObjectFactory.java
@@ -28,7 +28,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.plugin.AbstractPluginBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningDAOFactory;
@@ -53,11 +52,10 @@ public final class ScreeningBusinessObjectFactory extends AbstractPluginBusiness
     {
     }
 
-    public IHCSDatasetLoader createHCSDatasetLoader(ExternalData dataSet)
+    public IHCSDatasetLoader createHCSDatasetLoader(String datasetCode, String datastoreCode)
     {
-        String dssCode = dataSet.getDataStore().getCode();
-        String dataSetCode = dataSet.getCode();
-        return new HCSDatasetLoader(specificDAOFactory.getImagingQueryDAO(dssCode), dataSetCode);
+        return new HCSDatasetLoader(specificDAOFactory.getImagingQueryDAO(datastoreCode),
+                datasetCode);
     }
 
     public final ISampleBO createSampleBO(final Session session)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
index 37421c61e782f502651823ab3723a95cc2a404da..b550a89a021d88e5515d4df4aa78fbbf474c6d58 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
@@ -59,10 +59,12 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellMaterialMapping;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellReferenceWithDatasets;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateMaterialsSearchCriteria;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 
 /**
  * The concrete {@link IScreeningServer} implementation.
@@ -146,6 +148,14 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl
                 materialCriteria, true);
     }
 
+    public List<ChannelStackImageReference> listImageChannelStacks(String sessionToken,
+            String datasetCode, String datastoreCode, WellLocation wellLocation)
+    {
+        Session session = getSession(sessionToken);
+        return PlateContentLoader.loadImageChannelStacks(session, businessObjectFactory,
+                datasetCode, datastoreCode, wellLocation);
+    }
+
     public TableModel loadImageAnalysisForExperiment(String sessionToken, TechId experimentId)
     {
         Session session = getSession(sessionToken);
@@ -260,5 +270,4 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl
     {
         return MINOR_VERSION;
     }
-
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
index b7e57f78fa0fce79274948d23f41d4fbc5af4838..c0868ed59a1584c27851175fd326febe4e2704c3 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerLogger.java
@@ -42,10 +42,12 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Plate;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellMaterialMapping;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateWellReferenceWithDatasets;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateMaterialsSearchCriteria;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 
 /**
  * The <i>screening</i> specific {@link AbstractServerLogger} extension.
@@ -94,6 +96,14 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree
         return null;
     }
 
+    public List<ChannelStackImageReference> listImageChannelStacks(String sessionToken,
+            String datasetCode, String datastoreCode, WellLocation wellLocation)
+    {
+        logAccess(sessionToken, "listImageChannelStacks", "dataset(%s) well(%s)", datasetCode,
+                wellLocation);
+        return null;
+    }
+
     public ExternalData getDataSetInfo(String sessionToken, TechId datasetId)
     {
         logAccess(sessionToken, "getDataSetInfo", "datasetId(%s)", datasetId.getId());
@@ -189,8 +199,8 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree
     {
         if (materialTypeIdentifierOrNull != null)
         {
-            logAccess(sessionToken, "listPlateMaterialMapping", "plates(%s), materialType(%s)", plates,
-                    materialTypeIdentifierOrNull);
+            logAccess(sessionToken, "listPlateMaterialMapping", "plates(%s), materialType(%s)",
+                    plates, materialTypeIdentifierOrNull);
         } else
         {
             logAccess(sessionToken, "listPlateMaterialMapping", "plates(%s)", plates);
@@ -207,5 +217,4 @@ final class ScreeningServerLogger extends AbstractServerLogger implements IScree
     {
         return ScreeningServer.MINOR_VERSION;
     }
-
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/GenePlateLocationsLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/GenePlateLocationsLoader.java
index 4368104d7b622710f94265deb0e1ede0da317e37..3b771378789f1ed72d01c930f246082ae0a4c7c0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/GenePlateLocationsLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/GenePlateLocationsLoader.java
@@ -207,12 +207,19 @@ public class GenePlateLocationsLoader
         List<PlateImageParameters> imageParameters = new ArrayList<PlateImageParameters>();
         for (ExternalData dataSet : imageDatasets)
         {
-            final IHCSDatasetLoader loader = businessObjectFactory.createHCSDatasetLoader(dataSet);
+            final IHCSDatasetLoader loader = createHCSDatasetLoader(dataSet);
             imageParameters.add(PlateImageParametersFactory.create(loader));
         }
         return asDatasetToParamsMap(imageParameters);
     }
 
+    private IHCSDatasetLoader createHCSDatasetLoader(ExternalData dataSet)
+    {
+        String datastoreCode = dataSet.getDataStore().getCode();
+        String datasetCode = dataSet.getCode();
+        return businessObjectFactory.createHCSDatasetLoader(datasetCode, datastoreCode);
+    }
+
     private static Map<String/* dataset code */, PlateImageParameters> asDatasetToParamsMap(
             List<PlateImageParameters> imageParameters)
     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
index f832ef5ecc1de71aa7eb53099638c2d93b61b268..f47bcc96a8498d6e00639a04b749ab706a0682fc 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/PlateContentLoader.java
@@ -40,6 +40,7 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.Geometry;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent;
@@ -92,6 +93,17 @@ public class PlateContentLoader
                 .getPlateContentForDataset(datasetId);
     }
 
+    /**
+     * Loads information about all channels stacks of a given well in a given dataset.
+     */
+    public static List<ChannelStackImageReference> loadImageChannelStacks(Session session,
+            IScreeningBusinessObjectFactory businessObjectFactory, String datasetCode,
+            String datastoreCode, WellLocation wellLocation)
+    {
+        return new PlateContentLoader(session, businessObjectFactory).loadImageChannelStacks(
+                datasetCode, datastoreCode, wellLocation);
+    }
+
     private final Session session;
 
     private final IScreeningBusinessObjectFactory businessObjectFactory;
@@ -273,10 +285,17 @@ public class PlateContentLoader
 
     private PlateImageParameters loadImageParams(ExternalData dataset)
     {
-        final IHCSDatasetLoader loader = businessObjectFactory.createHCSDatasetLoader(dataset);
+        final IHCSDatasetLoader loader = createHCSDatasetLoader(dataset);
         return PlateImageParametersFactory.create(loader);
     }
 
+    private IHCSDatasetLoader createHCSDatasetLoader(ExternalData dataSet)
+    {
+        String datastoreCode = dataSet.getDataStore().getCode();
+        String datasetCode = dataSet.getCode();
+        return businessObjectFactory.createHCSDatasetLoader(datasetCode, datastoreCode);
+    }
+
     private static List<WellMetadata> createWells(List<Sample> wellSamples)
     {
         List<WellMetadata> wells = new ArrayList<WellMetadata>();
@@ -305,4 +324,12 @@ public class PlateContentLoader
         return new ListOrSearchSampleCriteria(ListOrSearchSampleCriteria
                 .createForContainer(plateId));
     }
+
+    private List<ChannelStackImageReference> loadImageChannelStacks(String datasetCode,
+            String datastoreCode, WellLocation wellLocation)
+    {
+        IHCSDatasetLoader datasetLoader =
+                businessObjectFactory.createHCSDatasetLoader(datasetCode, datastoreCode);
+        return datasetLoader.listImageChannelStacks(wellLocation);
+    }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java
index 19cd120571e24e70e11995ca9ef7c7e0e66a7825..dd04e5ace82cda2f4eedab0a1e5fe7d34ed692a5 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/IScreeningServer.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCodePredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleTechIdPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.DataSetTechIdPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
@@ -37,10 +38,12 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.authorization.PlateMaterialsSearchCriteriaPredicate;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.authorization.WellContentValidator;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateContent;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateImages;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.PlateMaterialsSearchCriteria;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 
 /**
  * The <i>screening</i> server. Used internally.
@@ -74,6 +77,12 @@ public interface IScreeningServer extends IServer
             String sessionToken,
             @AuthorizationGuard(guardClass = PlateMaterialsSearchCriteriaPredicate.class) PlateMaterialsSearchCriteria materialCriteria);
 
+    @Transactional
+    @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
+    public List<ChannelStackImageReference> listImageChannelStacks(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String datasetCode,
+            String datastoreCode, WellLocation wellLocation);
+
     /**
      * Loads all analysis results from all existing image-analysis datasets connected with the
      * specified experiment. It is assumed that all datasets are CSV files with the same headers.
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ChannelStackImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ChannelStackImageReference.java
index bdd0a67c72add02191d1e38c4d5c09a0d90e2406..d600d4d70bf49bb2dcd53a03c474b09614dd949d 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ChannelStackImageReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ChannelStackImageReference.java
@@ -88,7 +88,8 @@ public class ChannelStackImageReference implements IsSerializable,
             desc += ", z=" + zOrNull;
         }
 
-        return "tile [" + tileRow + "," + tileCol + "]" + desc;
+        return "channelStack=" + channelStackTechId + ", tile[" + tileRow + "," + tileCol + "]"
+                + desc;
     }
 
     public int compareTo(ChannelStackImageReference other)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java
index eb86a4ad9d1f9198e28169032268bd69f2680232..14ec2678eec9a92673f5d9e59b88eba24520c1a6 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/HCSDatasetLoader.java
@@ -21,7 +21,10 @@ import java.util.Arrays;
 import java.util.List;
 
 import ch.systemsx.cisd.bds.hcs.Geometry;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingQueryDAO;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelStackDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgContainerDTO;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgDatasetDTO;
 
@@ -115,4 +118,29 @@ public class HCSDatasetLoader implements IHCSDatasetLoader
     {
         return dataset.getIsMultidimensional();
     }
+
+    public List<ChannelStackImageReference> listImageChannelStacks(WellLocation wellLocation)
+    {
+        int spotYRow = wellLocation.getRow();
+        int spotXColumn = wellLocation.getColumn();
+        List<ImgChannelStackDTO> stacks =
+                query.listChannelStacks(dataset.getId(), spotXColumn, spotYRow);
+        return convert(stacks);
+    }
+
+    private static List<ChannelStackImageReference> convert(List<ImgChannelStackDTO> stacks)
+    {
+        List<ChannelStackImageReference> result = new ArrayList<ChannelStackImageReference>();
+        for (ImgChannelStackDTO stack : stacks)
+        {
+            result.add(convert(stack));
+        }
+        return result;
+    }
+
+    private static ChannelStackImageReference convert(ImgChannelStackDTO stack)
+    {
+        return new ChannelStackImageReference(stack.getId(), stack.getRow(), stack.getColumn(),
+                stack.getT(), stack.getZ());
+    }
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/IHCSDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/IHCSDatasetLoader.java
index c8c5c933b1302c5689c3b48486acb38ec3a268c4..a2c6bbd0b31db7f1222719dbb2e5874d595148a8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/IHCSDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/IHCSDatasetLoader.java
@@ -19,6 +19,8 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging;
 import java.util.List;
 
 import ch.systemsx.cisd.bds.hcs.Geometry;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ChannelStackImageReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 
 /**
  * @author Tomasz Pylak
@@ -39,4 +41,8 @@ public interface IHCSDatasetLoader
 
     boolean isMultidimensional();
 
+    /**
+     * Loads information about all channels stacks of a given well.
+     */
+    List<ChannelStackImageReference> listImageChannelStacks(WellLocation wellLocation);
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingQueryDAO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingQueryDAO.java
index 123aa2995ddc0889d1e01cb7aba3148d6c85724f..59d357e52a20c146e801f9992aa6a71890ed7ad5 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingQueryDAO.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/IImagingQueryDAO.java
@@ -43,18 +43,47 @@ public interface IImagingQueryDAO extends TransactionQuery
                     + "CHANNEL_STACKS.SPOT_ID = SPOTS.ID ";
 
     public static final String SQL_NO_MULTIDIMENTIONAL_DATA_COND =
-    // " and CHANNEL_STACKS.T_in_SEC is NULL and CHANNEL_STACKS.Z_in_M is NULL";
             " order by CHANNEL_STACKS.T_in_SEC, CHANNEL_STACKS.Z_in_M limit 1";
 
+    /**
+     * @return an image for the specified chanel, well and tile. If many images for different
+     *         timepoints or depths exist, the first one is returned.
+     */
     @Select(SQL_IMAGE + " and ACQUIRED_IMAGES.IMG_ID = i.ID " + SQL_NO_MULTIDIMENTIONAL_DATA_COND)
     public ImgImageDTO tryGetImage(long channelId, long datasetId, Location tileLocation,
             Location wellLocation);
 
+    /**
+     * @return a thumbnail for the specified chanel, well and tile. If many images for different
+     *         timepoints or depths exist, the first one is returned.
+     */
     @Select(SQL_IMAGE + " and ACQUIRED_IMAGES.THUMBNAIL_ID = i.ID "
             + SQL_NO_MULTIDIMENTIONAL_DATA_COND)
     public ImgImageDTO tryGetThumbnail(long channelId, long datasetId, Location tileLocation,
             Location wellLocation);
 
+    /** @return an image for the specified chanel and channel stack or null */
+    @Select("select i.* 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                                                                "
+            + "ACQUIRED_IMAGES.CHANNEL_ID = ?{1} and CHANNEL_STACKS.ID = ?{2} and "
+            + "CHANNEL_STACKS.DS_ID = ?{3}")
+    // The condition on dataset equality is just to ensure that the stack channel belongs the right
+    // dataset.
+    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 "
+            + "join ACQUIRED_IMAGES on ACQUIRED_IMAGES.THUMBNAIL_ID = i.ID "
+            + "join CHANNEL_STACKS on ACQUIRED_IMAGES.CHANNEL_STACK_ID = CHANNEL_STACKS.ID "
+            + "where                                                                "
+            + "ACQUIRED_IMAGES.CHANNEL_ID = ?{1} and CHANNEL_STACKS.ID = ?{2} and "
+            + "CHANNEL_STACKS.DS_ID = ?{3}")
+    // The condition on dataset equality is just to ensure that the stack channel belongs the right
+    // dataset.
+    public ImgImageDTO tryGetThumbnail(long channelId, Long channelStackId, long datasetId);
+
     // simple getters
 
     @Select("select ID from EXPERIMENTS where PERM_ID = ?{1}")
@@ -69,6 +98,10 @@ public interface IImagingQueryDAO extends TransactionQuery
     @Select("select * from CONTAINERS where ID = ?{1}")
     public ImgContainerDTO getContainerById(long containerId);
 
+    @Select("select * from CHANNEL_STACKS cs join SPOTS s on s.id = cs.spot_id where "
+            + "cs.ds_id = ?{1} and s.x = ?{2} and s.y = ?{3}")
+    public List<ImgChannelStackDTO> listChannelStacks(long datasetId, int spotX, int spotY);
+
     @Select("select count(*) from CHANNELS where DS_ID = ?{1} or EXP_ID = ?{2}")
     public int countChannelByDatasetIdOrExperimentId(long datasetId, long experimentId);
 
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImagingQueryDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImagingQueryDAOTest.java
index e43394408cf7538af2ea96e52406dc26d16f0389..2ffc31f81b07f93d08ac5fc91bc091ae9778bae6 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImagingQueryDAOTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImagingQueryDAOTest.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.assertNull;
 
 import java.sql.SQLException;
 import java.util.Arrays;
@@ -28,15 +29,6 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.bds.hcs.Location;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ColorComponent;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.IImagingQueryDAO;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgAcquiredImageDTO;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelDTO;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ImgChannelStackDTO;
-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.ImgSpotDTO;
 
 /**
  * Tests for {@link IImagingQueryDAO}.
@@ -118,22 +110,50 @@ public class ImagingQueryDAOTest extends AbstractDBTest
         addAcquiredImage(imageId1, channelStackId, channelId1);
         addAcquiredImage(imageId2, channelStackId, channelId2);
 
-        testGetImage(datasetId, channelId1, channelId2);
+        testGetImage(datasetId, channelStackId, channelId1, channelId2);
+        testListChannelStacks(datasetId, channelStackId, spotId);
     }
 
-    private void testGetImage(final long datasetId, final long channelId1, final long channelId2)
+    private void testListChannelStacks(long datasetId, long channelStackId, long spotId)
     {
-        ImgImageDTO image1 =
-                dao.tryGetImage(channelId1, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW),
-                        new Location(X_TILE_COLUMN, Y_TILE_ROW));
+        List<ImgChannelStackDTO> stack =
+                dao.listChannelStacks(datasetId, X_WELL_COLUMN, Y_WELL_ROW);
+        assertEquals(1, stack.size());
+        ImgChannelStackDTO stackDTO = stack.get(0);
+        assertEquals(channelStackId, stackDTO.getId());
+        assertEquals(spotId, stackDTO.getSpotId());
+        assertEquals(datasetId, stackDTO.getDatasetId());
+        assertEquals(TIMEPOINT, stackDTO.getT());
+        assertNull(stackDTO.getZ());
+        assertEquals(Y_WELL_ROW, stackDTO.getRow().intValue());
+        assertEquals(X_WELL_COLUMN, stackDTO.getColumn().intValue());
+    }
+
+    private void testGetImage(final long datasetId, final long channelStackId,
+            final long channelId1, final long channelId2)
+    {
+        Location tileLocation = new Location(X_TILE_COLUMN, Y_TILE_ROW);
+        Location wellLocation = new Location(X_WELL_COLUMN, Y_WELL_ROW);
+        ImgImageDTO image1 = dao.tryGetImage(channelId1, datasetId, tileLocation, wellLocation);
         assertEquals(PATH1, image1.getFilePath());
         assertEquals(ColorComponent.BLUE, image1.getColorComponent());
 
-        ImgImageDTO image2 =
-                dao.tryGetImage(channelId2, datasetId, new Location(X_WELL_COLUMN, Y_WELL_ROW),
-                        new Location(X_TILE_COLUMN, Y_TILE_ROW));
+        ImgImageDTO image1bis = dao.tryGetImage(channelId1, channelStackId, datasetId);
+        assertEquals(image1, image1bis);
+
+        ImgImageDTO thumbnail1 =
+                dao.tryGetThumbnail(channelId1, datasetId, tileLocation, wellLocation);
+        assertEquals(image1, thumbnail1);
+
+        ImgImageDTO thumbnail1bis = dao.tryGetThumbnail(channelId1, channelStackId, datasetId);
+        assertEquals(thumbnail1, thumbnail1bis);
+
+        ImgImageDTO image2 = dao.tryGetImage(channelId2, datasetId, wellLocation, tileLocation);
         assertEquals(PATH2, image2.getFilePath());
         assertEquals(ColorComponent.RED, image2.getColorComponent());
+
+        ImgImageDTO image2bis = dao.tryGetImage(channelId2, channelStackId, datasetId);
+        assertEquals(image2, image2bis);
     }
 
     private void testChannelMethods(final long experimentId, final long datasetId,
@@ -259,6 +279,9 @@ public class ImagingQueryDAOTest extends AbstractDBTest
     {
         final ImgAcquiredImageDTO acquiredImage = new ImgAcquiredImageDTO();
         acquiredImage.setImageId(imageId);
+        // we set the same image to be its thumbnail to simplify tests
+        acquiredImage.setThumbnailId(imageId);
+
         acquiredImage.setChannelStackId(channelStackId);
         acquiredImage.setChannelId(channelId);