diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
index df7ab282b3c048125eb9f53be8aee3211088d167..1adc6e9a4c3a8e4b8a896f983c9f749efc977c13 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbsoluteImageReference.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.dss.etl;
 
-import ch.systemsx.cisd.base.image.IImageTransformerFactory;
 import ch.systemsx.cisd.common.io.IContent;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess.ColorComponent;
 
@@ -35,9 +35,7 @@ public class AbsoluteImageReference extends AbstractImageReference
 
     private final RequestedImageSize imageSize;
 
-    private IImageTransformerFactory transformerFactory;
-
-    private IImageTransformerFactory transformerFactoryForMergedChannels;
+    private final ImageTransfomationFactories imageTransfomationFactories;
 
     // This is an artificial value which helps to keep coloring channels constant. Starts with 0.
     // Unique for a given experiment or dataset (if channels are per dataset).
@@ -47,14 +45,18 @@ public class AbsoluteImageReference extends AbstractImageReference
      * @param content the content before choosing the color component and the page
      */
     public AbsoluteImageReference(IContent content, String uniqueId, Integer pageOrNull,
-            ColorComponent colorComponentOrNull, RequestedImageSize imageSize, int channelIndex)
+            ColorComponent colorComponentOrNull, RequestedImageSize imageSize, int channelIndex,
+            ImageTransfomationFactories imageTransfomationFactories)
     {
         super(pageOrNull, colorComponentOrNull);
         assert imageSize != null : "image size is null";
+        assert imageTransfomationFactories != null : "imageTransfomationFactories is null";
+
         this.content = content;
         this.uniqueId = uniqueId;
         this.imageSize = imageSize;
         this.channelIndex = channelIndex;
+        this.imageTransfomationFactories = imageTransfomationFactories;
     }
 
     /**
@@ -76,14 +78,9 @@ public class AbsoluteImageReference extends AbstractImageReference
         return imageSize;
     }
 
-    public final IImageTransformerFactory getTransformerFactory()
-    {
-        return transformerFactory;
-    }
-
-    public final IImageTransformerFactory getTransformerFactoryForMergedChannels()
+    public ImageTransfomationFactories getImageTransfomationFactories()
     {
-        return transformerFactoryForMergedChannels;
+        return imageTransfomationFactories;
     }
 
     public int getChannelIndex()
@@ -91,26 +88,11 @@ public class AbsoluteImageReference extends AbstractImageReference
         return channelIndex;
     }
 
-    public final void setTransformerFactoryForMergedChannels(
-            IImageTransformerFactory transformerFactoryForMergedChannels)
-    {
-        this.transformerFactoryForMergedChannels = transformerFactoryForMergedChannels;
-    }
-
-    public final void setTransformerFactory(IImageTransformerFactory transformerFactory)
-    {
-        this.transformerFactory = transformerFactory;
-    }
-
     public AbsoluteImageReference createWithoutColorComponent()
     {
         ColorComponent colorComponent = null;
-        AbsoluteImageReference ref =
-                new AbsoluteImageReference(content, uniqueId, tryGetPage(), colorComponent,
-                        imageSize, channelIndex);
-        ref.setTransformerFactory(transformerFactory);
-        ref.setTransformerFactoryForMergedChannels(transformerFactoryForMergedChannels);
-        return ref;
+        return new AbsoluteImageReference(content, uniqueId, tryGetPage(), colorComponent,
+                imageSize, channelIndex, imageTransfomationFactories);
 
     }
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java
index 6f07a138145a1895049916c414d2845383a0d6cc..c24810d9657f77db13f96cc407a0fd450dbf4f55 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dataaccess/ImagingDatasetLoader.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.IContentRepository;
 import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference.HCSChannelStackByLocationReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference.MicroscopyChannelStackByLocationReference;
@@ -91,20 +92,21 @@ public class ImagingDatasetLoader extends HCSDatasetLoader implements IImagingDa
         String path = imageDTO.getFilePath();
         IContent content = contentRepository.getContent(path);
         ColorComponent colorComponent = imageDTO.getColorComponent();
-        AbsoluteImageReference imgRef =
-                new AbsoluteImageReference(content, path, imageDTO.getPage(), colorComponent,
-                        imageSize, getChannelIndex(channel));
-        imgRef.setTransformerFactoryForMergedChannels(tryGetImageTransformerFactoryForMergedChannels());
-        imgRef.setTransformerFactory(channel.getImageTransformerFactory());
-        return imgRef;
+        ImageTransfomationFactories imageTransfomationFactories = new ImageTransfomationFactories();
+        imageTransfomationFactories
+                .setForMergedChannels(tryGetImageTransformerFactoryForMergedChannels());
+        imageTransfomationFactories.setForChannel(channel.tryGetImageTransformerFactory());
+        imageTransfomationFactories.setForImage(imageDTO.tryGetImageTransformerFactory());
+        return new AbsoluteImageReference(content, path, imageDTO.getPage(), colorComponent,
+                imageSize, getChannelIndex(channel), imageTransfomationFactories);
     }
 
     private IImageTransformerFactory tryGetImageTransformerFactoryForMergedChannels()
     {
-        IImageTransformerFactory imageTransformerFactory = dataset.getImageTransformerFactory();
+        IImageTransformerFactory imageTransformerFactory = dataset.tryGetImageTransformerFactory();
         if (imageTransformerFactory == null && experimentOrNull != null)
         {
-            imageTransformerFactory = experimentOrNull.getImageTransformerFactory();
+            imageTransformerFactory = experimentOrNull.tryGetImageTransformerFactory();
         }
         return imageTransformerFactory;
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/ImageTransfomationFactories.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/ImageTransfomationFactories.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a6aa9f26c661afaf8029fc3fc5d1546514ec10d
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/dto/ImageTransfomationFactories.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.dss.etl.dto;
+
+import ch.systemsx.cisd.base.image.IImageTransformerFactory;
+
+/**
+ * Stores transformations defined for the image on different levels.
+ * 
+ * @author Tomasz Pylak
+ */
+public class ImageTransfomationFactories
+{
+    // applied when a single channel is displayed
+    private IImageTransformerFactory singleChannel;
+
+    // applied when all channels of the image are merged
+    private IImageTransformerFactory mergedChannels;
+
+    // individual transformation for the image
+    private IImageTransformerFactory image;
+
+    public IImageTransformerFactory tryGetForChannel(boolean areChannelsMerged)
+    {
+        return areChannelsMerged ? mergedChannels : singleChannel;
+    }
+
+    public void setForChannel(IImageTransformerFactory transformerFactoryForChannel)
+    {
+        this.singleChannel = transformerFactoryForChannel;
+    }
+
+    public void setForMergedChannels(IImageTransformerFactory transformerFactoryForMergedChannels)
+    {
+        this.mergedChannels = transformerFactoryForMergedChannels;
+    }
+
+    public IImageTransformerFactory tryGetForImage()
+    {
+        return image;
+    }
+
+    public void setForImage(IImageTransformerFactory transformerFactoryForImage)
+    {
+        this.image = transformerFactoryForImage;
+    }
+
+}
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 1f50bd38599f764c69e074b7f7a7a43684c78207..4348e6bfb240f222da0de87272e88af4e43b8a5d 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
@@ -43,6 +43,7 @@ import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.HCSImageDatasetLoaderFactory;
 import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.generic.server.ResponseContentStream;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.DatasetAcquiredImagesReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference;
@@ -206,6 +207,8 @@ public class ImageChannelsUtils
         return mergeChannels(imageContents, transform, mergeAllChannels);
     }
 
+    // Check if all exiting channels of the image should be merged (and not a single one or a
+    // subset).
     // We want to treat the case where merged channels were requested in the same way as the case
     // where all channel names have been enumerated.
     private boolean isMergeAllChannels(DatasetAcquiredImagesReference imageChannels)
@@ -420,14 +423,8 @@ public class ImageChannelsUtils
     private static BufferedImage calculateAndTransformSingleImage(
             AbsoluteImageReference imageReference, boolean transform, boolean allChannelsMerged)
     {
-        IImageTransformerFactory transformerFactory = null;
-        if (transform)
-        {
-            transformerFactory =
-                    allChannelsMerged ? imageReference.getTransformerFactoryForMergedChannels()
-                            : imageReference.getTransformerFactory();
-        }
-        return transform(calculateSingleImage(imageReference), transformerFactory);
+        BufferedImage image = calculateSingleImage(imageReference);
+        return transform(image, imageReference, transform, allChannelsMerged);
     }
 
     private static BufferedImage calculateSingleImage(AbsoluteImageReference imageReference)
@@ -489,31 +486,48 @@ public class ImageChannelsUtils
     private static BufferedImage mergeChannels(List<AbsoluteImageReference> imageReferences,
             boolean transform, boolean allChannelsMerged)
     {
+        AbsoluteImageReference singleImageReference = imageReferences.get(0);
         if (imageReferences.size() == 1)
         {
-            AbsoluteImageReference imageReference = imageReferences.get(0);
-            return calculateAndTransformSingleImage(imageReference, transform, allChannelsMerged);
+            return calculateAndTransformSingleImage(singleImageReference, transform,
+                    allChannelsMerged);
         } else
         {
             List<ImageWithReference> images = calculateSingleImages(imageReferences);
             BufferedImage mergedImage = mergeImages(images);
             // NOTE: even if we are not merging all the channels but just few of them we use the
             // merged-channel transformation
-            IImageTransformerFactory transformerFactory =
-                    transform ? imageReferences.get(0).getTransformerFactoryForMergedChannels()
-                            : null;
-            return transform(mergedImage, transformerFactory);
+            return transform(mergedImage, singleImageReference, transform, true);
+        }
+    }
+
+    private static BufferedImage transform(BufferedImage image,
+            AbsoluteImageReference imageReference, boolean transform, boolean allChannelsMerged)
+    {
+        BufferedImage resultImage = image;
+        ImageTransfomationFactories transfomations =
+                imageReference.getImageTransfomationFactories();
+        // image level transformation is applied always, as it cannot be applied or changed in
+        // external image viewer
+        resultImage = applyImageTransformation(resultImage, transfomations.tryGetForImage());
+
+        if (transform == false)
+        {
+            return resultImage;
         }
+        IImageTransformerFactory channelLevelTransformation =
+                transfomations.tryGetForChannel(allChannelsMerged);
+        return applyImageTransformation(resultImage, channelLevelTransformation);
     }
 
-    private static BufferedImage transform(BufferedImage input,
-            IImageTransformerFactory factoryOrNull)
+    private static BufferedImage applyImageTransformation(BufferedImage image,
+            IImageTransformerFactory transformerFactoryOrNull)
     {
-        if (factoryOrNull == null)
+        if (transformerFactoryOrNull == null)
         {
-            return input;
+            return image;
         }
-        return factoryOrNull.createTransformer().transform(input);
+        return transformerFactoryOrNull.createTransformer().transform(image);
     }
 
     private static class ImageWithReference
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 1dc3538e0625960cee66135ba64faf850e8e134f..ee825310f453748da5ec15663e99dfcf35d83b24 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
@@ -127,8 +127,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
 
     DssServiceRpcScreening(String storeRootDir, IImagingReadonlyQueryDAO dao,
             IImagingTransformerDAO transformerDAO, IEncapsulatedOpenBISService service,
-            IShareIdManager shareIdManager,
-            boolean registerAtNameService)
+            IShareIdManager shareIdManager, boolean registerAtNameService)
     {
         super(service, shareIdManager);
         this.dao = dao;
@@ -747,14 +746,7 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
                     + dataSetIdentifiers);
         }
         String experimentPermID = experimentPermIDs.iterator().next();
-        if (isMergedChannel(channel))
-        {
-            return getDAO().tryGetExperimentByPermId(experimentPermID).getImageTransformerFactory();
-        } else
-        {
-            return getDAO().tryGetChannelForExperimentPermId(experimentPermID, channel)
-                    .getImageTransformerFactory();
-        }
+        return tryGetImageTransformerFactoryForExperiment(experimentPermID, channel);
     }
 
     private Set<String> getExperimentPermIDs(String sessionToken,
@@ -781,11 +773,24 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
         ImgDatasetDTO dataset = getImagingDataset(datasetIdentifier);
         if (isMergedChannel(channel))
         {
-            return dataset.getImageTransformerFactory();
+            return dataset.tryGetImageTransformerFactory();
         } else
         {
             return getDAO().tryGetChannelForDataset(dataset.getId(), channel)
-                    .getImageTransformerFactory();
+                    .tryGetImageTransformerFactory();
+        }
+    }
+
+    private IImageTransformerFactory tryGetImageTransformerFactoryForExperiment(
+            String experimentPermID, String channel)
+    {
+        if (isMergedChannel(channel))
+        {
+            return getDAO().tryGetExperimentByPermId(experimentPermID).tryGetImageTransformerFactory();
+        } else
+        {
+            return getDAO().tryGetChannelForExperimentPermId(experimentPermID, channel)
+                    .tryGetImageTransformerFactory();
         }
     }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/AbstractImageTransformerFactoryHolder.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/AbstractImageTransformerFactoryHolder.java
index b4ad0f7adec2ddb44b5cd1fc7a345731cbc92e44..4eead6285eb9353de40a17d243849353e49f8d92 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/AbstractImageTransformerFactoryHolder.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/AbstractImageTransformerFactoryHolder.java
@@ -43,7 +43,7 @@ abstract class AbstractImageTransformerFactoryHolder extends AbstractHashable
         this.serializedImageTransformerFactory = serializedImageTransformerFactory;
     }
     
-    public IImageTransformerFactory getImageTransformerFactory()
+    public IImageTransformerFactory tryGetImageTransformerFactory()
     {
         if (serializedImageTransformerFactory == null)
         {
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 4e59a6dd10dc7829655c3059d5539b3e2191d72d..f08a89140afb2167a9ee472cd45558577ac3a4aa 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,6 +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 =
+        { TransformerFactoryMapper.class, TypeMapper.class /* default */})
+    public void saveTransformerFactoryForImage(long imageId, IImageTransformerFactory factory);
+
     @Update(sql = "update channels set image_transformer_factory = ?{3} "
             + "where code = ?{2} and exp_id = ?{1}", parameterBindings =
         { TransformerFactoryMapper.class, TypeMapper.class/* default */, TypeMapper.class /* default */})
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 3c0d33c38e19dde1dfb22f43da9c58c2d58ac92c..b3ccb8a864939d6876adee4b3734121a8a6a083f 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
@@ -18,12 +18,10 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess;
 
 import net.lemnik.eodsql.ResultColumn;
 
-import ch.systemsx.cisd.common.utilities.AbstractHashable;
-
 /**
  * @author Tomasz Pylak
  */
-public class ImgImageDTO extends AbstractHashable
+public class ImgImageDTO extends AbstractImageTransformerFactoryHolder
 {
     @ResultColumn("id")
     private long id;
@@ -36,7 +34,7 @@ public class ImgImageDTO extends AbstractHashable
 
     @ResultColumn("COLOR")
     private String colorComponentOrNull;
-
+    
     @SuppressWarnings("unused")
     private ImgImageDTO()
     {
diff --git a/screening/source/sql/postgresql/010/data.sql b/screening/source/sql/postgresql/010/data.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f08222c48c2932180be40863f775e14dac5267bc
--- /dev/null
+++ b/screening/source/sql/postgresql/010/data.sql
@@ -0,0 +1,275 @@
+-- Note that these data has to be loaded manually into the openBIS Core database.
+
+-- TODO: this sql should be converted to a generic sql without refering to technical ids. 
+-- Now the ids should be updated if some new records will be added in the generic data.
+
+--
+-- PostgreSQL database dump
+--
+
+SET statement_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = off;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET escape_string_warning = off;
+
+SET search_path = public, pg_catalog;
+
+--
+-- Data for Name: controlled_vocabularies; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY controlled_vocabularies (id, code, description, registration_timestamp, pers_id_registerer, is_managed_internally, is_internal_namespace, dbin_id, modification_timestamp, is_chosen_from_list, source_uri) FROM stdin;
+2	PLATE_GEOMETRY	The geometry or dimensions of a plate	2008-06-17 16:38:30.723292+02	1	t	t	1	2009-11-27 16:02:26.451046+01	t	\N
+3	MICROSCOPE	Microscope used in an experiment.	2009-11-29 23:55:18.978884+01	1	f	f	1	2009-12-17 01:50:54.68+01	t	\N
+\.
+
+
+--
+-- Data for Name: controlled_vocabulary_terms; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY controlled_vocabulary_terms (id, code, registration_timestamp, covo_id, pers_id_registerer, label, description, ordinal) FROM stdin;
+3	384_WELLS_16X24	2008-06-17 16:38:30.723292+02	2	1	384 Wells, 16x24	\N	1
+4	96_WELLS_8X12	2008-06-17 16:38:31.101031+02	2	1	96 Wells, 8x12	\N	2
+5	1536_WELLS_32X48	2008-06-17 16:38:31.101031+02	2	1	1536 Wells, 32x48	\N	3
+6	BD_PATHWAY_855	2009-11-29 23:55:18.978884+01	3	1	\N	\N	1
+7	MD_IMAGEXPRESS_MICROLIVE	2009-11-29 23:55:18.978884+01	3	1	\N	\N	2
+8	MD_IMAGEXPRESS_MICRO_2	2009-11-29 23:55:18.978884+01	3	1	\N	\N	3
+\.
+
+
+--
+-- Data for Name: data_set_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY data_set_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+3	HCS_IMAGE_ANALYSIS_DATA	Data derived from analysis of HCS images	1	2009-11-27 16:02:26.451046+01
+2	HCS_IMAGE	HCS raw images acquired by microscopes	1	2009-11-27 16:02:26.451046+01
+4	HCS_ANALYSIS_PER_GENE	Image analysis data aggregated per gene.	1	2009-12-16 16:59:50.743029+01
+\.
+
+
+--
+-- Data for Name: material_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY material_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+1	VIRUS	Virus	1	2009-11-27 16:02:26.451046+01
+2	CELL_LINE	Cell Line or Cell Culture. The growing of cells under controlled conditions.	1	2009-11-27 16:02:26.451046+01
+3	GENE	Gene	1	2009-11-27 16:02:26.451046+01
+4	SIRNA	siRNA nucleotide	1	2009-11-27 16:02:26.451046+01
+5	CONTROL	Control of a control layout	1	2009-11-27 16:02:26.451046+01
+6	BACTERIUM	Bacterium	1	2009-11-27 16:02:26.451046+01
+7	COMPOUND	Compound	1	2009-11-27 16:02:26.451046+01
+\.
+
+
+--
+-- Data for Name: property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY property_types (id, code, description, label, daty_id, registration_timestamp, pers_id_registerer, covo_id, is_managed_internally, is_internal_namespace, dbin_id, maty_prop_id) FROM stdin;
+3	NUCLEOTIDE_SEQUENCE	A sequence of nucleotides	Nucleotide Sequence	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+4	REFSEQ	NCBI Reference Sequence code, applicable to sequences of type: DNA, RNA, protein	RefSeq	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+13	MICROSCOPE	 	Microscope	7	2009-11-29 23:57:05.85618+01	1	3	f	f	1	\N
+7	INHIBITOR_OF	Inhibitor Of	Inhibitor Of	8	2009-11-27 16:02:45.060699+01	1	\N	f	f	1	3
+11	SIRNA	siRNA	siRNA	8	2009-11-29 23:56:19.39967+01	1	\N	f	f	1	4
+12	CONTROL	Control	Control	8	2009-11-29 23:56:37.355313+01	1	\N	f	f	1	5
+6	PLATE_GEOMETRY	Plate Geometry	Plate Geometry	7	2008-06-17 16:38:30.723292+02	1	2	t	t	1	\N
+15	NUMBER_OF_CHANNEL	 	Channels	3	2009-12-17 10:56:17.239319+01	1	\N	f	f	1	\N
+16	LIBRARY_ID	Library id	Id from the master plate library	1	2008-02-28 13:03:03.358532+01	1	\N	f	f	1	\N
+\.
+
+
+--
+-- Data for Name: data_set_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY data_set_type_property_types (id, dsty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin;
+\.
+
+
+--
+-- Data for Name: experiment_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY experiment_types (id, code, description, dbin_id, modification_timestamp) FROM stdin;
+2	COMPOUND_HCS	Compound High Content Screening	1	2009-11-27 16:02:26.451046+01
+1	SIRNA_HCS	Small Interfering RNA High Content Screening	1	2009-11-27 16:02:26.451046+01
+\.
+
+
+--
+-- Data for Name: experiment_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY experiment_type_property_types (id, exty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, section, ordinal) FROM stdin;
+1	1	1	t	t	1	2008-06-17 16:38:49.023295+02	\N	1
+2	2	1	t	t	1	2008-06-17 16:38:49.301922+02	\N	1
+5	1	13	f	f	1	2009-12-17 10:54:01.261178+01	\N	2
+\.
+
+
+--
+-- Data for Name: file_format_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY file_format_types (id, code, description, dbin_id) FROM stdin;
+7	PNG	\N	1
+8	CSV	files with values separated by comma or semicolon	1
+9	JPG	\N	1
+\.
+
+
+--
+-- Data for Name: filters; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY filters (id, dbin_id, name, description, registration_timestamp, pers_id_registerer, modification_timestamp, expression, is_public, grid_id) FROM stdin;
+9	1	Infection index	\N	2009-12-16 21:19:19.012657+01	1	2009-12-16 22:41:56.863+01	float(row.col('colIndex_5')) > float(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+8	1	Total number of cells	\N	2009-12-16 21:18:05.161964+01	1	2009-12-16 22:42:31.707+01	int(row.col('colIndex_3')) > int(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+7	1	Number of infected cells	\N	2009-12-16 21:17:40.765083+01	1	2009-12-16 22:42:46.052+01	int(row.col('colIndex_4')) > int(${threshold})	t	data-set-reporting-gridplate-image-analysis-merger
+\.
+
+
+--
+-- Data for Name: material_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY material_type_property_types (id, maty_id, prty_id, is_mandatory, registration_timestamp, pers_id_registerer, is_managed_internally, section, ordinal) FROM stdin;
+10	4	7	t	2009-11-27 16:02:45.060699+01	1	f	\N	4
+9	5	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	1
+8	4	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	3
+6	4	3	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+12	4	16	f	2008-02-28 13:03:03.358532+01	1	f	\N	1
+5	3	1	f	2008-02-28 13:03:03.358532+01	1	f	\N	2
+3	7	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+2	6	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+1	1	1	t	2008-02-28 13:03:03.358532+01	1	f	\N	1
+\.
+
+
+--
+-- Data for Name: sample_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY sample_types (id, code, description, dbin_id, is_listable, generated_from_depth, part_of_depth, modification_timestamp, is_auto_generated_code, generated_code_prefix) FROM stdin;
+3	PLATE	Cell Plate	1	t	2	0	2009-11-27 16:02:26.451046+01	f	S
+7	SIRNA_WELL	\N	1	f	0	1	2009-11-27 19:42:03.483115+01	f	O
+8	CONTROL_WELL	\N	1	f	0	1	2009-11-27 19:42:25.791288+01	f	C
+9	LIBRARY	\N	1	f	0	0	2009-11-27 19:42:25.791288+01	f	L
+\.
+
+
+--
+-- Data for Name: sample_type_property_types; Type: TABLE DATA; Schema: public; Owner: -
+--
+
+COPY sample_type_property_types (id, saty_id, prty_id, is_mandatory, is_managed_internally, pers_id_registerer, registration_timestamp, is_displayed, section, ordinal) FROM stdin;
+8	7	11	f	f	1	2009-11-29 23:57:38.268212+01	t	\N	1
+9	8	12	f	f	1	2009-11-29 23:57:49.098187+01	t	\N	1
+10	3	6	f	f	1	2009-11-30 01:28:20.972263+01	t	\N	1
+\.
+
+--
+-- PostgreSQL database dump complete
+--
+
+--------------------------------------------------
+-- update sequences values
+--------------------------------------------------
+
+select setval('controlled_vocabulary_id_seq', 100);
+select setval('cvte_id_seq', 100);
+select setval('property_type_id_seq', 100);
+select setval('file_format_type_id_seq', 100);
+select setval('filter_id_seq', 100);
+select setval('experiment_type_id_seq', 100);
+select setval('sample_type_id_seq', 100);
+select setval('data_set_type_id_seq', 100);
+select setval('material_type_id_seq', 100);
+select setval('etpt_id_seq', 100);
+select setval('stpt_id_seq', 100);
+select setval('mtpt_id_seq', 100);
+
+
+--------------------------------------------------
+-- create a gene property and assign it to sirna well
+--------------------------------------------------
+
+insert into property_types(
+	id, 
+	code, description, label, 
+	daty_id,
+	pers_id_registerer,
+	dbin_id,
+	maty_prop_id) 
+values(
+		nextval('PROPERTY_TYPE_ID_SEQ'), 
+		'GENE','Inhibited gene','Gene',
+		(select id from data_types where code = 'MATERIAL'), 
+		(select id from persons where user_id ='system'), 
+		(select id from database_instances where is_original_source = 'T'), 
+		(select id from material_types where code = 'GENE')
+	);
+	
+insert into sample_type_property_types( 
+  id,
+  saty_id,
+  prty_id,
+  is_mandatory,
+  pers_id_registerer,
+  ordinal
+) values(
+		nextval('stpt_id_seq'), 
+		(select id from sample_types where code = 'SIRNA_WELL'),
+		(select id from property_types where code = 'GENE'),
+		false,
+		(select id from persons where user_id ='system'),
+		(select max(ordinal)+1 from sample_type_property_types 
+			where saty_id = (select id from sample_types where code = 'SIRNA_WELL'))
+	);
+
+
+--------------------------------------------------
+-- Create gene property: gene_symbols
+--------------------------------------------------
+
+
+	insert into property_types
+		(id
+		,code
+		,description
+		,label
+		,daty_id
+		,pers_id_registerer
+		,dbin_id)
+	values 
+		(nextval('PROPERTY_TYPE_ID_SEQ')
+		,'GENE_SYMBOLS'
+		,'Gene symbols'
+		,'Gene symbols'
+		,(select id from data_types where code ='VARCHAR')
+		,(select id from persons where user_id ='system')
+		,(select id from database_instances where is_original_source = 'T')
+	);
+		
+	insert into material_type_property_types( 
+	  id,
+	  maty_id,
+	  prty_id,
+	  is_mandatory,
+	  pers_id_registerer,
+	  ordinal
+	) values(
+			nextval('mtpt_id_seq'), 
+			(select id from material_types where code = 'GENE'),
+			(select id from property_types where code = 'GENE_SYMBOLS'),
+			false,
+			(select id from persons where user_id ='system'),
+			(select max(ordinal)+1 from material_type_property_types 
+				where maty_id = (select id from material_types where code = 'GENE'))
+		);
+
diff --git a/screening/source/sql/postgresql/010/schema-010.sql b/screening/source/sql/postgresql/010/schema-010.sql
new file mode 100644
index 0000000000000000000000000000000000000000..681a48e7475b37745e2c199da0d840ea246cb176
--- /dev/null
+++ b/screening/source/sql/postgresql/010/schema-010.sql
@@ -0,0 +1,273 @@
+
+/* ---------------------------------------------------------------------- */
+/* Domains                                                                */
+/* ---------------------------------------------------------------------- */
+
+CREATE DOMAIN TECH_ID AS BIGINT;
+
+CREATE DOMAIN CODE AS VARCHAR(40);
+
+CREATE DOMAIN NAME AS VARCHAR(80);
+
+CREATE DOMAIN DESCRIPTION AS VARCHAR(200);
+
+CREATE DOMAIN FILE_PATH as VARCHAR(1000);
+
+CREATE DOMAIN COLOR_COMPONENT AS VARCHAR(40) CHECK (VALUE IN ('RED', 'GREEN', 'BLUE'));
+
+CREATE DOMAIN BOOLEAN_CHAR AS BOOLEAN DEFAULT FALSE;
+
+/* ---------------------------------------------------------------------- */
+/* Tables                                                                 */
+/* ---------------------------------------------------------------------- */
+
+CREATE TABLE EXPERIMENTS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  IMAGE_TRANSFORMER_FACTORY BYTEA,
+
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID)
+);
+
+CREATE TABLE CONTAINERS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+
+  SPOTS_WIDTH INTEGER,
+  SPOTS_HEIGHT INTEGER,
+  
+  EXPE_ID TECH_ID NOT NULL,
+
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID),
+  CONSTRAINT FK_SAMPLE_1 FOREIGN KEY (EXPE_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX CONTAINERS_EXPE_IDX ON CONTAINERS(EXPE_ID);
+
+CREATE TABLE SPOTS (
+  ID BIGSERIAL NOT NULL,
+	
+	-- position in the container, one-based
+  X INTEGER, 
+  Y INTEGER, 
+  CONT_ID TECH_ID NOT NULL,
+  
+  PRIMARY KEY (ID),
+  CONSTRAINT FK_SPOT_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX SPOTS_CONT_IDX ON SPOTS(CONT_ID);
+-- allows to select one spot of the container quicker
+CREATE INDEX SPOTS_COORDS_IDX ON SPOTS(CONT_ID, X, Y);
+
+CREATE TABLE DATA_SETS (
+  ID BIGSERIAL NOT NULL,
+  PERM_ID CODE NOT NULL,
+  
+	FIELDS_WIDTH INTEGER,
+	FIELDS_HEIGHT INTEGER,	
+  
+  CONT_ID TECH_ID,
+  -- a redundant information if there are timepoint or depth stack data for any spots in this dataset
+  IS_MULTIDIMENSIONAL BOOLEAN_CHAR NOT NULL,
+  -- transformation for merged channels on the dataset level, overrides experiment level transformation
+  IMAGE_TRANSFORMER_FACTORY BYTEA,
+  
+  PRIMARY KEY (ID),
+  UNIQUE (PERM_ID),
+  CONSTRAINT FK_DATA_SET_1 FOREIGN KEY (CONT_ID) REFERENCES CONTAINERS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX DATA_SETS_CONT_IDX ON DATA_SETS(CONT_ID);
+
+CREATE TABLE CHANNELS (
+    ID BIGSERIAL  NOT NULL,
+    
+    CODE NAME NOT NULL,
+    LABEL NAME NOT NULL,
+    DESCRIPTION DESCRIPTION,
+    WAVELENGTH INTEGER,
+    IMAGE_TRANSFORMER_FACTORY BYTEA,
+
+    DS_ID TECH_ID,
+    EXP_ID TECH_ID,
+    
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_CHANNELS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_CHANNELS_2 FOREIGN KEY (EXP_ID) REFERENCES EXPERIMENTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT CHANNELS_DS_EXP_ARC_CK CHECK ((DS_ID IS NOT NULL AND EXP_ID IS NULL) OR (DS_ID IS NULL AND EXP_ID IS NOT NULL)),
+    
+    CONSTRAINT CHANNELS_UK_1 UNIQUE(CODE, DS_ID),
+    CONSTRAINT CHANNELS_UK_2 UNIQUE(CODE, EXP_ID)
+);
+
+CREATE INDEX CHANNELS_DS_IDX ON CHANNELS(DS_ID);
+
+CREATE TABLE CHANNEL_STACKS (
+    ID BIGSERIAL  NOT NULL,
+		
+		-- x and y are kind of a two dimensional sequence number, some use case may only use x and leave y alone
+		X INTEGER,
+		Y INTEGER,
+		-- We use the fixed dimension meters here.
+		Z_in_M REAL,
+		-- We use the fixed dimension seconds here.
+		T_in_SEC REAL,
+		SERIES_NUMBER INTEGER,
+		
+		-- For all channel stacks of a well (HCS) or image dataset (microscopy) there should be exactly 
+		-- one record with is_representative = true
+		is_representative BOOLEAN_CHAR NOT NULL DEFAULT 'F',
+    
+    DS_ID TECH_ID	NOT NULL,
+		SPOT_ID TECH_ID,
+
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_CHANNEL_STACKS_1 FOREIGN KEY (SPOT_ID) REFERENCES SPOTS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_CHANNEL_STACKS_2 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX CHANNEL_STACKS_DS_IDX ON CHANNEL_STACKS(DS_ID);
+CREATE INDEX CHANNEL_STACKS_SPOT_IDX ON CHANNEL_STACKS(SPOT_ID);
+CREATE INDEX CHANNEL_STACKS_DIM_IDX ON CHANNEL_STACKS(X, Y, Z_in_M, T_in_SEC);
+
+CREATE TABLE IMAGES (
+    ID BIGSERIAL  NOT NULL,
+   
+    PATH	FILE_PATH NOT NULL,
+    PAGE	INTEGER,
+    COLOR	COLOR_COMPONENT,
+    IMAGE_TRANSFORMER_FACTORY BYTEA,
+    
+    PRIMARY KEY (ID)
+);
+
+CREATE TABLE ACQUIRED_IMAGES (
+    ID BIGSERIAL  NOT NULL,
+   
+		IMG_ID   TECH_ID NOT NULL,
+		THUMBNAIL_ID  TECH_ID,
+
+    CHANNEL_STACK_ID  TECH_ID NOT NULL,
+    CHANNEL_ID  TECH_ID NOT NULL,
+
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_IMAGES_1 FOREIGN KEY (CHANNEL_STACK_ID) REFERENCES CHANNEL_STACKS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_2 FOREIGN KEY (CHANNEL_ID) REFERENCES CHANNELS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_3 FOREIGN KEY (IMG_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FK_IMAGES_4 FOREIGN KEY (THUMBNAIL_ID) REFERENCES IMAGES (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX IMAGES_CHANNEL_STACK_IDX ON ACQUIRED_IMAGES(CHANNEL_STACK_ID);
+CREATE INDEX IMAGES_CHANNEL_IDX ON ACQUIRED_IMAGES(CHANNEL_ID);
+CREATE INDEX IMAGES_IMG_IDX ON ACQUIRED_IMAGES(IMG_ID);
+CREATE INDEX IMAGES_THUMBNAIL_IDX ON ACQUIRED_IMAGES(THUMBNAIL_ID);
+
+CREATE TABLE EVENTS (
+  LAST_SEEN_DELETION_EVENT_ID TECH_ID NOT NULL
+);
+
+/* ---------------------------------------------------------------------- */
+/* FEATURE VECTORS                                                        */
+/* ---------------------------------------------------------------------- */ 
+
+CREATE TABLE FEATURE_DEFS (
+    ID BIGSERIAL  NOT NULL,
+    
+    CODE NAME NOT NULL,
+    LABEL NAME NOT NULL,
+    DESCRIPTION DESCRIPTION,
+    
+    DS_ID  TECH_ID NOT NULL,
+    
+    PRIMARY KEY (ID),
+    CONSTRAINT FK_FEATURE_DEFS_1 FOREIGN KEY (DS_ID) REFERENCES DATA_SETS (ID) ON DELETE CASCADE ON UPDATE CASCADE,
+    CONSTRAINT FEATURE_DEFS_UK_1 UNIQUE(CODE, DS_ID)
+);
+
+CREATE INDEX FEATURE_DEFS_DS_IDX ON FEATURE_DEFS(DS_ID);
+
+CREATE TABLE FEATURE_VOCABULARY_TERMS (
+	ID BIGSERIAL  NOT NULL,
+
+  CODE NAME NOT NULL,
+  SEQUENCE_NUMBER INTEGER NOT NULL,
+	FD_ID  TECH_ID NOT NULL,
+
+	PRIMARY KEY (ID),
+	CONSTRAINT FK_FEATURE_VOCABULARY_TERMS_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX FEATURE_VOCABULARY_TERMS_FD_IDX ON FEATURE_VOCABULARY_TERMS(FD_ID);
+
+CREATE TABLE FEATURE_VALUES (
+    ID BIGSERIAL  NOT NULL,
+		
+		-- we use the fixed dimension meters here
+		Z_in_M REAL,
+		-- we use the fixed dimension seconds here
+		T_in_SEC REAL,
+		-- Serialized 2D matrix with values for each spot.
+		-- Contains floats which can be NaN. 
+		-- It is never a case that the whole matrix contains NaN - in such a case we save nothing.
+		-- If feature definition has some connected vocabulary terms then the matrix 
+		-- stores FEATURE_VOCABULARY_TERMS.SEQUENCE_NUMBER of the terms (should be casted from float to int).
+		-- If the term is null the Float.NaN is stored.
+		VALUES BYTEA NOT NULL,
+		
+		FD_ID  TECH_ID NOT NULL,
+		
+		PRIMARY KEY (ID),
+		CONSTRAINT FK_FEATURE_VALUES_1 FOREIGN KEY (FD_ID) REFERENCES FEATURE_DEFS (ID) ON DELETE CASCADE ON UPDATE CASCADE
+    -- This constaint does not make any sense. Leave it out for now.
+    -- CONSTRAINT FEATURE_VALUES_UK_1 UNIQUE(Z_in_M, T_in_SEC)
+);
+
+CREATE INDEX FEATURE_VALUES_FD_IDX ON FEATURE_VALUES(FD_ID);
+CREATE INDEX FEATURE_VALUES_Z_AND_T_IDX ON FEATURE_VALUES(Z_in_M, T_in_SEC);
+
+
+/* ---------------------------------------------------------------------- */
+/* FUNCTIONS AND TRIGGERS                                                 */
+/* ---------------------------------------------------------------------- */ 
+
+CREATE OR REPLACE FUNCTION DELETE_UNUSED_IMAGES() RETURNS trigger AS $$
+BEGIN
+   delete from images where id = OLD.img_id or id = OLD.thumbnail_id;
+   RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE TRIGGER UNUSED_IMAGES AFTER DELETE ON ACQUIRED_IMAGES
+    FOR EACH ROW EXECUTE PROCEDURE DELETE_UNUSED_IMAGES();
+    
+------------------------------------------------------------------------------------
+--  Purpose:  Create trigger CHANNEL_STACKS_CHECK which checks if both spot_id and dataset.cont_id 
+--            are both null or not null.
+------------------------------------------------------------------------------------
+
+CREATE OR REPLACE FUNCTION CHANNEL_STACKS_CHECK() RETURNS trigger AS $$
+DECLARE
+   v_cont_id  CODE;
+BEGIN
+
+   select cont_id into v_cont_id from data_sets where id = NEW.ds_id;
+
+   -- Check that if there is no spot than there is no dataset container as well
+   if v_cont_id IS NULL then
+      if NEW.spot_id IS NOT NULL then
+         RAISE EXCEPTION 'Insert/Update of CHANNEL_STACKS failed, as the dataset container is not set, but spot is (spot id = %).',NEW.spot_id;
+      end if;
+	 else
+      if NEW.spot_id IS NULL then
+         RAISE EXCEPTION 'Insert/Update of CHANNEL_STACKS failed, as the dataset container is set (id = %), but spot is not set.',v_cont_id;
+      end if; 
+   end if;
+   RETURN NEW;
+END;
+$$ LANGUAGE 'plpgsql';
+
+CREATE TRIGGER CHANNEL_STACKS_CHECK BEFORE INSERT OR UPDATE ON CHANNEL_STACKS
+    FOR EACH ROW EXECUTE PROCEDURE CHANNEL_STACKS_CHECK();
\ No newline at end of file
diff --git a/screening/source/sql/postgresql/010/upload-screening-metadata.sh b/screening/source/sql/postgresql/010/upload-screening-metadata.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1a8a1969f1ef9d83fafdeb766696b9c5eef14fe7
--- /dev/null
+++ b/screening/source/sql/postgresql/010/upload-screening-metadata.sh
@@ -0,0 +1,2 @@
+DB=$1
+psql -U postgres -d openbis_$DB -f data.sql
diff --git a/screening/source/sql/postgresql/migration/migration-009-010.sql b/screening/source/sql/postgresql/migration/migration-009-010.sql
new file mode 100644
index 0000000000000000000000000000000000000000..db3cf424f7c9734a1cbd670781f515b4eb433799
--- /dev/null
+++ b/screening/source/sql/postgresql/migration/migration-009-010.sql
@@ -0,0 +1,3 @@
+-- Migration from 009 to 010
+
+ALTER TABLE images ADD COLUMN image_transformer_factory BYTEA;
\ No newline at end of file
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
index db7cc1938fe1c4c4fc7454668f8314875506ba7b..bf3ada2540fd3e42d441d5c7e3ad022eba8bf3af 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/images/ImageChannelsUtilsTest.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.common.io.FileBasedContent;
 import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.DatasetAcquiredImagesReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.ImageChannelStackReference;
 import ch.systemsx.cisd.openbis.dss.generic.server.images.dto.RequestedImageSize;
@@ -123,8 +124,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit
     public void testGetTiffImage()
     {
         AbsoluteImageReference absoluteImageReference =
-                new AbsoluteImageReference(image("img1.tiff"), "id42", null, null,
-                        RequestedImageSize.createOriginal(), 0);
+                createAbsoluteImageReference("img1.tiff", RequestedImageSize.createOriginal());
         performTest(absoluteImageReference, getImageContentDescription(image("img1.png")), null);
         context.assertIsSatisfied();
     }
@@ -134,8 +134,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit
     {
         Size size = new Size(4, 2);
         AbsoluteImageReference absoluteImageReference =
-                new AbsoluteImageReference(image("img1.jpg"), "id42", null, null,
-                        new RequestedImageSize(size, false), 0);
+                createAbsoluteImageReference("img1.jpg", new RequestedImageSize(size, false));
         performTest(absoluteImageReference, "cde cde\ncde cde\n", size);
         context.assertIsSatisfied();
     }
@@ -191,9 +190,8 @@ public class ImageChannelsUtilsTest extends AssertJUnit
     {
         final DatasetAcquiredImagesReference imageRef = createDatasetAcquiredImagesReference();
         AbsoluteImageReference imgRef =
-                new AbsoluteImageReference(image("img1.gif"), "id42", null, null,
-                        RequestedImageSize.createOriginal(), 0);
-        imgRef.setTransformerFactory(transformerFactory);
+                createAbsoluteImageReference("img1.gif", RequestedImageSize.createOriginal());
+        imgRef.getImageTransfomationFactories().setForChannel(transformerFactory);
 
         prepareExpectations(imgRef, imageRef);
         context.checking(new Expectations()
@@ -211,6 +209,13 @@ public class ImageChannelsUtilsTest extends AssertJUnit
         context.assertIsSatisfied();
     }
 
+    private static AbsoluteImageReference createAbsoluteImageReference(String fileName,
+            RequestedImageSize imageSize)
+    {
+        return new AbsoluteImageReference(image(fileName), "id42", null, null, imageSize, 0,
+                new ImageTransfomationFactories());
+    }
+
     private ImageChannelsUtils createImageChannelsUtils(Size thumbnailSizeOrNull)
     {
         return new ImageChannelsUtils(loader, new RequestedImageSize(thumbnailSizeOrNull, false));
@@ -235,7 +240,7 @@ public class ImageChannelsUtilsTest extends AssertJUnit
         }
     }
 
-    private IContent image(String fileName)
+    private static IContent image(String fileName)
     {
         return new FileBasedContent(new File(TEST_IMAGE_FOLDER, fileName));
     }
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
index 03230353b2cb16b8ccf281813a88f4fb973ed621..cbba754fbb7f453825a9443fbe4aca3712a0ac48 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/dss/screening/server/DssServiceRpcScreeningTest.java
@@ -50,6 +50,7 @@ import ch.systemsx.cisd.common.io.FileBasedContent;
 import ch.systemsx.cisd.common.io.IContent;
 import ch.systemsx.cisd.openbis.dss.etl.AbsoluteImageReference;
 import ch.systemsx.cisd.openbis.dss.etl.IImagingDatasetLoader;
+import ch.systemsx.cisd.openbis.dss.etl.dto.ImageTransfomationFactories;
 import ch.systemsx.cisd.openbis.dss.generic.server.DatasetSessionAuthorizer;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor;
 import ch.systemsx.cisd.openbis.dss.generic.server.DssServiceRpcAuthorizationAdvisor.DssServiceRpcAuthorizationMethodInterceptor;
@@ -324,13 +325,13 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
                             ImageChannelStackReference.createHCSFromLocations(new Location(3, 1),
                                     new Location(1, 1)), thumbnailSize);
                     will(returnValue(new AbsoluteImageReference(image("img1.jpg"), "img1", null,
-                            null, thumbnailSize, 0)));
+                            null, thumbnailSize, 0, new ImageTransfomationFactories())));
                     one(imageLoader).tryGetImage(
                             channel,
                             ImageChannelStackReference.createHCSFromLocations(new Location(3, 1),
                                     new Location(2, 1)), thumbnailSize);
                     will(returnValue(new AbsoluteImageReference(image("img1.gif"), "img1", null,
-                            null, thumbnailSize, 0)));
+                            null, thumbnailSize, 0, new ImageTransfomationFactories())));
                 }
             });
 
@@ -703,7 +704,7 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
                 }
             });
     }
-    
+
     private FeatureVectorDatasetReference createFeatureVectorDatasetReference(String dataSetCode)
     {
         return new FeatureVectorDatasetReference(dataSetCode, "", null, null, null, null, null,