diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
index b91694f61143c0d50aaa8f96842957a727ab1e5a..7ec4de82a1fe38ff8e92cf09e78dbf68b57c4d8b 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
@@ -17,7 +17,6 @@
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers;
 
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL;
-import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_CONTENT_MATERIAL;
 
 import java.util.Arrays;
 import java.util.Date;
@@ -70,10 +69,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKin
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ISerializableComparable;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ClientPluginFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.DisplayTypeIDGenerator;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplayTypeIDGenerator;
@@ -81,7 +78,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.d
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ui.columns.specific.ScreeningLinkExtractor;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ExperimentReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellContent;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellSearchCriteria;
@@ -272,7 +268,6 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
         final IDefaultChannelState defaultChannelState =
                 createDefaultChannelState(viewContext, experimentCriteriaOrNull);
         channelChooser = new ChannelChooserPanel(defaultChannelState);
-        linkWellContent();
         linkExperiment();
         linkPlate();
         linkWell();
@@ -301,38 +296,6 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
         return new DefaultChannelState(viewContext, displayTypeId);
     }
 
-    private void linkWellContent()
-    {
-        registerListenerAndLinkGenerator(WELL_CONTENT_MATERIAL,
-                new ICellListenerAndLinkGenerator<WellContent>()
-                    {
-                        public String tryGetLink(WellContent entity, ISerializableComparable value)
-                        {
-                            Material material = entity.getMaterialContent();
-                            String experimentIdentifier =
-                                    entity.getExperiment().getExperimentIdentifier();
-                            return ScreeningLinkExtractor.tryCreateMaterialDetailsLink(material,
-                                    experimentIdentifier);
-                        }
-
-                        public void handle(TableModelRowWithObject<WellContent> wellContent,
-                                boolean specialKeyPressed)
-                        {
-                            Material contentMaterial =
-                                    wellContent.getObjectOrNull().getMaterialContent();
-                            ExperimentReference experiment =
-                                    wellContent.getObjectOrNull().getExperiment();
-                            ExperimentSearchCriteria experimentCriteria =
-                                    ExperimentSearchCriteria.createExperiment(experiment.getId(),
-                                            experiment.getPermId(),
-                                            experiment.getExperimentIdentifier());
-
-                            ClientPluginFactory.openImagingMaterialViewer(contentMaterial,
-                                    experimentCriteria, viewContext);
-                        }
-                    });
-    }
-
     private void linkExperiment()
     {
         registerListenerAndLinkGenerator(WellSearchGridColumnIds.EXPERIMENT,
@@ -680,7 +643,7 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
     @Override
     protected List<String> getColumnIdsOfFilters()
     {
-        return Arrays.asList(WELL_CONTENT_MATERIAL, WELL);
+        return Arrays.asList(WELL);
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/WellContentProvider.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/WellContentProvider.java
index 887084b72ec60b5f1b176657f6bf8ccdae25ddf5..44808cda3d1c2997c5a5cadf6d2972051b6de0c5 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/WellContentProvider.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/server/WellContentProvider.java
@@ -23,8 +23,6 @@ import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.W
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.PLATE;
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL;
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_COLUMN;
-import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_CONTENT_MATERIAL;
-import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_CONTENT_MATERIAL_TYPE;
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_IMAGES;
 import static ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids.WellSearchGridColumnIds.WELL_ROW;
 
@@ -32,6 +30,7 @@ import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.AbstractTableModelProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
+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.TypedTableModel;
 import ch.systemsx.cisd.openbis.generic.shared.util.IColumn;
@@ -52,6 +51,8 @@ public class WellContentProvider extends AbstractTableModelProvider<WellContent>
 {
     static final String WELL_PROPERTY_ID_PREFIX = "WELL_PROPERTY-";
 
+    static final String MATERIAL_PROPERTY_ID_PREFIX = "MATERIAL-PROPERTY-";
+
     static final String WELL_CONTENT_PROPERTY_ID_PREFIX = "WELL_CONTENT_PROPERTY-";
 
     static final String WELL_CONTENT_FEATURE_VECTOR_PREFIX = "WELL_CONTENT_FEATURE_VECTOR-";
@@ -85,8 +86,6 @@ public class WellContentProvider extends AbstractTableModelProvider<WellContent>
 
     private void addStandardWellColumns(TypedTableModelBuilder<WellContent> builder)
     {
-        builder.addColumn(WELL_CONTENT_MATERIAL);
-        builder.addColumn(WELL_CONTENT_MATERIAL_TYPE);
         builder.addColumn(EXPERIMENT);
         builder.addColumn(PLATE);
         builder.addColumn(WELL);
@@ -101,12 +100,6 @@ public class WellContentProvider extends AbstractTableModelProvider<WellContent>
     private void addRow(TypedTableModelBuilder<WellContent> builder, WellContent well)
     {
         builder.addRow(well);
-        Material material = well.getMaterialContent();
-        String value = material.getCode();
-        builder.column(WELL_CONTENT_MATERIAL).addString(value);
-        builder.column(WELL_CONTENT_MATERIAL_TYPE).addString(material.getEntityType().getCode());
-        builder.columnGroup(WELL_CONTENT_PROPERTY_ID_PREFIX)
-                .addProperties(material.getProperties());
         NamedFeatureVector featureVector = well.tryGetFeatureVectorValues();
         if (featureVector != null)
         {
@@ -129,12 +122,45 @@ public class WellContentProvider extends AbstractTableModelProvider<WellContent>
                 imageDataset == null ? null : imageDataset.getDatasetReference().getFileTypeCode());
         builder.column(WELL_IMAGES).addString(well.tryGetImageDataset() == null ? "" : "[images]");
 
-        if (well.getWellProperties().isEmpty() == false)
+        List<IEntityProperty> wellProperties = well.getWellProperties();
+        builder.columnGroup(WELL_PROPERTY_ID_PREFIX).addProperties(wellProperties);
+        addMaterialProperties(builder, wellProperties);
+    }
+
+    private void addMaterialProperties(TypedTableModelBuilder<WellContent> builder,
+            List<IEntityProperty> wellProperties)
+    {
+        for (IEntityProperty property : wellProperties)
+        {
+            DataTypeCode propertyDataTypeCode = property.getPropertyType().getDataType().getCode();
+            if (propertyDataTypeCode == DataTypeCode.MATERIAL)
+            {
+                addMaterialProperties(builder, property);
+            }
+        }
+    }
+
+    private void addMaterialProperties(TypedTableModelBuilder<WellContent> builder,
+            IEntityProperty materialProperty)
+    {
+        Material materialOrNull = materialProperty.getMaterial();
+        if (materialOrNull != null)
         {
-            builder.columnGroup(WELL_PROPERTY_ID_PREFIX).addProperties(well.getWellProperties());
+            List<IEntityProperty> materialProperties = materialOrNull.getProperties();
+            if (materialProperties != null)
+            {
+                String materialPropsGroupId = getMaterialPropsGroupId(materialProperty);
+                builder.columnGroup(materialPropsGroupId)
+                        .addProperties(materialOrNull.getProperties());
+            }
         }
     }
 
+    private String getMaterialPropsGroupId(IEntityProperty property)
+    {
+        return MATERIAL_PROPERTY_ID_PREFIX + property.getPropertyType().getSimpleCode() + "-";
+    }
+
     private void addFeatureColumns(TypedTableModelBuilder<WellContent> builder,
             NamedFeatureVector featureVector)
     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IScreeningQuery.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IScreeningQuery.java
index 6cbb8fd87939ad803f07a8c32c75812821de8e2a..f840a825259a1bdfe37f870c255d8f625e090a1a 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IScreeningQuery.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/IScreeningQuery.java
@@ -32,7 +32,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.StringArrayMapper;
  * @author Tomasz Pylak
  */
 @Private
-@Friend(toClasses = WellContent.class)
+@Friend(toClasses = WellContentQueryResult.class)
 public interface IScreeningQuery extends BaseQuery
 {
 
@@ -73,7 +73,7 @@ public interface IScreeningQuery extends BaseQuery
      *         Each well will have a material property (e.g. gene) with the specified id.
      */
     @Select(sql = WELLS_FOR_MATERIAL_ID_SELECT + " where well_material.id = ?{1} and exp.id = ?{2}")
-    public DataIterator<WellContent> getPlateLocationsForMaterialId(long materialId,
+    public DataIterator<WellContentQueryResult> getPlateLocationsForMaterialId(long materialId,
             long experimentId);
 
     /**
@@ -81,7 +81,7 @@ public interface IScreeningQuery extends BaseQuery
      *         id.
      */
     @Select(sql = WELLS_FOR_MATERIAL_ID_SELECT + " where well_material.id = ?{1}")
-    public DataIterator<WellContent> getPlateLocationsForMaterialId(long materialId);
+    public DataIterator<WellContentQueryResult> getPlateLocationsForMaterialId(long materialId);
 
     /**
      * @return well locations which belong to a parent plate connected to a specified experiment.
@@ -91,7 +91,7 @@ public interface IScreeningQuery extends BaseQuery
     @Select(sql = WELLS_FOR_MATERIAL_ID_SELECT + " where well_material.id = any(?{1}) and "
             + "well_material_type.code = any(?{2}) and exp.id = ?{3}", parameterBindings =
         { LongArrayMapper.class, StringArrayMapper.class, TypeMapper.class /* default mapper */}, fetchSize = FETCH_SIZE)
-    public DataIterator<WellContent> getPlateLocationsForMaterialCodes(long[] materialIds,
+    public DataIterator<WellContentQueryResult> getPlateLocationsForMaterialCodes(long[] materialIds,
             String[] materialTypeCodes, long experimentId);
 
     /**
@@ -102,7 +102,7 @@ public interface IScreeningQuery extends BaseQuery
     @Select(sql = WELLS_FOR_MATERIAL_ID_SELECT + " where well_material.id = any(?{1}) and "
             + "well_material_type.code = any(?{2})", parameterBindings =
         { LongArrayMapper.class, StringArrayMapper.class }, fetchSize = FETCH_SIZE)
-    public DataIterator<WellContent> getPlateLocationsForMaterialCodes(long[] materialIds,
+    public DataIterator<WellContentQueryResult> getPlateLocationsForMaterialCodes(long[] materialIds,
             String[] materialTypeCodes);
 
     /**
@@ -120,7 +120,7 @@ public interface IScreeningQuery extends BaseQuery
             + "   join materials well_material on well_props.mate_prop_id = well_material.id"
             + "   join material_types well_material_type on well_material.maty_id = well_material_type.id"
             + " where well_material_type.code=?{2} and pl.perm_id=?{1}")
-    public DataIterator<WellContent> getPlateMappingForMaterialType(String platePermId,
+    public DataIterator<WellContentQueryResult> getPlateMappingForMaterialType(String platePermId,
             String materialTypeCode);
 
     /**
@@ -139,7 +139,7 @@ public interface IScreeningQuery extends BaseQuery
             + "   join materials well_material on well_props.mate_prop_id = well_material.id"
             + "   join material_types well_material_type on well_material.maty_id = well_material_type.id"
             + " where pl.perm_id=?{1} order by material_content_type_code")
-    public DataIterator<WellContent> getPlateMapping(String platePermId);
+    public DataIterator<WellContentQueryResult> getPlateMapping(String platePermId);
 
     /**
      * @return the material to well plate mapping for the given <var>spaceCode</var> and
@@ -157,7 +157,7 @@ public interface IScreeningQuery extends BaseQuery
             + "   join materials well_material on well_props.mate_prop_id = well_material.id"
             + "   join material_types well_material_type on well_material.maty_id = well_material_type.id"
             + " where well_material_type.code = ?{3} and pl.code = ?{2} and sp.code = ?{1}")
-    public DataIterator<WellContent> getPlateMappingForMaterialType(String spaceCode,
+    public DataIterator<WellContentQueryResult> getPlateMappingForMaterialType(String spaceCode,
             String plateCode, String materialTypeCode);
 
     /**
@@ -177,7 +177,7 @@ public interface IScreeningQuery extends BaseQuery
             + "   join materials well_material on well_props.mate_prop_id = well_material.id"
             + "   join material_types well_material_type on well_material.maty_id = well_material_type.id"
             + " where sp.code = ?{1} and pl.code = ?{2} order by material_content_type_code")
-    public DataIterator<WellContent> getPlateMapping(String spaceCode, String plateCode);
+    public DataIterator<WellContentQueryResult> getPlateMapping(String spaceCode, String plateCode);
 
     /**
      * Returns the plate geometry string for the plate with given <var>platePermId</var>, or
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContent.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java
similarity index 97%
rename from screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContent.java
rename to screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java
index 29abf1eecfcef65427f15256dee29361fa769e85..17f82ddad7ccd3484d5c606f81124947f463b9a8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContent.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/WellContentQueryResult.java
@@ -22,7 +22,7 @@ import ch.rinn.restrictions.Private;
  * @author Tomasz Pylak
  */
 @Private
-public class WellContent
+public class WellContentQueryResult
 {
     // well pointer
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
index 931634aa7cd439b53c8c55f366c95bde93d7577e..95d9e637caa7dcc2a3b28bff2677ebc52373b967 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImpl.java
@@ -92,7 +92,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
  * @author Tomasz Pylak
  */
 @Friend(toClasses =
-    { ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent.class,
+    { ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult.class,
             PlateGeometryContainer.class })
 public class ScreeningApiImpl
 {
@@ -529,7 +529,7 @@ public class ScreeningApiImpl
             PlateIdentifier plateIdentifier,
             MaterialTypeIdentifier materialTypeIdentifierOrNull,
             PlateGeometryContainer plateGeometryContainer,
-            DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> wellContentList)
+            DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult> wellContentList)
     {
         final Geometry plateGeometry =
                 Geometry.createFromPlateGeometryString(plateGeometryContainer.plate_geometry);
@@ -540,7 +540,7 @@ public class ScreeningApiImpl
                 new PlateWellMaterialMapping(finalPlateIdentifier, plateGeometry, 1);
         if (materialTypeIdentifierOrNull != null)
         {
-            for (ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent wellContent : wellContentList)
+            for (ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult wellContent : wellContentList)
             {
                 final WellLocation location =
                         ScreeningUtils.tryCreateLocationFromMatrixCoordinate(wellContent.well_code);
@@ -552,7 +552,7 @@ public class ScreeningApiImpl
         {
             final Map<String, MaterialTypeIdentifier> map =
                     new HashMap<String, MaterialTypeIdentifier>();
-            for (ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent wellContent : wellContentList)
+            for (ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult wellContent : wellContentList)
             {
                 MaterialTypeIdentifier typeId = map.get(wellContent.material_content_type_code);
                 if (typeId == null)
@@ -597,7 +597,7 @@ public class ScreeningApiImpl
         return plateGeometryContainer;
     }
 
-    private DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> getPlateMapping(
+    private DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult> getPlateMapping(
             IScreeningQuery query, PlateIdentifier plate,
             MaterialTypeIdentifier materialTypeIdentifierOrNull)
     {
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java
index 3c09d44d421baf1e72c26a5c84aa0a082e7b7652..1a1c483c3703ee34731afe2c277628d1131a9cb1 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoader.java
@@ -54,7 +54,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialAttributeSearchFieldKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
@@ -63,6 +62,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePropertyTypePE;
 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.dataaccess.IScreeningQuery;
+import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContentQueryResult;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.api.v1.dto.PlateIdentifier;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetReference;
@@ -82,7 +82,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.FeatureVectorLoa
 import ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.IHCSFeatureVectorLoader;
 
 /**
- * Loades selected wells content: metadata and (if available) image dataset and feature vectors.
+ * Loades selected wells content: metadata and (if available) image dataset.
  * 
  * @author Tomasz Pylak
  */
@@ -103,8 +103,7 @@ public class WellContentLoader
         WellContentLoader loader =
                 new WellContentLoader(session, businessObjectFactory, daoFactory);
 
-        List<WellContent> contents = loader.loadLocations(geneMaterialId, experimentPermId);
-        return loader.enrichWithWellProperties(contents);
+        return loader.loadLocations(geneMaterialId, experimentPermId);
     }
 
     /** loads wells metadata, but no information about image or image analysis datasets */
@@ -113,8 +112,7 @@ public class WellContentLoader
             TechId geneMaterialId)
     {
         final WellContentLoader loader = new WellContentLoader(session, businessObjectFactory, daoFactory);
-        List<WellContent> contents = loader.loadLocations(geneMaterialId);
-        return loader.enrichWithWellProperties(contents);
+        return loader.loadLocations(geneMaterialId);
     }
 
     /**
@@ -130,9 +128,7 @@ public class WellContentLoader
                 new WellContentLoader(session, businessObjectFactory, daoFactory);
 
         List<WellContent> locations = loader.loadLocations(materialCriteria);
-        List<WellContent> uniqueLocations = loader.filterWellDuplicates(locations);
-        List<WellContent> withProperties = loader.enrichWithWellProperties(uniqueLocations);
-        List<WellContent> withPropsAndDataSets = loader.enrichWithDatasets(withProperties);
+        List<WellContent> withPropsAndDataSets = loader.enrichWithDatasets(locations);
         return loader.enrichWithFeatureVectors(withPropsAndDataSets);
     }
 
@@ -152,16 +148,6 @@ public class WellContentLoader
         return new ArrayList<Material>(materials);
     }
 
-    private static Set<Material> extractMaterials(List<WellContent> locations)
-    {
-        Set<Material> materials = new HashSet<Material>();
-        for (WellContent location : locations)
-        {
-            materials.add(location.getMaterialContent());
-        }
-        return materials;
-    }
-
     private final Session session;
 
     private final IScreeningBusinessObjectFactory businessObjectFactory;
@@ -176,24 +162,6 @@ public class WellContentLoader
         this.daoFactory = daoFactory;
     }
 
-    private List<WellContent> filterWellDuplicates(List<WellContent> wellContents)
-    {
-        Set<String> seenPermIds = new HashSet<String>();
-        ArrayList<WellContent> filtered = new ArrayList<WellContent>();
-
-        for (WellContent content : wellContents)
-        {
-            String wellPermId = content.getWell().getPermId();
-            if (false == seenPermIds.contains(wellPermId))
-            {
-                seenPermIds.add(wellPermId);
-                filtered.add(content);
-            }
-        }
-
-        return filtered;
-    }
-
     private List<WellContent> enrichWithWellProperties(List<WellContent> locations)
     {
         Map<Long /* id */, WellContent> wellContents = new HashMap<Long/* id */, WellContent>();
@@ -614,7 +582,7 @@ public class WellContentLoader
 
     private List<WellContent> loadLocations(WellSearchCriteria materialCriteria)
     {
-        DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> locations;
+        DataIterator<WellContentQueryResult> locations;
         MaterialSearchCriteria materialSearchCriteria =
                 materialCriteria.getMaterialSearchCriteria();
         ExperimentSearchCriteria experiment = materialCriteria.getExperimentCriteria();
@@ -724,7 +692,7 @@ public class WellContentLoader
     {
         final long experimentId = loadExperimentIdByPermId(experimentPermId);
 
-        DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> locations =
+        DataIterator<WellContentQueryResult> locations =
                 createDAO(daoFactory).getPlateLocationsForMaterialId(geneMaterialId.getId(),
                         experimentId);
 
@@ -733,71 +701,102 @@ public class WellContentLoader
 
     private List<WellContent> loadLocations(TechId geneMaterialId)
     {
-        DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> locations =
+        DataIterator<WellContentQueryResult> locations =
                 createDAO(daoFactory).getPlateLocationsForMaterialId(geneMaterialId.getId());
         return convert(locations);
     }
 
-    private List<WellContent> convert(
-            DataIterator<ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent> locations)
+    private List<WellContent> convert(DataIterator<WellContentQueryResult> queryResults)
     {
-        List<WellContent> wellLocations = new ArrayList<WellContent>();
+        List<WellContentQueryResult> uniqueResults = removeDuplicateWells(queryResults);
 
-        for (ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent location : locations)
+        ArrayList<WellContent> wellContents = new ArrayList<WellContent>();
+        for (WellContentQueryResult uniqueWell : uniqueResults)
         {
-            wellLocations.add(convert(location));
+            wellContents.add(convert(uniqueWell));
         }
-        sortByMaterialName(wellLocations);
+        sortByWellCode(wellContents);
+        List<WellContent> withProperties = enrichWithWellProperties(wellContents);
         IMaterialLister materialLister = businessObjectFactory.createMaterialLister(session);
-        List<Material> containedMaterials = getMaterials(wellLocations);
+        List<Material> containedMaterials = getMaterialsWithDuplicates(withProperties);
         materialLister.enrichWithProperties(containedMaterials);
-        return wellLocations;
+        return wellContents;
+    }
+    
+    private static Set<Material> extractMaterials(List<WellContent> locations)
+    {
+        Set<Material> materials = new HashSet<Material>();
+        for (WellContent location : locations)
+        {
+            materials.addAll(location.getMaterialContents());
+        }
+        return materials;
     }
 
-    private static List<Material> getMaterials(List<WellContent> wellLocations)
+    /**
+     * Return *all* material objects contained in the wells as list. The list can contained
+     * different objects representing the same entity in the database, but we need the duplication
+     * to be able to populate an object graph with wells correctly.
+     */
+    private static List<Material> getMaterialsWithDuplicates(List<WellContent> wellLocations)
     {
         List<Material> materials = new ArrayList<Material>();
         for (WellContent wc : wellLocations)
         {
-            materials.add(wc.getMaterialContent());
+            materials.addAll(wc.getMaterialContents());
         }
         return materials;
     }
 
-    private static void sortByMaterialName(List<? extends WellContent> wellLocations)
+    // TODO KE: talk with Tomek : sorting by material code will appear artificial
+    // Material m1 = o1.getMaterialContents();
+    // Material m2 = o2.getMaterialContents();
+    private static void sortByWellCode(List<? extends WellContent> wellLocations)
     {
         Collections.sort(wellLocations, new Comparator<WellContent>()
             {
                 public int compare(WellContent o1, WellContent o2)
                 {
-                    Material m1 = o1.getMaterialContent();
-                    Material m2 = o2.getMaterialContent();
-                    return m1.getCode().compareTo(m2.getCode());
+                    String o1Code = o1.getWell().getCode();
+                    String o2Code = o2.getWell().getCode();
+                    return o1Code.compareTo(o2Code);
                 }
             });
     }
 
-    private static WellContent convert(
-            ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent loc)
+    private List<WellContentQueryResult> removeDuplicateWells(
+            DataIterator<WellContentQueryResult> queryResults)
     {
-        WellLocation location = ScreeningUtils.tryCreateLocationFromMatrixCoordinate(loc.well_code);
-        EntityReference well =
-                new EntityReference(loc.well_id, loc.well_code, loc.well_type_code,
-                        EntityKind.SAMPLE, loc.well_perm_id);
+        Set<String> seenWellPermIds = new HashSet<String>();
+        List<WellContentQueryResult> result = new ArrayList<WellContentQueryResult>();
+
+        for (WellContentQueryResult queryResult : queryResults)
+        {
+            String permId = queryResult.well_perm_id;
+            if (false == seenWellPermIds.contains(permId))
+            {
+                seenWellPermIds.add(permId);
+                result.add(queryResult);
+            }
+        }
+        return result;
+    }
+
+    private static WellContent convert(WellContentQueryResult well)
+    {
+        WellLocation location =
+                ScreeningUtils.tryCreateLocationFromMatrixCoordinate(well.well_code);
+        EntityReference wellReference =
+                new EntityReference(well.well_id, well.well_code,
+                        well.well_type_code, EntityKind.SAMPLE, well.well_perm_id);
         EntityReference plate =
-                new EntityReference(loc.plate_id, loc.plate_code, loc.plate_type_code,
-                        EntityKind.SAMPLE, loc.plate_perm_id);
-        Material materialContent = new Material();
-        materialContent.setCode(loc.material_content_code);
-        materialContent.setId(loc.material_content_id);
-        MaterialType type = new MaterialType();
-        type.setCode(loc.material_content_type_code);
-        materialContent.setMaterialType(type);
-        return new WellContent(location, well, plate, convertExperiment(loc), materialContent);
-    }
-
-    private static ExperimentReference convertExperiment(
-            ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.WellContent loc)
+                new EntityReference(well.plate_id, well.plate_code,
+                        well.plate_type_code, EntityKind.SAMPLE, well.plate_perm_id);
+
+        return new WellContent(location, wellReference, plate, convertExperiment(well));
+    }
+
+    private static ExperimentReference convertExperiment(WellContentQueryResult loc)
     {
         return new ExperimentReference(loc.exp_id, loc.exp_perm_id, loc.exp_code,
                 loc.exp_type_code, loc.proj_code, loc.space_code);
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java
index 17ab75566346976fa6f96ba589a2eb66799a776d..c9fef632223b01f9c0f3dd1117886d82a6ee46f2 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/WellContent.java
@@ -21,6 +21,7 @@ import java.util.Collections;
 import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityReference;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
@@ -42,15 +43,16 @@ public class WellContent implements ISerializable
 
     private EntityReference well;
 
+    /**
+     * well properties also contain the referenced materials (if any) enriched with material
+     * properties.
+     */
     private List<IEntityProperty> wellProperties = new ArrayList<IEntityProperty>(0);
 
     private EntityReference plate;
 
     private ExperimentReference experiment;
 
-    // Material which was being searched for inside a well. Enriched with properties.
-    private Material materialContent;
-
     // ------------ Dataset Data -------------
 
     // dataset which contains images for this well, null if no images have been acquired
@@ -69,13 +71,13 @@ public class WellContent implements ISerializable
     }
 
     public WellContent(WellLocation locationOrNull, EntityReference well, EntityReference plate,
-            ExperimentReference experiment, Material materialContent)
+            ExperimentReference experiment)
     {
-        this(locationOrNull, well, plate, experiment, materialContent, null, null, null, null);
+        this(locationOrNull, well, plate, experiment, null, null, null, null);
     }
 
     private WellContent(WellLocation locationOrNull, EntityReference well, EntityReference plate,
-            ExperimentReference experiment, Material materialContent,
+            ExperimentReference experiment,
             List<IEntityProperty> wellProperties, DatasetImagesReference imagesDatasetOrNull,
             DatasetReference featureVectorDatasetOrNull, NamedFeatureVector featureVectorOrNull)
     {
@@ -83,7 +85,6 @@ public class WellContent implements ISerializable
         this.well = well;
         this.plate = plate;
         this.experiment = experiment;
-        this.materialContent = materialContent;
         this.imagesDatasetOrNull = imagesDatasetOrNull;
         this.featureVectorDatasetOrNull = featureVectorDatasetOrNull;
         this.featureVectorOrNull = featureVectorOrNull;
@@ -105,9 +106,22 @@ public class WellContent implements ISerializable
         return plate;
     }
 
-    public Material getMaterialContent()
+    public List<Material> getMaterialContents()
     {
-        return materialContent;
+        ArrayList<Material> materials = new ArrayList<Material>();
+        for (IEntityProperty property : wellProperties)
+        {
+            DataTypeCode propertyDataTypeCode = property.getPropertyType().getDataType().getCode();
+            if (propertyDataTypeCode == DataTypeCode.MATERIAL)
+            {
+                Material materialOrNull = property.getMaterial();
+                if (materialOrNull != null)
+                {
+                    materials.add(materialOrNull);
+                }
+            }
+        }
+        return materials;
     }
 
     public DatasetImagesReference tryGetImageDataset()
@@ -134,14 +148,14 @@ public class WellContent implements ISerializable
             DatasetReference newFeatureVectorDatasetOrNull)
     {
         return new WellContent(this.locationOrNull, this.well, this.plate, this.experiment,
-                this.materialContent, this.wellProperties, newImagesDatasetOrNull,
+                this.wellProperties, newImagesDatasetOrNull,
                 newFeatureVectorDatasetOrNull, this.featureVectorOrNull);
     }
 
     public WellContent cloneWithFeatureVector(NamedFeatureVector newFeatureVectorOrNull)
     {
         return new WellContent(this.locationOrNull, this.well, this.plate, this.experiment,
-                this.materialContent, this.wellProperties, this.imagesDatasetOrNull,
+                this.wellProperties, this.imagesDatasetOrNull,
                 this.featureVectorDatasetOrNull, newFeatureVectorOrNull);
     }
 
@@ -149,7 +163,7 @@ public class WellContent implements ISerializable
     public String toString()
     {
         return "location = " + locationOrNull + ", experiment = " + experiment + ", plate = "
-                + plate + ", well = " + well + ", content = " + materialContent;
+                + plate + ", well = " + well;
     }
 
     public List<IEntityProperty> getWellProperties()
@@ -167,4 +181,5 @@ public class WellContent implements ISerializable
     {
         this.wellProperties = properties;
     }
+
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/grids/WellSearchGridColumnIds.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/grids/WellSearchGridColumnIds.java
index e0951691c61d2868edec3c42db771ba1d0e158c5..ef9a42e1da913d481b7b07735ec0e4ed5cbdec00 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/grids/WellSearchGridColumnIds.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/basic/dto/grids/WellSearchGridColumnIds.java
@@ -24,8 +24,6 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.grids;
  */
 public class WellSearchGridColumnIds 
 {
-    public static final String WELL_CONTENT_MATERIAL = "WELL_CONTENT_MATERIAL";
-    public static final String WELL_CONTENT_MATERIAL_TYPE = "WELL_CONTENT_MATERIAL_TYPE";
     public static final String EXPERIMENT = "experiment";
     public static final String PLATE = "PLATE";
     public static final String WELL = "WELL";
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java
index 73e14d38b22b233e0191d5941e3769bc407e37d7..b03d89a8166405961e065c25fa5a80d40a2b6a13 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/dataaccess/ScreeningDAOTest.java
@@ -65,7 +65,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateLocationsForOneMaterial()
     {
         // it just tests if the sql runs
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateLocationsForMaterialId(1, 1));
         AssertJUnit.assertEquals(0, locations.size());
     }
@@ -74,7 +74,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateLocationsForOneMaterialAllExperiments()
     {
         // it just tests if the sql runs
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateLocationsForMaterialId(1));
         AssertJUnit.assertEquals(0, locations.size());
     }
@@ -83,7 +83,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateMappingAllTypes()
     {
         // it just tests if the sql runs
-        List<WellContent> locations = EntityListingTestUtils.asList(query.getPlateMapping("xxx"));
+        List<WellContentQueryResult> locations = EntityListingTestUtils.asList(query.getPlateMapping("xxx"));
         AssertJUnit.assertEquals(0, locations.size());
     }
 
@@ -91,7 +91,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateMappingAllTypesAugmentedCode()
     {
         // it just tests if the sql runs
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateMapping("xxx", "yyy"));
         AssertJUnit.assertEquals(0, locations.size());
     }
@@ -117,7 +117,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateMappingGeneType()
     {
         // it just tests if the sql runs
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateMappingForMaterialType("xxx", "Gene"));
         AssertJUnit.assertEquals(0, locations.size());
     }
@@ -126,7 +126,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
     public void testGetPlateMappingGeneTypeAugmentedCode()
     {
         // it just tests if the sql runs
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateMappingForMaterialType("xxx", "yyy",
                         "Gene"));
         AssertJUnit.assertEquals(0, locations.size());
@@ -143,7 +143,7 @@ public class ScreeningDAOTest extends AbstractScreeningDAOTest
             { 1, 2 };
 
         // one experiment
-        List<WellContent> locations =
+        List<WellContentQueryResult> locations =
                 EntityListingTestUtils.asList(query.getPlateLocationsForMaterialCodes(ids,
                         materialTypeCodes, 1));
         AssertJUnit.assertEquals(0, locations.size());
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoaderTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoaderTest.java
index 476971ddc86273091d4a044686a804353cea72c4..5afa9de28219954b76d5dcb05a86bd11a29e126c 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoaderTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/WellContentLoaderTest.java
@@ -28,7 +28,6 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.authentication.Principal;
 import ch.systemsx.cisd.bds.StringUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
@@ -106,12 +105,14 @@ public class WellContentLoaderTest extends AbstractScreeningDAOTest
         assertTrue("At least one property per well is expected", props.size() > 0);
         for (IEntityProperty prop : props)
         {
-            MaterialEntityProperty wellProp = (MaterialEntityProperty) prop;
-            assertNotNull(wellProp.getPropertyType().getCode());
-            assertNotNull(wellProp.getMaterial());
+            assertNotNull(prop.getPropertyType().getCode());
+            assertNotNull(prop.getMaterial());
+            assertTrue("Material properties should be populated", prop.getMaterial()
+                    .getProperties().size() > 0);
             // assert the string representation actually has contents
-            String stringValue = wellProp.tryGetAsString();
+            String stringValue = prop.tryGetAsString();
             assertEquals(false, StringUtils.isBlank(stringValue));
+
         }
     }