diff --git a/screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png b/screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec584cf9b80a7c13bfb5a06c9a043bd67b806618
Binary files /dev/null and b/screening/resource/test-data/TransformedImageRepresentationsTest/TRANSFORMED-THUMB-PLATE/bPLATE_wA1_s1_cRGB.png differ
diff --git a/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py b/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py
new file mode 100644
index 0000000000000000000000000000000000000000..74db9b21d8599a96e5b50b650f1c37273ed0b279
--- /dev/null
+++ b/screening/resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py
@@ -0,0 +1,150 @@
+#!/usr/bin/env python
+
+PLATE_GEOMETRY_PROPERTY_CODE = "$PLATE_GEOMETRY"
+PLATE_GEOMETRY = "384_WELLS_16X24"
+
+"""
+An Jython dropbox for importing HCS image datasets for use by the TransformedImageRepresentationsTest
+
+The folder loaded to the dropbox folder should have the same name as the plate that the data will be attached to.
+"""
+
+import os
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1 import SimpleImageDataConfig, ImageMetadata, Location, Channel, ChannelColor, ChannelColorComponent
+from ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto import Geometry
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.transformations import ImageTransformationBuffer
+from ch.systemsx.cisd.openbis.dss.etl.dto.api.v1.thumbnails import ResolutionBasedThumbnailsConfiguration
+
+  
+class ImageDataSetFlexible(SimpleImageDataConfig):
+  def extractImageMetadata(self, imagePath):
+    """
+    Extracts tile number, channel code and well code for a given relative path to an image.
+    Will be called for each file found in the incoming directory which has the allowed image extension.
+    
+    Example file name: bDZ01-1A_wD17_s3_z123_t321_cGFP
+    Returns:
+      ImageMetadata
+    """
+    image_tokens = ImageMetadata()
+  
+    basename = os.path.splitext(imagePath)[0]
+    # 
+    token_dict = {}
+    for token in basename.split("_"):
+      token_dict[token[:1]] = token[1:]
+    
+    image_tokens.well = token_dict["w"]
+    fieldText = token_dict["s"]
+    try:
+      image_tokens.tileNumber = int(fieldText)
+    except ValueError:
+      raise Exception("Cannot parse field number from '" + fieldText + "' in '" + basename + "' file name.")
+  
+    image_tokens.channelCode = token_dict["c"]
+    return image_tokens
+
+  def getTileGeometry(self, imageTokens, maxTileNumber):
+    """
+    Overrides the default implementation which returns (1, maxTileNumber) geometry.
+  
+    Calculates the width and height of the matrix of tiles (a.k.a. fields or sides) in the well.
+  
+    Parameter imageMetadataList: a list of metadata for each encountered image
+    Parameter maxTileNumber: the biggest tile number among all encountered images
+    Returns:
+      Geometry
+    """
+    return Geometry.createFromRowColDimensions(1, 1);
+  
+  def getTileCoordinates(self, tileNumber, tileGeometry):
+    """
+    Overrides the default implementation which does the same thing (to demonstrate how this can be done). 
+  
+    For a given tile number and tiles geometry returns (x,y) which describes where the tile is
+    located on the well.
+  
+    Parameter tileNumber: number of the tile
+    Parameter tileGeometry: the geometry of the well matrix
+    Returns:
+       Location
+    """
+    columns = tileGeometry.getWidth()
+    row = ((tileNumber - 1) / columns) + 1
+    col = ((tileNumber - 1) % columns) + 1
+    return Location(row, col)
+    
+
+def getAvailableChannelTransformations():
+  """
+  Create a collection of transformations that are applicable to the image
+  """
+  transforms = ImageTransformationBuffer()
+  transforms.appendImageMagicConvert("-edge 1", "Edge detection")
+  transforms.appendImageMagicConvert("-radial-blur 30", "Radial Blur")
+  transforms.appendImageMagicConvert("-blur 3x.7 -solarize 50% -level 50%,0", "Fuzzy")
+  transforms.appendImageMagicConvert("-shade 0x45", "3D 1")
+  transforms.appendImageMagicConvert("-shade 90x60", "3D 2")
+  transforms.appendImageMagicConvert("-blur 0x3 -shade 120x45 -normalize", "3D 3")
+  transforms.appendImageMagicConvert("-motion-blur 0x12+45", "Motion Blur")
+  transforms.appendImageMagicConvert("-fft -delete 1 -auto-level -evaluate log 100000", "FFT")
+  
+  return transforms.getTransformations()
+  
+def create_experiment(tr):
+    space = tr.createNewSpace("TEST", "etlserver")
+    project = tr.createNewProject("/TEST/TEST-PROJECT")
+    expid = "/TEST/TEST-PROJECT/TRANSFORMED_THUMBNAILS_EXP"
+
+    exp = tr.createNewExperiment(expid, 'SIRNA_HCS')
+    exp.setPropertyValue("DESCRIPTION", "Test experiment")
+        
+    return exp
+
+def create_plate(tr, experiment, plateCode):
+    plateId = "/TEST/" + plateCode
+    plate = tr.createNewSample(plateId, 'PLATE')
+    plate.setPropertyValue(PLATE_GEOMETRY_PROPERTY_CODE, PLATE_GEOMETRY)
+    plate.setExperiment(experiment)
+    
+    wellA1 = tr.createNewSample(plate.getSampleIdentifier() + ":A1", "SIRNA_WELL")
+    wellA1.setContainer(plate)
+
+    wellA2 = tr.createNewSample(plate.getSampleIdentifier() + ":A2", "SIRNA_WELL")
+    wellA2.setContainer(plate)
+    
+    return plate
+
+      
+if incoming.isDirectory(): 
+  tr = service.transaction()
+  experiment = create_experiment(tr)
+  plate = create_plate(tr, experiment, 'TRANSFORMED-THUMB-PLATE')
+  tr.commit()
+  
+  
+  imageDataset = ImageDataSetFlexible()
+  imageDataset.setRawImageDatasetType()
+  imageDataset.setPlate("TEST", 'TRANSFORMED-THUMB-PLATE')
+  transforms = getAvailableChannelTransformations()
+  # We want thumbnails generarted for the following resolutions, and they should be JPEG and have the
+  # Radial Blur transform applied
+  for resolution in ['64x64', '128x128', '256x256']:
+    representation = imageDataset.addGeneratedImageRepresentationWithResolution(resolution)
+    for channel in ["DAPI", "GFP", "Cy5"]:
+      representation.setTransformation(channel, transforms[1].getCode())
+    storageFormat = representation.getThumbnailsStorageFormat(imageDataset)
+    storageFormat.setFileFormat('JPEG')
+
+  imageRegistrationDetails = factory.createImageRegistrationDetails(imageDataset, incoming)
+  datasetInfo = imageRegistrationDetails.getDataSetInformation()
+  channels = [ Channel(code, code) for code in ["DAPI", "GFP", "Cy5"]]
+  colorComponents = [ ChannelColorComponent.BLUE, ChannelColorComponent.GREEN, ChannelColorComponent.RED]
+  
+  # Add transforms to the channels
+  for channel in channels:
+    channel.setAvailableTransformations(transforms)
+  
+  datasetInfo.setChannels(channels, colorComponents)
+  
+  factory.registerImageDataset(imageRegistrationDetails, incoming, service)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
index c639f8cbf66bf053612a450bced0cddf1d3bf5be..67099adfe536b82c8cd2dc69af6d195239c70d5b 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/AbstractImageStorageProcessor.java
@@ -665,10 +665,9 @@ abstract class AbstractImageStorageProcessor extends AbstractStorageProcessor im
         ImageDataSetStructure imageDataSetStructure = dataSetInformation.getImageDataSetStructure();
         if (imageDataSetStructure.isValid() == false)
         {
-            throw ConfigurationFailureException
-                    .fromTemplate("Invalid image dataset info object, check if your jython script fills all the required fields. "
-                            + "Or maybe the recognized files extensions is set incorrectly? Dataset: "
-                            + imageDataSetStructure);
+            throw new ConfigurationFailureException("Invalid image dataset info object, check if your jython script fills all the required fields. "
+                    + "Or maybe the recognized files extensions is set incorrectly? Dataset: "
+                    + imageDataSetStructure);
         }
         Geometry tileGeometry =
                 new Geometry(imageDataSetStructure.getTileRowsNumber(),
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e2310cdfbb97bc030ac9257f77dc34c1896bca0
--- /dev/null
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/screening/systemtests/TransformedImageRepresentationsTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.screening.systemtests;
+
+import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.servlet.SpringRequestContextProvider;
+import ch.systemsx.cisd.etlserver.DefaultStorageProcessor;
+import ch.systemsx.cisd.openbis.dss.etl.PlateStorageProcessor;
+import ch.systemsx.cisd.openbis.dss.etl.jython.JythonPlateDataSetHandler;
+import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.IScreeningOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.plugin.screening.client.api.v1.ScreeningOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientService;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.ResourceNames;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.IScreeningApiServer;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.DatasetImageRepresentationFormats;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageDatasetReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.ImageRepresentationFormat;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+@Test(groups =
+    { "slow", "systemtest" })
+public class TransformedImageRepresentationsTest extends AbstractScreeningSystemTestCase
+{
+    private MockHttpServletRequest request;
+
+    private String sessionToken;
+
+    private IScreeningClientService screeningClientService;
+
+    private IScreeningApiServer screeningServer;
+
+    private IScreeningOpenbisServiceFacade screeningFacade;
+
+    @Override
+    protected void setUpTestThread()
+    {
+        setUpTestThread(JythonPlateDataSetHandler.class, PlateStorageProcessor.class,
+                getTestDataFolder() + "data-set-handler.py");
+
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX
+                + "dss-system-test-thread.storage-processor.processor", DefaultStorageProcessor.class.getName());
+        System.setProperty(OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX
+                + "dss-system-test-thread.storage-processor.data-source", "imaging-db");
+    }
+
+    @BeforeMethod
+    public void setUp() throws Exception
+    {
+        screeningClientService =
+                (IScreeningClientService) applicationContext
+                        .getBean(ResourceNames.SCREENING_PLUGIN_SERVICE);
+        request = new MockHttpServletRequest();
+        ((SpringRequestContextProvider) applicationContext.getBean("request-context-provider"))
+                .setRequest(request);
+        Object bean = applicationContext.getBean(ResourceNames.SCREENING_PLUGIN_SERVER);
+        screeningServer = (IScreeningApiServer) bean;
+        sessionToken = screeningClientService.tryToLogin("admin", "a").getSessionID();
+        screeningFacade = ScreeningOpenbisServiceFacade.tryCreateForTest(sessionToken, "http://localhost:" + SYSTEM_TEST_CASE_SERVER_PORT, screeningServer);
+    }
+
+    @AfterMethod
+    public void tearDown()
+    {
+        File[] files = getIncomingDirectory().listFiles();
+        for (File file : files)
+        {
+            FileUtilities.deleteRecursively(file);
+        }
+    }
+
+    @Test
+    public void testTransformedThumbnails() throws Exception
+    {
+        dropAnExampleDataSet();
+        // The components of the plate identifier come from the dropbox code
+        // (resource/test-data/TransformedImageRepresentationsTest/data-set-handler.py)
+        PlateIdentifier plate = new PlateIdentifier("TRANSFORMED-THUMB-PLATE", "TEST", null);
+        List<ImageDatasetReference> imageDataSets = screeningFacade.listRawImageDatasets(Arrays.asList(plate));
+        List<DatasetImageRepresentationFormats> representationFormats = screeningFacade.listAvailableImageRepresentationFormats(imageDataSets);
+        assertEquals(1, representationFormats.size());
+        List<ImageRepresentationFormat> formats = representationFormats.get(0).getImageRepresentationFormats();
+
+        HashSet<Dimension> expectedResolutions = new HashSet<Dimension>();
+        expectedResolutions.addAll(Arrays.asList(new Dimension(64, 64), new Dimension(128, 128), new Dimension(256, 256), new Dimension(512, 512)));
+        for (ImageRepresentationFormat format : formats)
+        {
+            Dimension resolution = new Dimension(format.getWidth(), format.getHeight());
+            // Make sure the resolution we specified was found
+            assertTrue("" + resolution + " was not expected", expectedResolutions.remove(resolution));
+        }
+        assertEquals(0, expectedResolutions.size());
+
+        System.err.println(representationFormats);
+    }
+
+    private void dropAnExampleDataSet() throws IOException, Exception
+    {
+        File exampleDataSet = createTestDataContents();
+        moveFileToIncoming(exampleDataSet);
+        waitUntilDataSetImported();
+    }
+
+    private File createTestDataContents() throws IOException
+    {
+        File dest = new File(workingDirectory, "test-data");
+        dest.mkdirs();
+        File src = new File(getTestDataFolder(), "TRANSFORMED-THUMB-PLATE");
+
+        // Copy the test data set to the location for processing
+        FileUtils.copyDirectory(src, dest);
+        return dest;
+    }
+
+    private String getTestDataFolder()
+    {
+        return "../screening/resource/test-data/" + getClass().getSimpleName() + "/";
+    }
+
+    @Override
+    protected int dataSetImportWaitDurationInSeconds()
+    {
+        return 60;
+    }
+
+}