diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/TabularDataGraphServlet.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/TabularDataGraphServlet.java
index 6023113ff5b52bad79616de1417c671cb83afd9b..829933ec0f7b8e430dd9a8fcb610a323b088960a 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/TabularDataGraphServlet.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/TabularDataGraphServlet.java
@@ -19,8 +19,6 @@ package ch.systemsx.cisd.openbis.dss.generic.server;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.servlet.http.HttpServletRequest;
@@ -28,12 +26,10 @@ import javax.servlet.http.HttpServletRequest;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ITabularData;
+import ch.systemsx.cisd.openbis.dss.screening.server.util.FeatureVectorLoaderMetadataProviderFactory;
 import ch.systemsx.cisd.openbis.dss.shared.DssScreeningUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.CodeNormalizer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.PlateUtils;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
@@ -209,34 +205,7 @@ public class TabularDataGraphServlet extends AbstractTabularDataGraphServlet
     private static IMetadataProvider createFeatureVectorsMetadataProvider()
     {
         final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
-        return new IMetadataProvider()
-            {
-                @Override
-                public SampleIdentifier tryGetSampleIdentifier(String samplePermId)
-                {
-                    return openBISService.tryGetSampleIdentifier(samplePermId);
-                }
-
-                @Override
-                public List<String> tryGetContainedDatasets(String datasetCode)
-                {
-                    AbstractExternalData ds = openBISService.tryGetDataSet(datasetCode);
-                    ContainerDataSet container = ds.tryGetAsContainerDataSet();
-                    if (container != null)
-                    {
-                        List<String> list = new LinkedList<String>();
-                        for (AbstractExternalData contained : container.getContainedDataSets())
-                        {
-                            list.add(contained.getCode());
-                        }
-                        return list;
-                    } else
-                    {
-                        return Collections.emptyList();
-                    }
-                }
-
-            };
+        return FeatureVectorLoaderMetadataProviderFactory.createMetadataProvider(openBISService);
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java
index dbeeed4ee4e2cdb8429304e94cc2c7b0054c0555..62db47b673a8d3d8146cf7ade3a36131e249a4ab 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/ImageAnalysisMergedRowsReportingPlugin.java
@@ -18,27 +18,22 @@ package ch.systemsx.cisd.openbis.dss.generic.server.plugins;
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Properties;
 
 import ch.systemsx.cisd.openbis.dss.generic.server.plugins.standard.AbstractTableModelReportingPlugin;
 import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
-import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.screening.server.util.FeatureVectorLoaderMetadataProviderFactory;
 import ch.systemsx.cisd.openbis.dss.shared.DssScreeningUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.CodeNormalizer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeAndLabel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DoubleTableCell;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IntegerTableCell;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.StringTableCell;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.util.SimpleTableModelBuilder;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.PlateUtils;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.FeatureValue;
@@ -94,7 +89,7 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractTableModelRe
         ArrayList<String> featureCodes = new ArrayList<String>(); // fetch all
         WellFeatureCollection<FeatureTableRow> featuresCollection =
                 FeatureVectorLoader.fetchDatasetFeatures(datasetCodes, featureCodes, getDAO(),
-                        getMetadataProvider());
+                        getMetadataProvider(datasetCodes));
 
         List<CodeAndLabel> codeAndLabels = featuresCollection.getFeatureCodesAndLabels();
         List<FeatureTableRow> rows = featuresCollection.getFeatures();
@@ -177,47 +172,17 @@ public class ImageAnalysisMergedRowsReportingPlugin extends AbstractTableModelRe
         return dao;
     }
 
-    private IMetadataProvider getMetadataProvider()
+    private IMetadataProvider getMetadataProvider(final List<String> datasetCodes)
     {
         synchronized (this)
         {
             if (metadataProvider == null)
             {
-                metadataProvider = createFeatureVectorsMetadataProvider();
+                metadataProvider =
+                        FeatureVectorLoaderMetadataProviderFactory.createMetadataProvider(
+                                ServiceProvider.getOpenBISService(), datasetCodes);
             }
         }
         return metadataProvider;
     }
-
-    private static IMetadataProvider createFeatureVectorsMetadataProvider()
-    {
-        final IEncapsulatedOpenBISService openBISService = ServiceProvider.getOpenBISService();
-        return new IMetadataProvider()
-            {
-                @Override
-                public SampleIdentifier tryGetSampleIdentifier(String samplePermId)
-                {
-                    return openBISService.tryGetSampleIdentifier(samplePermId);
-                }
-
-                @Override
-                public List<String> tryGetContainedDatasets(String datasetCode)
-                {
-                    AbstractExternalData ds = openBISService.tryGetDataSet(datasetCode);
-                    ContainerDataSet container = ds.tryGetAsContainerDataSet();
-                    if (container != null)
-                    {
-                        List<String> list = new LinkedList<String>();
-                        for (AbstractExternalData contained : container.getContainedDataSets())
-                        {
-                            list.add(contained.getCode());
-                        }
-                        return list;
-                    } else
-                    {
-                        return Collections.emptyList();
-                    }
-                }
-            };
-    }
 }
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 062a0c6e2db7d22148577a1850df24bfe844ad57..61603a40255cbf86cbf23100344896c27af02305 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
@@ -27,7 +27,6 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -66,12 +65,11 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.dss.screening.server.logic.ImageRepresentationFormatFinder;
+import ch.systemsx.cisd.openbis.dss.screening.server.util.FeatureVectorLoaderMetadataProviderFactory;
 import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
 import ch.systemsx.cisd.openbis.dss.shared.DssScreeningUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.CodeNormalizer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.AbstractFormatSelectionCriterion;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.DatasetImageRepresentationFormats;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureInformation;
@@ -482,19 +480,26 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
     {
         List<String> codes = normalize(featureNames);
         List<FeatureVectorDataset> result = new ArrayList<FeatureVectorDataset>();
+
+        IMetadataProvider metadataProvider =
+                FeatureVectorLoaderMetadataProviderFactory
+                        .createMetadataProviderFromFeatureVectors(getOpenBISService(),
+                                featureDatasets);
+
         for (FeatureVectorDatasetReference dataset : featureDatasets)
         {
-            result.add(createFeatureVectorDataset(sessionToken, dataset, codes));
+            result.add(createFeatureVectorDataset(sessionToken, dataset, codes, metadataProvider));
         }
         return result;
     }
 
     private FeatureVectorDataset createFeatureVectorDataset(String sessionToken,
-            FeatureVectorDatasetReference dataset, List<String> featureCodes)
+            FeatureVectorDatasetReference dataset, List<String> featureCodes,
+            IMetadataProvider metadataProvider)
     {
         WellFeatureCollection<FeatureTableRow> datasetFeatures =
                 FeatureVectorLoader.fetchDatasetFeatures(Arrays.asList(dataset.getDatasetCode()),
-                        featureCodes, getDAO(), createMetadataProvider());
+                        featureCodes, getDAO(), metadataProvider);
         List<FeatureVector> featureVectors = new ArrayList<FeatureVector>();
         for (FeatureTableRow featureTableRow : datasetFeatures.getFeatures())
         {
@@ -548,42 +553,12 @@ public class DssServiceRpcScreening extends AbstractDssServiceRpc<IDssServiceRpc
     {
         WellFeatureCollection<FeatureTableRow> features =
                 FeatureVectorLoader.fetchWellFeatures(datasetWellReferences, featureNames, dao,
-                        createMetadataProvider());
+                        FeatureVectorLoaderMetadataProviderFactory
+                                .createMetadataProviderFromFeatureVectors(getOpenBISService(),
+                                        datasetWellReferences));
         return createFeatureVectorList(features);
     }
 
-    private IMetadataProvider createMetadataProvider()
-    {
-        final IEncapsulatedOpenBISService openBISService = getOpenBISService();
-        return new IMetadataProvider()
-            {
-                @Override
-                public SampleIdentifier tryGetSampleIdentifier(String samplePermId)
-                {
-                    return openBISService.tryGetSampleIdentifier(samplePermId);
-                }
-
-                @Override
-                public List<String> tryGetContainedDatasets(String datasetCode)
-                {
-                    AbstractExternalData ds = openBISService.tryGetDataSet(datasetCode);
-                    ContainerDataSet container = ds.tryGetAsContainerDataSet();
-                    if (container != null)
-                    {
-                        List<String> list = new LinkedList<String>();
-                        for (AbstractExternalData contained : container.getContainedDataSets())
-                        {
-                            list.add(contained.getCode());
-                        }
-                        return list;
-                    } else
-                    {
-                        return Collections.emptyList();
-                    }
-                }
-            };
-    }
-
     private List<FeatureVectorWithDescription> createFeatureVectorList(
             final WellFeatureCollection<FeatureTableRow> features)
     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/util/FeatureVectorLoaderMetadataProviderFactory.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/util/FeatureVectorLoaderMetadataProviderFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7473530085a8e3e83d0302a69fc012123d4ba3d
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/screening/server/util/FeatureVectorLoaderMetadataProviderFactory.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2013 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.screening.server.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.FeatureVectorDatasetReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoader.IMetadataProvider;
+
+/**
+ * Creates a metadata provider for feature data set loader based on the IEncapsulatedOpenBISService
+ * 
+ * @author Jakub Straszewski
+ */
+public class FeatureVectorLoaderMetadataProviderFactory
+{
+
+    private static HashMap<String, List<String>> createContainedDatasetMapFromFeatureVectors(
+            IEncapsulatedOpenBISService service,
+            List<? extends FeatureVectorDatasetReference> featureDatasets)
+    {
+
+        List<String> dsCodes = new LinkedList<String>();
+
+        for (FeatureVectorDatasetReference ds : featureDatasets)
+        {
+            dsCodes.add(ds.getDatasetCode());
+        }
+
+        return createContainedDatasetMap(service, dsCodes);
+    }
+
+    private static HashMap<String, List<String>> createContainedDatasetMap(
+            IEncapsulatedOpenBISService service, List<String> dsCodes)
+    {
+        List<AbstractExternalData> dataSets = service.listDataSetsByCode(dsCodes);
+
+        HashMap<String, List<String>> containedDataSetsMap = new HashMap<String, List<String>>();
+
+        for (AbstractExternalData dataSet : dataSets)
+        {
+            List<String> list = getContainedDatasets(dataSet);
+            containedDataSetsMap.put(dataSet.getCode(), list);
+        }
+        return containedDataSetsMap;
+    }
+
+    private static List<String> getContainedDatasets(AbstractExternalData dataSet)
+    {
+        List<String> list;
+        ContainerDataSet container = dataSet.tryGetAsContainerDataSet();
+        if (container != null)
+        {
+            list = new LinkedList<String>();
+            for (AbstractExternalData contained : container.getContainedDataSets())
+            {
+                list.add(contained.getCode());
+            }
+        } else
+        {
+            list = Collections.<String> emptyList();
+        }
+        return list;
+    }
+
+    /**
+     * Metadata provider that get's the request for dataset only once for all datasets at the moment
+     * of creation.
+     */
+    public static IMetadataProvider createMetadataProvider(
+            final IEncapsulatedOpenBISService openBISService, final List<String> dataSetCodes)
+    {
+
+        return createMetadataProvider(openBISService,
+                createContainedDatasetMap(openBISService, dataSetCodes));
+    }
+
+    /**
+     * Creates a metadata provider that will always ask openbis service about the required
+     * information
+     */
+    public static IMetadataProvider createMetadataProvider(
+            final IEncapsulatedOpenBISService openBISService)
+    {
+        return new IMetadataProvider()
+            {
+
+                @Override
+                public SampleIdentifier tryGetSampleIdentifier(String samplePermId)
+                {
+                    return openBISService.tryGetSampleIdentifier(samplePermId);
+                }
+
+                @Override
+                public List<String> tryGetContainedDatasets(String datasetCode)
+                {
+                    AbstractExternalData dataSet = openBISService.tryGetDataSet(datasetCode);
+                    return getContainedDatasets(dataSet);
+                }
+            };
+    }
+
+    /**
+     * Metadata provider that get's the request for dataset only once for all datasets at the moment
+     * of creation
+     */
+    public static IMetadataProvider createMetadataProviderFromFeatureVectors(
+            final IEncapsulatedOpenBISService openBISService,
+            final List<? extends FeatureVectorDatasetReference> featureDatasets)
+    {
+
+        return createMetadataProvider(openBISService,
+                createContainedDatasetMapFromFeatureVectors(openBISService, featureDatasets));
+    }
+
+    private static IMetadataProvider createMetadataProvider(
+            final IEncapsulatedOpenBISService openBISService,
+            final HashMap<String, List<String>> containedDataSetsMap)
+    {
+
+        return new IMetadataProvider()
+            {
+                @Override
+                public SampleIdentifier tryGetSampleIdentifier(String samplePermId)
+                {
+                    return openBISService.tryGetSampleIdentifier(samplePermId);
+                }
+
+                @Override
+                public List<String> tryGetContainedDatasets(String datasetCode)
+                {
+                    if (containedDataSetsMap.containsKey(datasetCode))
+                    {
+                        return containedDataSetsMap.get(datasetCode);
+                    } else
+                    {
+                        throw new IllegalArgumentException(
+                                "Data set code unknown to the provider. " + datasetCode);
+                    }
+                }
+            };
+    }
+}
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 d13e877cc867f0b0b42691fc0257ce545aafc7a9..f6e57d93178496f316ceae350537d908c822b516 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
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.aopalliance.intercept.MethodInterceptor;
@@ -72,9 +73,9 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.authorization.Ds
 import ch.systemsx.cisd.openbis.dss.generic.shared.dto.Size;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.ImageUtilTest;
 import ch.systemsx.cisd.openbis.dss.screening.shared.api.v1.IDssServiceRpcScreening;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataSetBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
@@ -339,10 +340,14 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
     @Test
     public void testLoadFeatures()
     {
+        prepareFeatureVectorContainedDatasets(new long[]
+            { 1, 2 });
+
         prepareAssetDataSetsAreAccessible();
         prepareLockDataSet("ds1", DATASET_CODE2);
         FeatureVectorDatasetReference r1 = createFeatureVectorDatasetReference(DATASET_CODE);
         FeatureVectorDatasetReference r2 = createFeatureVectorDatasetReference(DATASET_CODE2);
+
         String[][] featureCodesPerDataset = new String[][]
             {
                 { "F1", "F2" } };
@@ -378,7 +383,6 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
 
     private void prepareLoadFeatures(long[] dataSetIDs, String[][] featureCodesPerDataset)
     {
-        prepareFeatureVectorContainedDatasets(dataSetIDs);
         prepareListAnalysisDatasets(dataSetIDs);
         prepareListContainers(dataSetIDs);
         prepareGetFeatureDefinitions(dataSetIDs, featureCodesPerDataset);
@@ -928,16 +932,20 @@ public class DssServiceRpcScreeningTest extends AssertJUnit
                 {
                     String[] permIDs = new String[dataSetIDs.length];
 
+                    List<AbstractExternalData> result = new LinkedList<AbstractExternalData>();
                     for (int i = 0; i < dataSetIDs.length; i++)
                     {
                         long id = dataSetIDs[i];
                         permIDs[i] = "ds" + id;
 
-                        AbstractExternalData d = new PhysicalDataSet(); // this dataset is only asked if it is a
-                                                        // container
-                        one(service).tryGetDataSet(permIDs[i]);
-                        will(returnValue(d));
+                        PhysicalDataSet dataSet = new PhysicalDataSet();
+                        dataSet.setCode(permIDs[i]);
+
+                        result.add(dataSet);
+
                     }
+                    one(service).listDataSetsByCode(with(equal(Arrays.asList(permIDs))));
+                    will(returnValue(result));
                 }
             });
     }