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 4a8fe7f1c55b58253c2dddc5406f519bccfffb0d..d6f6aa0e6036b383d65d9519a3c4b0a6d3176835 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
@@ -69,6 +69,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningQue
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.ExperimentFeatureVectorSummaryLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.FeatureVectorValuesLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.LogicalImageLoader;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.MaterialAllAssaysFeatureVectorSummaryLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.MaterialFeatureVectorSummaryLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.PlateContentLoader;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.ScreeningApiImpl;
@@ -313,8 +314,8 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl
         Session session = getSession(sessionToken);
         // NOTE: we want the settings to be passed form the client in future
         MaterialSummarySettings settings = createDefaultSettings();
-        return MaterialFeatureVectorSummaryLoader.loadMaterialFeatureVectorsFromAllAssays(session,
-                businessObjectFactory, getDAOFactory(), materialId, settings);
+        return MaterialAllAssaysFeatureVectorSummaryLoader.loadMaterialFeatureVectorsFromAllAssays(
+                session, businessObjectFactory, getDAOFactory(), materialId, settings);
     }
 
     public static MaterialSummarySettings createDefaultSettings()
@@ -469,5 +470,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/logic/ExperimentFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java
index 0ad99b5018a3abcd5d618eec1008f8feb43e8cc3..c337dd81e44dc616f778bfee379b10b2a7642974 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ExperimentFeatureVectorSummaryLoader.java
@@ -27,7 +27,6 @@ import java.util.Set;
 
 import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction;
-import ch.systemsx.cisd.common.collections.GroupByMap;
 import ch.systemsx.cisd.common.collections.IKeyExtractor;
 import ch.systemsx.cisd.common.collections.TableMap;
 import ch.systemsx.cisd.common.collections.TableMap.UniqueKeyViolationStrategy;
@@ -36,7 +35,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleL
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
@@ -46,20 +44,17 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObject
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary;
-import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentFeatureVectorSummary;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialFeatureVectorSummary;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader;
 
 /**
  * {@See #loadExperimentFeatureVectors}.
@@ -114,7 +109,7 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
         return enrichWithMaterial(summaries, wellDataCollection);
     }
 
-    protected final List<MaterialIdFeatureVectorSummary> calculateReplicasFeatureVectorSummaries(
+    private final List<MaterialIdFeatureVectorSummary> calculateReplicasFeatureVectorSummaries(
             List<? extends IWellData> wellDataList)
     {
         return WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries(wellDataList,
@@ -189,6 +184,13 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
                 featureVectorsCollection.getFeatureCodesAndLabels());
     }
 
+    private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors(
+            Set<PlateIdentifier> plateIdentifiers)
+    {
+        return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory)
+                .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes());
+    }
+
     private static ExperimentFeatureVectorSummary createEmptySummary(ExperimentReference experiment)
     {
         List<MaterialFeatureVectorSummary> materialsSummary = Collections.emptyList();
@@ -262,7 +264,8 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
         {
             return null;
         }
-        return new WellData(replicaMaterial.getId(), featureVectorNumbers, well, replicaMaterial);
+        return new WellExtendedData(replicaMaterial.getId(), featureVectorNumbers, well,
+                replicaMaterial);
     }
 
     private static Material tryFindReplicaMaterial(Sample well, MaterialSummarySettings settings)
@@ -292,26 +295,8 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
         {
             return null;
         }
-        return asFeatureVectorValues(featureVector, orderedFeatureLabels);
-    }
-
-    private static float[] asFeatureVectorValues(FeatureVectorValues featureVector,
-            List<String> orderedFeatureLabels)
-    {
-        Map<String, FeatureValue> featureMap = featureVector.getFeatureMap();
-        float[] values = new float[featureMap.size()];
-        int i = 0;
-        for (String featureLabel : orderedFeatureLabels)
-        {
-            FeatureValue featureValue = featureMap.get(featureLabel);
-            values[i++] = asFloat(featureValue);
-        }
-        return values;
-    }
-
-    private static float asFloat(FeatureValue featureValue)
-    {
-        return featureValue.isFloat() ? featureValue.asFloat() : Float.NaN;
+        return WellFeatureCollectionLoader.asFeatureVectorValues(featureVector,
+                orderedFeatureLabels);
     }
 
     private static WellReference asWellReference(Sample well)
@@ -332,32 +317,6 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
         return idents;
     }
 
-    // private static List<WellContent> convert(List<Sample> wells, ExperimentReference experiment)
-    // {
-    // List<WellContent> wellContents = new ArrayList<WellContent>();
-    // for (Sample well : wells)
-    // {
-    // wellContents.add(convert(well, experiment));
-    // }
-    // return wellContents;
-    // }
-    //
-    // private static WellContent convert(Sample well, ExperimentReference experiment)
-    // {
-    // WellLocation location =
-    // ScreeningUtils.tryCreateLocationFromMatrixCoordinate(well.getSubCode());
-    // EntityReference wellReference = asEntityReference(well);
-    // EntityReference plate = asEntityReference(well.getContainer());
-    //
-    // return new WellContent(location, wellReference, plate, experiment);
-    // }
-    //
-    // private static EntityReference asEntityReference(Sample sample)
-    // {
-    // return new EntityReference(sample.getId(), sample.getSubCode(), sample.getSampleType()
-    // .getCode(), EntityKind.SAMPLE, sample.getPermId());
-    // }
-
     private static ListOrSearchSampleCriteria createWellsCriteria(List<Sample> plates)
     {
         Collection<Long> plateIds = new ArrayList<Long>();
@@ -377,112 +336,6 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
                 ListOrSearchSampleCriteria.createForExperiment(new TechId(expId)));
     }
 
-    /**
-     * Fetches feature vectors from different datastores and merges them (assuming that feature
-     * codes are the same).
-     */
-    private static class FeatureVectorRetriever
-    {
-        public static WellFeatureCollection<FeatureVectorValues> tryFetch(
-                Collection<DatasetReference> datasets, List<String> featureCodes,
-                IScreeningBusinessObjectFactory businessObjectFactory)
-        {
-            assert datasets.size() > 0 : "No feature vector datasets specified.";
-            return new FeatureVectorRetriever(businessObjectFactory, featureCodes)
-                    .tryFetch(datasets);
-        }
-
-        private final IScreeningBusinessObjectFactory businessObjectFactory;
-
-        private final List<String> featureCodes;
-
-        public FeatureVectorRetriever(IScreeningBusinessObjectFactory businessObjectFactory,
-                List<String> featureCodes)
-        {
-            this.businessObjectFactory = businessObjectFactory;
-            this.featureCodes = featureCodes;
-        }
-
-        private WellFeatureCollection<FeatureVectorValues> tryFetch(
-                Collection<DatasetReference> datasets)
-        {
-            GroupByMap<String/* datastore code */, DatasetReference> datastoreToDatasetsMap =
-                    GroupByMap.create(datasets, new IKeyExtractor<String, DatasetReference>()
-                        {
-                            public String getKey(DatasetReference datasetReference)
-                            {
-                                return datasetReference.getDatastoreCode();
-                            }
-                        });
-            WellFeatureCollection<FeatureVectorValues> allFeatures = null;
-            for (String datastoreCode : datastoreToDatasetsMap.getKeys())
-            {
-                List<DatasetReference> datasetsForDatastore =
-                        datastoreToDatasetsMap.getOrDie(datastoreCode);
-                WellFeatureCollection<FeatureVectorValues> features =
-                        fetchFromDatastore(datastoreCode, datasetsForDatastore);
-                if (allFeatures == null)
-                {
-                    allFeatures = features;
-                } else
-                {
-                    mergeFeatures(allFeatures, features);
-                }
-            }
-            return allFeatures;
-        }
-
-        private static void mergeFeatures(WellFeatureCollection<FeatureVectorValues> allFeatures,
-                WellFeatureCollection<FeatureVectorValues> features)
-        {
-            if (allFeatures.getFeatureCodes().equals(features.getFeatureCodes()) == false)
-            {
-                throw new IllegalStateException(
-                        "Cannot merge feature vectors from different datastores because the have different set of features: '"
-                                + allFeatures.getFeatureCodes()
-                                + "' and '"
-                                + features.getFeatureCodes() + "'.");
-            }
-            allFeatures.getFeatures().addAll(features.getFeatures());
-        }
-
-        private WellFeatureCollection<FeatureVectorValues> fetchFromDatastore(String datastoreCode,
-                List<DatasetReference> datasets)
-        {
-            IHCSFeatureVectorLoader loader =
-                    businessObjectFactory.createHCSFeatureVectorLoader(datastoreCode);
-            return loader.fetchDatasetFeatureValues(extractCodes(datasets), featureCodes);
-        }
-
-        private static List<String> extractCodes(List<DatasetReference> datasets)
-        {
-            return CollectionUtils.map(datasets,
-                    new ICollectionMappingFunction<String, DatasetReference>()
-                        {
-                            public String map(DatasetReference element)
-                            {
-                                return element.getCode();
-                            }
-                        });
-        }
-    }
-
-    private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors(
-            Set<PlateIdentifier> plates)
-    {
-        FeatureVectorDatasetLoader datasetsRetriever = createFeatureVectorDatasetsRetriever(plates);
-        Collection<ExternalData> featureVectorDatasets =
-                datasetsRetriever.getFeatureVectorDatasets();
-        if (featureVectorDatasets.isEmpty())
-        {
-            return null;
-        }
-        List<DatasetReference> datasetPerPlate = chooseSingleDatasetForPlate(featureVectorDatasets);
-        List<String> featureCodes = settings.getFeatureCodes();
-        return FeatureVectorRetriever
-                .tryFetch(datasetPerPlate, featureCodes, businessObjectFactory);
-    }
-
     private static Map<WellReference, FeatureVectorValues> createWellToFeatureVectorMap(
             WellFeatureCollection<FeatureVectorValues> featureVectors)
     {
@@ -496,35 +349,4 @@ public class ExperimentFeatureVectorSummaryLoader extends AbstractContentLoader
         return wellToFeatureVectorMap;
     }
 
-    // TODO 2011-04-04, Tomasz Pylak: here if the plate has more than one dataset assigned, we
-    // take the first and ignore the rest. The clean solution would be to introduce analysis
-    // runs, where each plate has at most one analysis dataset in each run. {@link
-    // UniqueKeyViolationStrategy} could be set to {@link UniqueKeyViolationStrategy.ERROR} in
-    // such a case.
-    protected static List<DatasetReference> chooseSingleDatasetForPlate(
-            Collection<ExternalData> datasets)
-    {
-        TableMap<String, ExternalData> plateToDatasetMap =
-                new TableMap<String, ExternalData>(datasets,
-                        new IKeyExtractor<String, ExternalData>()
-                            {
-                                public String getKey(ExternalData externalData)
-                                {
-                                    Sample plate = externalData.getSample();
-                                    return plate != null ? plate.getPermId() : null;
-                                }
-                            }, UniqueKeyViolationStrategy.KEEP_FIRST);
-
-        List<DatasetReference> datasetPerPlate = new ArrayList<DatasetReference>();
-        for (String platePermId : plateToDatasetMap.keySet())
-        {
-            if (platePermId != null)
-            {
-                ExternalData dataset = plateToDatasetMap.getOrDie(platePermId);
-                DatasetReference datasetReference = ScreeningUtils.createDatasetReference(dataset);
-                datasetPerPlate.add(datasetReference);
-            }
-        }
-        return datasetPerPlate;
-    }
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..15789fed5d4c25cb29944fda1516a38e14c70152
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialAllAssaysFeatureVectorSummaryLoader.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.plugin.screening.server.logic;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import ch.systemsx.cisd.common.collections.CollectionUtils;
+import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction;
+import ch.systemsx.cisd.common.collections.GroupByMap;
+import ch.systemsx.cisd.common.collections.IKeyExtractor;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSimpleFeatureVectorSummary;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection;
+
+/**
+ * Finds all experiments where the given material is present and calculates summaries for feature
+ * vectors (if analysis data are available) .
+ * 
+ * @author Tomasz Pylak
+ */
+public class MaterialAllAssaysFeatureVectorSummaryLoader extends AbstractContentLoader
+{
+    public static List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays(
+            Session session, IScreeningBusinessObjectFactory businessObjectFactory,
+            IDAOFactory daoFactory, TechId materialId, MaterialSummarySettings settings)
+    {
+        List<WellContent> allAssayWellsForMaterial =
+                WellContentLoader.loadOnlyMetadata(session, businessObjectFactory, daoFactory,
+                        materialId);
+        return new MaterialAllAssaysFeatureVectorSummaryLoader(session, businessObjectFactory,
+                daoFactory, settings).loadMaterialFeatureVectorsFromAllAssays(materialId,
+                allAssayWellsForMaterial);
+    }
+
+    private final MaterialSummarySettings settings;
+
+    private MaterialAllAssaysFeatureVectorSummaryLoader(Session session,
+            IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory,
+            MaterialSummarySettings settings)
+    {
+        super(session, businessObjectFactory, daoFactory);
+        this.settings = settings;
+    }
+
+    /**
+     * Note that different experiments can have different set of features!
+     */
+    private List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays(
+            TechId materialId, List<WellContent> allAssayWellsForMaterial)
+    {
+        Set<PlateIdentifier> plates = extractPlates(allAssayWellsForMaterial);
+        WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull =
+                tryLoadWellSingleFeatureVectors(plates);
+
+        Map<ExperimentReference, Set<WellReference>> wellsForExperimentMap =
+                groupWellsByExperiment(allAssayWellsForMaterial);
+
+        List<MaterialSimpleFeatureVectorSummary> summaries =
+                new ArrayList<MaterialSimpleFeatureVectorSummary>();
+        for (ExperimentReference experiment : wellsForExperimentMap.keySet())
+        {
+            Set<WellReference> experimentWells = wellsForExperimentMap.get(experiment);
+
+            MaterialSimpleFeatureVectorSummary summary =
+                    calculateExperimentFeatureVectorSummary(materialId, experiment,
+                            experimentWells, allWellFeaturesOrNull);
+            summaries.add(summary);
+        }
+        return summaries;
+    }
+
+    private MaterialSimpleFeatureVectorSummary calculateExperimentFeatureVectorSummary(
+            TechId materialId, ExperimentReference experiment, Set<WellReference> experimentWells,
+            WellFeatureCollection<FeatureVectorValues> allWellFeaturesOrNull)
+    {
+        if (allWellFeaturesOrNull == null)
+        {
+            return new MaterialSimpleFeatureVectorSummary(experiment);
+        }
+
+        List<IWellData> experimentWellData =
+                selectExperimentWellData(experimentWells, allWellFeaturesOrNull, materialId);
+        float[] summaryFeatureVector =
+                WellReplicaSummaryCalculator.calculateSummaryFeatureVector(experimentWellData,
+                        settings.getAggregationType());
+        return new MaterialSimpleFeatureVectorSummary(experiment,
+                allWellFeaturesOrNull.getFeatureCodesAndLabels(), summaryFeatureVector);
+    }
+
+    private static List<IWellData> selectExperimentWellData(Set<WellReference> experimentWells,
+            WellFeatureCollection<FeatureVectorValues> allWellFeatures, TechId materialId)
+    {
+        List<String> orderedFeatureLabels = allWellFeatures.getFeatureLabels();
+
+        List<IWellData> experimentWellDataList = new ArrayList<IWellData>();
+        List<FeatureVectorValues> features = allWellFeatures.getFeatures();
+        for (FeatureVectorValues feature : features)
+        {
+            if (experimentWells.contains(feature.getWellReference()))
+            {
+                float[] values =
+                        WellFeatureCollectionLoader.asFeatureVectorValues(feature,
+                                orderedFeatureLabels);
+                IWellData wellData = new WellData(materialId.getId(), values);
+                experimentWellDataList.add(wellData);
+            }
+        }
+        return experimentWellDataList;
+    }
+
+    private static Map<ExperimentReference, Set<WellReference>> groupWellsByExperiment(
+            List<WellContent> allAssayWellsForMaterial)
+    {
+        GroupByMap<ExperimentReference, WellContent> expToWellContentMap =
+                GroupByMap.create(allAssayWellsForMaterial,
+                        new IKeyExtractor<ExperimentReference, WellContent>()
+                            {
+                                public ExperimentReference getKey(WellContent wellContent)
+                                {
+                                    return wellContent.getExperiment();
+                                }
+                            });
+        return convertToWellReferences(expToWellContentMap);
+    }
+
+    private static Map<ExperimentReference, Set<WellReference>> convertToWellReferences(
+            GroupByMap<ExperimentReference, WellContent> expToWellContentMap)
+    {
+        Map<ExperimentReference, Set<WellReference>> map =
+                new HashMap<ExperimentReference, Set<WellReference>>();
+        for (ExperimentReference exp : expToWellContentMap.getKeys())
+        {
+            List<WellContent> wellContents = expToWellContentMap.getOrDie(exp);
+            map.put(exp, asWellReferences(wellContents));
+        }
+        return map;
+    }
+
+    private static Set<WellReference> asWellReferences(List<WellContent> wellContents)
+    {
+        List<WellReference> wells =
+                CollectionUtils.map(wellContents,
+                        new ICollectionMappingFunction<WellReference, WellContent>()
+                            {
+                                public WellReference map(WellContent wellContent)
+                                {
+                                    return new WellReference(wellContent.tryGetLocation(),
+                                            wellContent.getPlate().getPermId());
+                                }
+                            });
+        return new HashSet<WellReference>(wells);
+    }
+
+    private static Set<PlateIdentifier> extractPlates(List<WellContent> wells)
+    {
+        Set<PlateIdentifier> plates = new HashSet<PlateIdentifier>();
+        for (WellContent well : wells)
+        {
+            String platePermId = well.getPlate().getPermId();
+            PlateIdentifier plateIdent = PlateIdentifier.createFromPermId(platePermId);
+            plates.add(plateIdent);
+        }
+        return plates;
+    }
+
+    private WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors(
+            Set<PlateIdentifier> plateIdentifiers)
+    {
+        return new WellFeatureCollectionLoader(session, businessObjectFactory, daoFactory)
+                .tryLoadWellSingleFeatureVectors(plateIdentifiers, settings.getFeatureCodes());
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java
index 1430c9256d587e62553293aebfb617393e52ccd3..09604792a2df91c636d6f05963b172800dce9f79 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoader.java
@@ -43,9 +43,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialBiolog
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummary;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaFeatureSummaryResult;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSimpleFeatureVectorSummary;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
 
 /**
  * For the specified material in the specified experiment loads feature vectors (details and
@@ -56,30 +54,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
  */
 public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorSummaryLoader
 {
-    public static List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays(
-            Session session, IScreeningBusinessObjectFactory businessObjectFactory,
-            IDAOFactory daoFactory, TechId materialId, MaterialSummarySettings settings)
-    {
-        List<WellContent> allAssayWellsForMaterial =
-                WellContentLoader.loadOnlyMetadata(session, businessObjectFactory, daoFactory,
-                        materialId);
-        // Probably the result DTO has to be converted (here?) to fit the GUI needs better.
-        // Note that different experiments can have different set of features!
-        return new MaterialFeatureVectorSummaryLoader(session, businessObjectFactory, daoFactory,
-                settings).loadMaterialFeatureVectorsFromAllAssays(materialId,
-                allAssayWellsForMaterial);
-    }
-
-    /**
-     * Note that different experiments can have different set of features!
-     */
-    private List<MaterialSimpleFeatureVectorSummary> loadMaterialFeatureVectorsFromAllAssays(
-            TechId materialId, List<WellContent> allAssayWellsForMaterial)
-    {
-        // TODO 2011-05-20, Tomasz Pylak: implement me!
-        return null;
-    }
-
     /**
      * For comments {@See MaterialFeatureVectorSummaryLoader}.
      */
@@ -286,7 +260,8 @@ public class MaterialFeatureVectorSummaryLoader extends ExperimentFeatureVectorS
             List<? extends IWellData> experimentWellDataList)
     {
         List<MaterialIdFeatureVectorSummary> featureSummaries =
-                calculateReplicasFeatureVectorSummaries(experimentWellDataList);
+                WellReplicaSummaryCalculator.calculateReplicasFeatureVectorSummaries(
+                        experimentWellDataList, settings.getAggregationType());
         return tryFindMaterialSummary(materialId, featureSummaries);
     }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..18c5fe2bce031389b194e8a6472dc22345bdf5b4
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellFeatureCollectionLoader.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.plugin.screening.server.logic;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import ch.systemsx.cisd.common.collections.CollectionUtils;
+import ch.systemsx.cisd.common.collections.CollectionUtils.ICollectionMappingFunction;
+import ch.systemsx.cisd.common.collections.GroupByMap;
+import ch.systemsx.cisd.common.collections.IKeyExtractor;
+import ch.systemsx.cisd.common.collections.TableMap;
+import ch.systemsx.cisd.common.collections.TableMap.UniqueKeyViolationStrategy;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.screening.server.IScreeningBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureVectorValues;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.WellFeatureCollection;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader;
+
+/**
+ * Loads feature vectors for chosen plates.
+ * 
+ * @author Tomasz Pylak
+ */
+public class WellFeatureCollectionLoader extends AbstractContentLoader
+{
+    public WellFeatureCollectionLoader(Session session,
+            IScreeningBusinessObjectFactory businessObjectFactory, IDAOFactory daoFactory)
+    {
+        super(session, businessObjectFactory, daoFactory);
+    }
+
+    /** Loads feature vectors for chosen plates and set of features */
+    public WellFeatureCollection<FeatureVectorValues> tryLoadWellSingleFeatureVectors(
+            Set<PlateIdentifier> plates, List<String> featureCodes)
+    {
+        FeatureVectorDatasetLoader datasetsRetriever = createFeatureVectorDatasetsRetriever(plates);
+        Collection<ExternalData> featureVectorDatasets =
+                datasetsRetriever.getFeatureVectorDatasets();
+        if (featureVectorDatasets.isEmpty())
+        {
+            return null;
+        }
+        List<DatasetReference> datasetPerPlate = chooseSingleDatasetForPlate(featureVectorDatasets);
+        return FeatureVectorRetriever
+                .tryFetch(datasetPerPlate, featureCodes, businessObjectFactory);
+    }
+
+    // TODO 2011-04-04, Tomasz Pylak: here if the plate has more than one dataset assigned, we
+    // take the first and ignore the rest. The clean solution would be to introduce analysis
+    // runs, where each plate has at most one analysis dataset in each run. {@link
+    // UniqueKeyViolationStrategy} could be set to {@link UniqueKeyViolationStrategy.ERROR} in
+    // such a case.
+    private static List<DatasetReference> chooseSingleDatasetForPlate(
+            Collection<ExternalData> datasets)
+    {
+        TableMap<String, ExternalData> plateToDatasetMap =
+                new TableMap<String, ExternalData>(datasets,
+                        new IKeyExtractor<String, ExternalData>()
+                            {
+                                public String getKey(ExternalData externalData)
+                                {
+                                    Sample plate = externalData.getSample();
+                                    return plate != null ? plate.getPermId() : null;
+                                }
+                            }, UniqueKeyViolationStrategy.KEEP_FIRST);
+
+        List<DatasetReference> datasetPerPlate = new ArrayList<DatasetReference>();
+        for (String platePermId : plateToDatasetMap.keySet())
+        {
+            if (platePermId != null)
+            {
+                ExternalData dataset = plateToDatasetMap.getOrDie(platePermId);
+                DatasetReference datasetReference = ScreeningUtils.createDatasetReference(dataset);
+                datasetPerPlate.add(datasetReference);
+            }
+        }
+        return datasetPerPlate;
+    }
+
+    /**
+     * Fetches feature vectors from different datastores and merges them (assuming that feature
+     * codes are the same).
+     */
+    private static class FeatureVectorRetriever
+    {
+        public static WellFeatureCollection<FeatureVectorValues> tryFetch(
+                Collection<DatasetReference> datasets, List<String> featureCodes,
+                IScreeningBusinessObjectFactory businessObjectFactory)
+        {
+            assert datasets.size() > 0 : "No feature vector datasets specified.";
+            return new FeatureVectorRetriever(businessObjectFactory, featureCodes)
+                    .tryFetch(datasets);
+        }
+
+        private final IScreeningBusinessObjectFactory businessObjectFactory;
+
+        private final List<String> featureCodes;
+
+        public FeatureVectorRetriever(IScreeningBusinessObjectFactory businessObjectFactory,
+                List<String> featureCodes)
+        {
+            this.businessObjectFactory = businessObjectFactory;
+            this.featureCodes = featureCodes;
+        }
+
+        private WellFeatureCollection<FeatureVectorValues> tryFetch(
+                Collection<DatasetReference> datasets)
+        {
+            GroupByMap<String/* datastore code */, DatasetReference> datastoreToDatasetsMap =
+                    GroupByMap.create(datasets, new IKeyExtractor<String, DatasetReference>()
+                        {
+                            public String getKey(DatasetReference datasetReference)
+                            {
+                                return datasetReference.getDatastoreCode();
+                            }
+                        });
+            WellFeatureCollection<FeatureVectorValues> allFeatures = null;
+            for (String datastoreCode : datastoreToDatasetsMap.getKeys())
+            {
+                List<DatasetReference> datasetsForDatastore =
+                        datastoreToDatasetsMap.getOrDie(datastoreCode);
+                WellFeatureCollection<FeatureVectorValues> features =
+                        fetchFromDatastore(datastoreCode, datasetsForDatastore);
+                if (allFeatures == null)
+                {
+                    allFeatures = features;
+                } else
+                {
+                    mergeFeatures(allFeatures, features);
+                }
+            }
+            return allFeatures;
+        }
+
+        private static void mergeFeatures(WellFeatureCollection<FeatureVectorValues> allFeatures,
+                WellFeatureCollection<FeatureVectorValues> features)
+        {
+            if (allFeatures.getFeatureCodes().equals(features.getFeatureCodes()) == false)
+            {
+                throw new IllegalStateException(
+                        "Cannot merge feature vectors from different datastores because the have different set of features: '"
+                                + allFeatures.getFeatureCodes()
+                                + "' and '"
+                                + features.getFeatureCodes() + "'.");
+            }
+            allFeatures.getFeatures().addAll(features.getFeatures());
+        }
+
+        private WellFeatureCollection<FeatureVectorValues> fetchFromDatastore(String datastoreCode,
+                List<DatasetReference> datasets)
+        {
+            IHCSFeatureVectorLoader loader =
+                    businessObjectFactory.createHCSFeatureVectorLoader(datastoreCode);
+            return loader.fetchDatasetFeatureValues(extractCodes(datasets), featureCodes);
+        }
+
+        private static List<String> extractCodes(List<DatasetReference> datasets)
+        {
+            return CollectionUtils.map(datasets,
+                    new ICollectionMappingFunction<String, DatasetReference>()
+                        {
+                            public String map(DatasetReference element)
+                            {
+                                return element.getCode();
+                            }
+                        });
+        }
+    }
+
+    public static float[] asFeatureVectorValues(FeatureVectorValues featureVector,
+            List<String> orderedFeatureLabels)
+    {
+        Map<String, FeatureValue> featureMap = featureVector.getFeatureMap();
+        float[] values = new float[featureMap.size()];
+        int i = 0;
+        for (String featureLabel : orderedFeatureLabels)
+        {
+            FeatureValue featureValue = featureMap.get(featureLabel);
+            values[i++] = asFloat(featureValue);
+        }
+        return values;
+    }
+
+    private static float asFloat(FeatureValue featureValue)
+    {
+        return featureValue.isFloat() ? featureValue.asFloat() : Float.NaN;
+    }
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java
index 877c98c50581c84218792d7a75c61360f52ba1b7..518f0d53227b3c7638b2f686eb609706490bce11 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculator.java
@@ -30,7 +30,7 @@ import ch.systemsx.cisd.common.collections.GroupByMap;
 import ch.systemsx.cisd.common.collections.IKeyExtractor;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary;
-import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType;
 
 /**
@@ -188,7 +188,7 @@ public class WellReplicaSummaryCalculator
         {
             Long replicaId = entry.getKey();
             float[] aggregates = entry.getValue().getAggregates();
-            IWellData summaryWellData = new WellData(replicaId, aggregates, null, null);
+            IWellData summaryWellData = new WellExtendedData(replicaId, aggregates, null, null);
             summaryWellDataList.add(summaryWellData);
         }
         return summaryWellDataList;
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java
index faad1e050314296d1307c6ea2b3cfaeb081139df..3dc98d7fbd3b38c7a66dbb224679ca37982147a4 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellData.java
@@ -17,33 +17,22 @@
 package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto;
 
 import java.util.Arrays;
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 
 /**
- * The simplest implementation of {@Link IWellExtendedData}.
+ * The simplest implementation of {@Link IWellData}.
  * 
  * @author Tomasz Pylak
  */
-public class WellData implements IWellExtendedData
+public class WellData implements IWellData
 {
     private final long replicaId;
 
-    private Sample well;
-
     private final float[] featureVector;
 
-    private final Material material;
-
-    public WellData(long replicaId, float[] featureVector, Sample well, Material material)
+    public WellData(long replicaId, float[] featureVector)
     {
-        this.well = well;
         this.featureVector = featureVector;
         this.replicaId = replicaId;
-        this.material = material;
     }
 
     public long getReplicaMaterialId()
@@ -51,35 +40,14 @@ public class WellData implements IWellExtendedData
         return replicaId;
     }
 
-    public Sample getWell()
-    {
-        return well;
-    }
-
     public float[] getFeatureVector()
     {
         return featureVector;
     }
 
-    public Material getMaterial()
-    {
-        return material;
-    }
-
     @Override
     public String toString()
     {
         return "repl " + replicaId + ": " + Arrays.toString(featureVector);
     }
-
-    public List<IEntityProperty> getProperties()
-    {
-        return well.getProperties();
-    }
-
-    public Long getId()
-    {
-        return well.getId();
-    }
-
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java
new file mode 100644
index 0000000000000000000000000000000000000000..32e62f85443b20d71f30ec1a19ea9745e96949d9
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/dto/WellExtendedData.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+
+/**
+ * The simplest implementation of {@Link IWellExtendedData}.
+ * 
+ * @author Tomasz Pylak
+ */
+public class WellExtendedData extends WellData implements IWellExtendedData
+{
+    private Sample well;
+
+    private final Material material;
+
+    public WellExtendedData(long replicaId, float[] featureVector, Sample well, Material material)
+    {
+        super(replicaId, featureVector);
+        this.well = well;
+        this.material = material;
+    }
+
+    public Sample getWell()
+    {
+        return well;
+    }
+
+    public Material getMaterial()
+    {
+        return material;
+    }
+
+    public List<IEntityProperty> getProperties()
+    {
+        return well.getProperties();
+    }
+
+    public Long getId()
+    {
+        return well.getId();
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java
index 2e98b79183291e89803629d71d682eb2226188ba..6473e4f7b5e1cc07e7f0e277068e6557acdb44cd 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/ExperimentReference.java
@@ -107,4 +107,29 @@ public class ExperimentReference implements ISerializable, IEntityInformationHol
     {
         return getIdentifier();
     }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (int) (experimentId ^ (experimentId >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ExperimentReference other = (ExperimentReference) obj;
+        if (experimentId != other.experimentId)
+            return false;
+        return true;
+    }
+
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java
index ba74534835193d5f92c8558414786fbb02fd8496..f9094b78fd7c58fe0816b7533c94264b3cd456b9 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/MaterialSimpleFeatureVectorSummary.java
@@ -16,11 +16,12 @@
 
 package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder;
 
 /**
@@ -32,21 +33,30 @@ public class MaterialSimpleFeatureVectorSummary implements ISerializable
 {
     private static final long serialVersionUID = ServiceVersionHolder.VERSION;
 
-    private Experiment experiment;
+    private ExperimentReference experiment;
 
-    // has the same length as feature vectors summary
+    // Has the same length as feature vectors summary.
+    // Note that it can be empty if there are no analysis results!
     private List<CodeAndLabel> featureDescriptions;
 
     private float[] featureVectorSummary;
 
     // GTW
-    // TODO KE: create a separate DTO for the UI layer if there is enough time
     @SuppressWarnings("unused")
     private MaterialSimpleFeatureVectorSummary()
     {
     }
 
-    public MaterialSimpleFeatureVectorSummary(Experiment experiment,
+    /**
+     * Useful when there are no analysis results for a material in the experiment (but there can be
+     * still some images acquired).
+     */
+    public MaterialSimpleFeatureVectorSummary(ExperimentReference experiment)
+    {
+        this(experiment, new ArrayList<CodeAndLabel>(), new float[0]);
+    }
+
+    public MaterialSimpleFeatureVectorSummary(ExperimentReference experiment,
             List<CodeAndLabel> featureDescriptions, float[] featureVectorSummary)
     {
         this.experiment = experiment;
@@ -54,7 +64,7 @@ public class MaterialSimpleFeatureVectorSummary implements ISerializable
         this.featureVectorSummary = featureVectorSummary;
     }
 
-    public Experiment getExperiment()
+    public ExperimentReference getExperiment()
     {
         return experiment;
     }
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java
index c9fefa41a60c69f011c7c7f65f7e57093678dfc4..2a6db8a96558385d63bcc1afe8d5b7169c3f9036 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/MaterialFeatureVectorSummaryLoaderTest.java
@@ -39,7 +39,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellExtendedD
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialAllReplicasFeatureVectors;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialBiologicalReplicateFeatureVector;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary;
-import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellDataCollection;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialSummarySettings;
@@ -147,6 +147,6 @@ public class MaterialFeatureVectorSummaryLoaderTest extends AssertJUnit
         material.setProperties(properties);
         well.setProperties(properties);
 
-        return new WellData(replicaId, featureValues, well, material);
+        return new WellExtendedData(replicaId, featureValues, well, material);
     }
 }
\ No newline at end of file
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java
index 69f2f5322fc4d09d5bc49ca3926ebdc732746840..739e1be813f4bce3e7726cbb24d0bbf8b7eddfc7 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellReplicaSummaryCalculatorTest.java
@@ -33,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.WellReplicaSummaryCalculator.SummaryFeatureVector;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.IWellData;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.MaterialIdFeatureVectorSummary;
-import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellData;
+import ch.systemsx.cisd.openbis.plugin.screening.server.logic.dto.WellExtendedData;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.MaterialReplicaSummaryAggregationType;
 
 /**
@@ -206,7 +206,7 @@ public class WellReplicaSummaryCalculatorTest extends AssertJUnit
     {
         Material material = new Material();
         material.setId(replicaId);
-        return new WellData(replicaId, featureValues, null, material);
+        return new WellExtendedData(replicaId, featureValues, null, material);
     }
 
     private List<MaterialIdFeatureVectorSummary> calculate(List<IWellData> wellDataList)