From 320159871b8d8e4bdfe2f9822cc6e5ffa7b8e078 Mon Sep 17 00:00:00 2001
From: izabel <izabel>
Date: Mon, 23 Feb 2009 14:57:57 +0000
Subject: [PATCH] [LMS-717] browsing of materials

SVN: 9929
---
 .../web/client/ICommonClientService.java      |  28 ++-
 .../web/client/ICommonClientServiceAsync.java |  20 +-
 .../client/web/client/application/Dict.java   |   9 +-
 .../framework/CategoriesBuilder.java          |   4 +-
 .../framework/ComponentProvider.java          |  18 ++
 .../material/CommonMaterialColDefKind.java    |  93 ++++++++++
 .../material/PropertyMaterialColDef.java      |  50 +++++
 .../ui/material/MaterialBrowserGrid.java      | 175 ++++++++++++++++++
 .../ui/material/MaterialBrowserToolbar.java   |  83 +++++++++
 .../material/MaterialRegistrationPanel.java   |  41 ++++
 .../material/MaterialTypeSelectionWidget.java |  73 ++++++++
 .../web/client/dto/ListMaterialCriteria.java  |  43 +++++
 .../client/web/client/dto/Material.java       |  81 ++++++++
 .../web/server/CommonClientService.java       |  44 ++++-
 .../ListMaterialOriginalDataProvider.java     |  59 ++++++
 .../MaterialPropertyTranslator.java           |  66 +++++++
 .../server/translator/MaterialTranslator.java |  64 +++++++
 .../MaterialTypePropertyTypeTranslator.java   |  17 +-
 .../translator/MaterialTypeTranslator.java    |   9 +
 .../translator/SampleTypeTranslator.java      |   1 -
 .../server/CommonBusinessObjectFactory.java   |   7 +
 .../openbis/generic/server/CommonServer.java  |  31 +++-
 .../generic/server/CommonServerLogger.java    |  19 +-
 .../business/bo/AbstractBusinessObject.java   |   6 +
 .../bo/ICommonBusinessObjectFactory.java      |   9 +-
 .../server/business/bo/IMaterialTable.java    |  45 +++++
 .../server/business/bo/MaterialTable.java     |  85 +++++++++
 .../server/dataaccess/IDAOFactory.java        |  11 +-
 .../server/dataaccess/IMaterialDAO.java       |  37 ++++
 .../server/dataaccess/db/DAOFactory.java      |   9 +
 .../server/dataaccess/db/MaterialDAO.java     |  70 +++++++
 .../openbis/generic/shared/ICommonServer.java |  25 ++-
 .../shared/basic/dto/MaterialProperty.java    |  30 +++
 .../shared/basic/dto/MaterialType.java        |  15 ++
 .../generic/shared/dto/MaterialTypePE.java    |  50 +++++
 .../cisd/openbis/public/common-dictionary.js  |   6 +
 .../cisd/openbis/generic/SystemTestSuite.java |   2 +
 .../application/MaterialBrowserTest.java      |  56 ++++++
 .../generic/server/CommonServerTest.java      |  48 ++++-
 .../server/business/bo/AbstractBOTest.java    |   4 +
 .../server/business/bo/MaterialTableTest.java |  65 +++++++
 .../server/dataaccess/db/MaterialDAOTest.java |  52 ++++++
 .../shared/AbstractServerTestCase.java        |   8 +-
 .../generic/shared/CommonTestUtils.java       |  12 ++
 .../shared/ICommonServer.java.expected        |  25 ++-
 45 files changed, 1674 insertions(+), 31 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/CommonMaterialColDefKind.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/PropertyMaterialColDef.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserGrid.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserToolbar.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Material.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialPropertyTranslator.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTranslator.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTable.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialProperty.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MaterialBrowserTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTableTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAOTest.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index c8d62c52675..6532e7c4ac2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -25,8 +25,10 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RoleAssignment;
@@ -34,15 +36,16 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SearchableEntity;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleSetCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 
 /**
@@ -93,12 +96,14 @@ public interface ICommonClientService extends IClientService
     /**
      * Registers a new role from given role set code and person code
      */
-    public void registerInstanceRole(RoleSetCode roleSetCode, String person) throws UserFailureException;
+    public void registerInstanceRole(RoleSetCode roleSetCode, String person)
+            throws UserFailureException;
 
     /**
      * Deletes the role described by given role set code and person code
      */
-    public void deleteInstanceRole(RoleSetCode roleSetCode, String person) throws UserFailureException;
+    public void deleteInstanceRole(RoleSetCode roleSetCode, String person)
+            throws UserFailureException;
 
     /**
      * Returns a list of sample types.
@@ -124,6 +129,12 @@ public interface ICommonClientService extends IClientService
     public ResultSet<Experiment> listExperiments(final ListExperimentsCriteria criteria)
             throws UserFailureException;
 
+    /**
+     * Returns a list of materials.
+     */
+    public ResultSet<Material> listMaterials(final ListMaterialCriteria criteria)
+            throws UserFailureException;
+
     /**
      * Like {@link #prepareExportSamples(TableExportCriteria)}, but for experiments.
      */
@@ -268,4 +279,15 @@ public interface ICommonClientService extends IClientService
             final IResultSetConfig<String, DataSetSearchHit> resultSetConfig)
             throws UserFailureException;
 
+    /**
+     * Returns a list of all material types.
+     */
+    public List<MaterialType> listMaterialTypes() throws UserFailureException;
+
+    /**
+     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for materials.
+     */
+    public String prepareExportMaterials(final TableExportCriteria<Material> criteria)
+            throws UserFailureException;
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index c3341be99f7..1eeb6ba9f8e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -27,23 +27,26 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RoleAssignment;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SearchableEntity;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleSetCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 
 /**
@@ -227,4 +230,19 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
             final IResultSetConfig<String, DataSetSearchHit> resultSetConfig,
             final AsyncCallback<ResultSet<DataSetSearchHit>> callback);
 
+    /**
+     * @see ICommonClientService#listMaterialTypes()
+     */
+    public void listMaterialTypes(AsyncCallback<List<MaterialType>> callback);
+
+    /**
+     * @see ICommonClientService#listMaterials(ListMaterialCriteria)
+     */
+    public void listMaterials(ListMaterialCriteria criteria,
+            AsyncCallback<ResultSet<Material>> callback);
+
+    /** @see ICommonClientService#prepareExportMaterials(TableExportCriteria) */
+    public void prepareExportMaterials(TableExportCriteria<Material> exportCriteria,
+            AsyncCallback<String> callback);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index cadf18cbd37..ad14e017323 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -283,7 +283,7 @@ public abstract class Dict
     //
 
     public static final String PARENT_CODE = "parent_code";
-    
+
     public static final String LOCATION = "location";
 
     public static final String FILE_FORMAT_TYPE = "file_format_type";
@@ -389,6 +389,13 @@ public abstract class Dict
 
     public static final String BUTTON_CHANGE_QUERY = "button_change_query";
 
+    //
+    // Material Browser
+    //
+    public static final String MATERIAL_TYPE = "material_type";
+
+    public static final String MATERIAL_BROWSER = "material_browser";
+
     //
     // Unclassified
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CategoriesBuilder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CategoriesBuilder.java
index b6bed21c1cf..afbf0457899 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CategoriesBuilder.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/CategoriesBuilder.java
@@ -184,8 +184,8 @@ public class CategoriesBuilder
     private MenuCategory createMaterialCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements
-                .add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getDummyComponent()));
+        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider
+                .getMaterialBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
                 .getDummyComponent()));
         return new MenuCategory(CATEGORIES.MATERIALS, "Materials", elements);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
index b16996231f5..d9ff9b726d3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
@@ -27,6 +27,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.Da
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentBrowserGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentRegistrationPanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialBrowserGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.project.ProjectGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.project.ProjectRegistrationForm;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeAssignmentForm;
@@ -79,6 +80,23 @@ final class ComponentProvider
             };
     }
 
+    public final ITabItemFactory getMaterialBrowser()
+    {
+        return new ITabItemFactory()
+            {
+                public ITabItem create()
+                {
+                    DisposableComponent browser = MaterialBrowserGrid.create(viewContext);
+                    return DefaultTabItem.create(getMessage(Dict.MATERIAL_BROWSER), browser, false);
+                }
+
+                public String getId()
+                {
+                    return MaterialBrowserGrid.BROWSER_ID;
+                }
+            };
+    }
+
     public final ITabItemFactory getDummyComponent()
     {
         return new ITabItemFactory()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/CommonMaterialColDefKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/CommonMaterialColDefKind.java
new file mode 100644
index 00000000000..17047498c14
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/CommonMaterialColDefKind.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application.ui.columns.specific.material;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
+
+/**
+ * Definition of material table columns.
+ * 
+ * @author Izabela Adamczyk
+ */
+public enum CommonMaterialColDefKind implements IColumnDefinitionKind<Material>
+{
+    CODE(new AbstractColumnDefinitionKind<Material>(Dict.CODE)
+        {
+            @Override
+            public String tryGetValue(Material entity)
+            {
+                return entity.getCode();
+            }
+        }),
+
+    MATERIAL_TYPE(new AbstractColumnDefinitionKind<Material>(Dict.MATERIAL_TYPE, true)
+        {
+            @Override
+            public String tryGetValue(Material entity)
+            {
+                return entity.getMaterialType().getCode();
+            }
+        }),
+
+    DATABASE_INSTANCE(new AbstractColumnDefinitionKind<Material>(Dict.DATABASE_INSTANCE, true)
+        {
+            @Override
+            public String tryGetValue(Material entity)
+            {
+                return entity.getDatabaseInstance().getCode();
+            }
+        }),
+
+    REGISTRATOR(new AbstractColumnDefinitionKind<Material>(Dict.REGISTRATOR)
+        {
+            @Override
+            public String tryGetValue(Material entity)
+            {
+                return renderRegistrator(entity);
+            }
+        }),
+
+    REGISTRATION_DATE(
+            new AbstractColumnDefinitionKind<Material>(Dict.REGISTRATION_DATE, 200, false)
+                {
+                    @Override
+                    public String tryGetValue(Material entity)
+                    {
+                        return renderRegistrationDate(entity);
+                    }
+                });
+
+    private final AbstractColumnDefinitionKind<Material> columnDefinitionKind;
+
+    private CommonMaterialColDefKind(AbstractColumnDefinitionKind<Material> columnDefinitionKind)
+    {
+        this.columnDefinitionKind = columnDefinitionKind;
+    }
+
+    public String id()
+    {
+        return name();
+    }
+
+    public AbstractColumnDefinitionKind<Material> getDescriptor()
+    {
+        return columnDefinitionKind;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/PropertyMaterialColDef.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/PropertyMaterialColDef.java
new file mode 100644
index 00000000000..1773bd02300
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/specific/material/PropertyMaterialColDef.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application.ui.columns.specific.material;
+
+import java.util.List;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractPropertyColDef;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+
+/**
+ * @author Izabela Adamczyk
+ */
+public class PropertyMaterialColDef extends AbstractPropertyColDef<Material> implements
+        IsSerializable
+{
+    // GWT only
+    public PropertyMaterialColDef()
+    {
+        super(null, false, 0, false, null, null);
+    }
+
+    public PropertyMaterialColDef(PropertyType propertyType)
+    {
+        super(propertyType, true);
+    }
+
+    @Override
+    protected List<? extends EntityProperty<?, ?>> getProperties(Material entity)
+    {
+        return entity.getProperties();
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserGrid.java
new file mode 100644
index 00000000000..d2982c93f4f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserGrid.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application.ui.material;
+
+import java.util.List;
+
+import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MaterialModel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.specific.material.CommonMaterialColDefKind;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractBrowserGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IColumnDefinition;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+
+/**
+ * A {@link LayoutContainer} which contains the grid where the materials are displayed.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialBrowserGrid extends AbstractBrowserGrid<Material, MaterialModel>
+{
+    private static final String PREFIX = "material-browser";
+
+    public static final String BROWSER_ID = GenericConstants.ID_PREFIX + PREFIX;
+
+    public static final String GRID_ID = BROWSER_ID + "_grid";
+
+    private final MaterialBrowserToolbar topToolbar;
+
+    private ListMaterialCriteria criteria;
+
+    public static DisposableComponent create(
+            final IViewContext<ICommonClientServiceAsync> viewContext)
+    {
+        final MaterialBrowserToolbar toolbar = new MaterialBrowserToolbar(viewContext);
+        final MaterialBrowserGrid browserGrid = new MaterialBrowserGrid(viewContext, toolbar);
+        return browserGrid.asDisposableWithToolbar(toolbar);
+    }
+
+    private MaterialBrowserGrid(final IViewContext<ICommonClientServiceAsync> viewContext,
+            MaterialBrowserToolbar topToolbar)
+    {
+        super(viewContext, GRID_ID);
+        this.topToolbar = topToolbar;
+        extendToolbar();
+        setId(BROWSER_ID);
+    }
+
+    private void extendToolbar()
+    {
+        SelectionChangedListener<?> refreshButtonListener = addRefreshButton(topToolbar);
+        this.topToolbar.setCriteriaChangedListener(refreshButtonListener);
+        this.topToolbar.add(new FillToolItem());
+
+        String showDetailsTitle = viewContext.getMessage(Dict.BUTTON_SHOW_DETAILS);
+        Button showDetailsButton =
+                createSelectedItemButton(showDetailsTitle, asShowEntityInvoker());
+        this.topToolbar.add(new AdapterToolItem(showDetailsButton));
+
+    }
+
+    @Override
+    protected boolean isRefreshEnabled()
+    {
+        return topToolbar.tryGetCriteria() != null;
+    }
+
+    @Override
+    protected void listEntities(DefaultResultSetConfig<String, Material> resultSetConfig,
+            AbstractAsyncCallback<ResultSet<Material>> callback)
+    {
+        copyPagingConfig(resultSetConfig);
+        viewContext.getService().listMaterials(criteria, callback);
+    }
+
+    private void copyPagingConfig(DefaultResultSetConfig<String, Material> resultSetConfig)
+    {
+        criteria.setLimit(resultSetConfig.getLimit());
+        criteria.setOffset(resultSetConfig.getOffset());
+        criteria.setSortInfo(resultSetConfig.getSortInfo());
+        criteria.setFilterInfos(resultSetConfig.getFilterInfos());
+        criteria.setResultSetKey(resultSetConfig.getResultSetKey());
+    }
+
+    @Override
+    protected MaterialModel createModel(Material entity)
+    {
+        return new MaterialModel(entity);
+    }
+
+    @Override
+    protected ColumnDefsAndConfigs<Material> createColumnsDefinition()
+    {
+        return MaterialModel.createColumnsSchema(viewContext, criteria.getMaterialType());
+    }
+
+    @Override
+    protected void prepareExportEntities(TableExportCriteria<Material> exportCriteria,
+            AbstractAsyncCallback<String> callback)
+    {
+        viewContext.getService().prepareExportMaterials(exportCriteria, callback);
+    }
+
+    private static final String createHeader(ListMaterialCriteria criteria)
+    {
+        final StringBuilder builder = new StringBuilder("Materials");
+        builder.append(" of type ");
+        builder.append(criteria.getMaterialType().getCode());
+        return builder.toString();
+    }
+
+    @Override
+    protected final void refresh()
+    {
+        ListMaterialCriteria newCriteria = topToolbar.tryGetCriteria();
+        if (newCriteria == null)
+        {
+            return;
+        }
+        boolean refreshColumnsDefinition =
+                hasColumnsDefinitionChanged(newCriteria.getMaterialType());
+        this.criteria = newCriteria;
+        String newHeader = createHeader(criteria);
+
+        super.refresh(newHeader, refreshColumnsDefinition);
+    }
+
+    private boolean hasColumnsDefinitionChanged(MaterialType entityType)
+    {
+        return criteria == null || entityType.equals(criteria.getMaterialType()) == false;
+    }
+
+    @Override
+    protected List<IColumnDefinition<Material>> getAvailableFilters()
+    {
+        return asColumnFilters(new CommonMaterialColDefKind[]
+            { CommonMaterialColDefKind.CODE });
+    }
+
+    @Override
+    protected final void showEntityViewer(MaterialModel modelData)
+    {
+        // do nothing
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserToolbar.java
new file mode 100644
index 00000000000..b0177dd6708
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBrowserToolbar.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application.ui.material;
+
+import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
+import com.google.gwt.user.client.Element;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+
+/**
+ * The toolbar of material browser.
+ * 
+ * @author Izabela Adamczyk
+ */
+class MaterialBrowserToolbar extends ToolBar
+{
+    public static final String ID = "material-browser-toolbar";
+
+    private final MaterialTypeSelectionWidget selectMaterialTypeCombo;
+
+    private final IViewContext<ICommonClientServiceAsync> viewContext;
+
+    public MaterialBrowserToolbar(final IViewContext<ICommonClientServiceAsync> viewContext)
+    {
+        this.viewContext = viewContext;
+        selectMaterialTypeCombo = new MaterialTypeSelectionWidget(viewContext, ID);
+        display();
+    }
+
+    public void setCriteriaChangedListener(SelectionChangedListener<?> criteriaChangedListener)
+    {
+        selectMaterialTypeCombo.addSelectionChangedListener(criteriaChangedListener);
+    }
+
+    private void display()
+    {
+        setBorders(true);
+        add(new LabelToolItem(viewContext.getMessage(Dict.MATERIAL_TYPE)
+                + GenericConstants.LABEL_SEPARATOR));
+        add(new AdapterToolItem(selectMaterialTypeCombo));
+    }
+
+    public final ListMaterialCriteria tryGetCriteria()
+    {
+        final MaterialType selectedType = selectMaterialTypeCombo.tryGetSelectedMaterialType();
+        if (selectedType == null)
+        {
+            return null;
+        }
+        ListMaterialCriteria criteria = new ListMaterialCriteria();
+        criteria.setMaterialType(selectedType);
+        return criteria;
+    }
+
+    @Override
+    protected final void onRender(final Element parent, final int pos)
+    {
+        super.onRender(parent, pos);
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java
new file mode 100644
index 00000000000..0aff0510697
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialRegistrationPanel.java
@@ -0,0 +1,41 @@
+/*
+* Copyright 2008 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.generic.client.web.client.application.ui.material;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MaterialTypeModel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.EntityRegistrationPanel;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+
+/**
+ * The {@link EntityRegistrationPanel} extension for registering an material.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialRegistrationPanel extends
+        EntityRegistrationPanel<MaterialTypeModel, MaterialTypeSelectionWidget>
+{
+
+    public static final String ID = EntityRegistrationPanel.createId(EntityKind.MATERIAL);
+
+    public MaterialRegistrationPanel(final CommonViewContext viewContext)
+    {
+        super(viewContext, EntityKind.MATERIAL, new MaterialTypeSelectionWidget(viewContext,
+                EntityRegistrationPanel.createId(EntityKind.MATERIAL)));
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java
new file mode 100644
index 00000000000..291d318b480
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialTypeSelectionWidget.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application.ui.material;
+
+import java.util.List;
+
+import com.extjs.gxt.ui.client.widget.form.ComboBox;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.MaterialTypeModel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+
+/**
+ * {@link ComboBox} containing list of material types loaded from the server.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialTypeSelectionWidget extends
+        DropDownList<MaterialTypeModel, MaterialType>
+{
+    public static final String SUFFIX = "material-type";
+
+    private final IViewContext<ICommonClientServiceAsync> viewContext;
+
+    public MaterialTypeSelectionWidget(final IViewContext<ICommonClientServiceAsync> viewContext,
+            final String idSuffix)
+    {
+        super(viewContext, SUFFIX + idSuffix, Dict.EXPERIMENT_TYPE, ModelDataPropertyNames.CODE,
+                "material type", "material types");
+        this.viewContext = viewContext;
+    }
+
+    /**
+     * Returns the {@link MaterialType} currently selected.
+     * 
+     * @return <code>null</code> if nothing is selected yet.
+     */
+    public final MaterialType tryGetSelectedMaterialType()
+    {
+        return super.tryGetSelected();
+    }
+
+    @Override
+    protected List<MaterialTypeModel> convertItems(List<MaterialType> result)
+    {
+        return MaterialTypeModel.convert(result);
+    }
+
+    @Override
+    protected void loadData(AbstractAsyncCallback<List<MaterialType>> callback)
+    {
+        viewContext.getService().listMaterialTypes(callback);
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
new file mode 100644
index 00000000000..9b0986c0d73
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/ListMaterialCriteria.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.dto;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+
+/**
+ * Criteria for listing <i>materials</i>.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class ListMaterialCriteria extends DefaultResultSetConfig<String, Material> implements
+        IsSerializable
+{
+    private MaterialType materialType;
+
+    public MaterialType getMaterialType()
+    {
+        return materialType;
+    }
+
+    public void setMaterialType(MaterialType materialType)
+    {
+        this.materialType = materialType;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Material.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Material.java
new file mode 100644
index 00000000000..4374ba96c2a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/Material.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.dto;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CodeWithRegistration;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * The <i>GWT</i> equivalent to {@link MaterialPE}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class Material extends CodeWithRegistration<Material>
+{
+    private DatabaseInstance databaseInstance;
+
+    private MaterialType MaterialType;
+
+    private Material inhibitorOf;
+
+    private List<MaterialProperty> properties;
+
+    public MaterialType getMaterialType()
+    {
+        return MaterialType;
+    }
+
+    public void setMaterialType(MaterialType experimentType)
+    {
+        this.MaterialType = experimentType;
+    }
+
+    public List<MaterialProperty> getProperties()
+    {
+        return properties;
+    }
+
+    public void setProperties(List<MaterialProperty> properties)
+    {
+        this.properties = properties;
+    }
+
+    public DatabaseInstance getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(DatabaseInstance databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    public Material getInhibitorOf()
+    {
+        return inhibitorOf;
+    }
+
+    public void setInhibitorOf(Material inhibitorOf)
+    {
+        this.inhibitorOf = inhibitorOf;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index 297297e3be0..c649ed4666c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -32,8 +32,10 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.IResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListExperimentsCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.MatchingEntity;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Project;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.RoleAssignment;
@@ -48,6 +50,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.translator.DtoConverte
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExperimentTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExternalDataTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.GroupTranslator;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.MaterialTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.PersonTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ProjectTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.PropertyTypeTranslator;
@@ -61,23 +64,25 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.util.TSVRenderer;
 import ch.systemsx.cisd.openbis.generic.server.SessionConstants;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentTypePropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleSetCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleTypePropertyType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -676,8 +681,8 @@ public final class CommonClientService extends AbstractClientService implements
         {
             final String sessionToken = getSessionToken();
             final List<ExperimentType> result = new ArrayList<ExperimentType>();
-            final List<ExperimentTypePE> projects = commonServer.listExperimentTypes(sessionToken);
-            for (final ExperimentTypePE expType : projects)
+            final List<ExperimentTypePE> experiments = commonServer.listExperimentTypes(sessionToken);
+            for (final ExperimentTypePE expType : experiments)
             {
                 result.add(ExperimentTranslator.translate(expType));
             }
@@ -787,4 +792,37 @@ public final class CommonClientService extends AbstractClientService implements
         return prepareExportEntities(exportCriteria);
     }
 
+    public List<MaterialType> listMaterialTypes()
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        try
+        {
+            final String sessionToken = getSessionToken();
+            final List<MaterialType> result = new ArrayList<MaterialType>();
+            final List<MaterialTypePE> projects = commonServer.listMaterialTypes(sessionToken);
+            for (final MaterialTypePE expType : projects)
+            {
+                result.add(MaterialTypeTranslator.translate(expType));
+            }
+            return result;
+        } catch (final UserFailureException e)
+        {
+            throw UserFailureExceptionTranslator.translate(e);
+        }
+    }
+
+    public ResultSet<Material> listMaterials(ListMaterialCriteria criteria)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        final String sessionToken = getSessionToken();
+        return listEntities(criteria, new ListMaterialOriginalDataProvider(commonServer,
+                sessionToken, criteria));
+    }
+
+    public String prepareExportMaterials(TableExportCriteria<Material> criteria)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        return prepareExportEntities(criteria);
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
new file mode 100644
index 00000000000..34f9c9b49f1
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListMaterialOriginalDataProvider.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 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.generic.client.web.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
+import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.MaterialTranslator;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.MaterialTypeTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * A {@link IOriginalDataProvider} implementation for listing materials.
+ * 
+ * @author Christian Ribeaud
+ */
+final class ListMaterialOriginalDataProvider extends AbstractOriginalDataProvider<Material>
+{
+    private final ListMaterialCriteria listCriteria;
+
+    ListMaterialOriginalDataProvider(final ICommonServer commonServer, final String sessionToken,
+            final ListMaterialCriteria listCriteria)
+    {
+        super(commonServer, sessionToken);
+        this.listCriteria = listCriteria;
+    }
+
+    //
+    // AbstractOriginalDataProvider
+    //
+
+    public final List<Material> getOriginalData()
+    {
+        final List<MaterialPE> materials =
+                commonServer.listMaterials(sessionToken, MaterialTypeTranslator
+                        .translate(listCriteria.getMaterialType()));
+        final List<Material> list = new ArrayList<Material>(materials.size());
+        list.addAll(MaterialTranslator.translate(materials));
+        return list;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialPropertyTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialPropertyTranslator.java
new file mode 100644
index 00000000000..06179bbcce9
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialPropertyTranslator.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2008 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.generic.client.web.server.translator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialProperty;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePropertyTypePE;
+
+/**
+ * A {@link MaterialProperty} &lt;---&gt; {@link ExperimentPropertyPE} translator.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialPropertyTranslator
+{
+    private MaterialPropertyTranslator()
+    {
+        // Can not be instantiated.
+    }
+
+    public final static MaterialProperty translate(final MaterialPropertyPE materialPropertyPE)
+    {
+        final MaterialProperty result = new MaterialProperty();
+        result.setValue(StringEscapeUtils.escapeHtml(materialPropertyPE.tryGetUntypedValue()));
+        result.setEntityTypePropertyType(MaterialTypePropertyTypeTranslator
+                .translate((MaterialTypePropertyTypePE) materialPropertyPE
+                        .getEntityTypePropertyType()));
+        return result;
+
+    }
+
+    public final static List<MaterialProperty> translate(final Set<MaterialPropertyPE> list)
+    {
+        if (list == null)
+        {
+            return null;
+        }
+        final List<MaterialProperty> result = new ArrayList<MaterialProperty>();
+        for (final MaterialPropertyPE materialProperty : list)
+        {
+            result.add(translate(materialProperty));
+        }
+        return result;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTranslator.java
new file mode 100644
index 00000000000..b25a76d158e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTranslator.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2008 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.generic.client.web.server.translator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Material;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * A {@link Material} &lt;---&gt; {@link MaterialPE} translator.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialTranslator
+{
+
+    private MaterialTranslator()
+    {
+        // Can not be instantiated.
+    }
+
+    public final static List<Material> translate(final List<MaterialPE> materials)
+    {
+        final List<Material> result = new ArrayList<Material>();
+        for (final MaterialPE material : materials)
+        {
+            result.add(MaterialTranslator.translate(material, true));
+        }
+        return result;
+    }
+
+    private final static Material translate(final MaterialPE materialPE, final boolean withDetails)
+    {
+        final Material result = new Material();
+        result.setCode(materialPE.getCode());
+        if (withDetails)
+        {
+            result.setMaterialType(MaterialTypeTranslator.translate(materialPE.getMaterialType()));
+            result.setDatabaseInstance(DatabaseInstanceTranslator.translate(materialPE
+                    .getDatabaseInstance()));
+            result.setRegistrator(PersonTranslator.translate(materialPE.getRegistrator()));
+            result.setRegistrationDate(materialPE.getRegistrationDate());
+            result.setProperties(MaterialPropertyTranslator.translate(materialPE.getProperties()));
+        }
+        return result;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypePropertyTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypePropertyTypeTranslator.java
index b37bc2ce79c..bd538f726f3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypePropertyTypeTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypePropertyTypeTranslator.java
@@ -27,8 +27,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePropertyTypePE;
 
 /**
- * Translates {@link MaterialTypePropertyTypePE} to  {@link MaterialTypePropertyType}.
- *
+ * Translates {@link MaterialTypePropertyTypePE} to {@link MaterialTypePropertyType}.
+ * 
  * @author Izabela Adamczyk
  */
 public class MaterialTypePropertyTypeTranslator
@@ -63,4 +63,17 @@ public class MaterialTypePropertyTypeTranslator
                 result);
     }
 
+    public static MaterialTypePropertyType translate(
+            MaterialTypePropertyTypePE entityTypePropertyType)
+    {
+        return new MaterialTypePropertyTypeTranslatorHelper().translate(entityTypePropertyType);
+    }
+
+    public static List<MaterialTypePropertyType> translate(
+            Set<MaterialTypePropertyTypePE> materialTypePropertyTypes, MaterialType result)
+    {
+        return new MaterialTypePropertyTypeTranslatorHelper().translate(materialTypePropertyTypes,
+                result);
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypeTranslator.java
index 880b59e702e..cebce2a3e26 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypeTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/MaterialTypeTranslator.java
@@ -40,6 +40,15 @@ public class MaterialTypeTranslator
         result.setDescription(StringEscapeUtils.escapeHtml(entityTypePE.getDescription()));
         result.setDatabaseInstance(DatabaseInstanceTranslator.translate(entityTypePE
                 .getDatabaseInstance()));
+        result.setMaterialTypePropertyTypes(MaterialTypePropertyTypeTranslator.translate(
+                entityTypePE.getMaterialTypePropertyTypes(), result));
+        return result;
+    }
+
+    public static MaterialTypePE translate(MaterialType type)
+    {
+        final MaterialTypePE result = new MaterialTypePE();
+        result.setCode(type.getCode());
         return result;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/SampleTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/SampleTypeTranslator.java
index 3b702bc009b..17cba52e894 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/SampleTypeTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/SampleTypeTranslator.java
@@ -54,6 +54,5 @@ public class SampleTypeTranslator
         final SampleTypePE result = new SampleTypePE();
         result.setCode(sampleType.getCode());
         return result;
-
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
index af372714f8a..81441f2c662 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java
@@ -30,6 +30,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IGroupBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IProcedureBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IProjectBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeBO;
@@ -38,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IRoleAssignmentTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.MaterialTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ProcedureBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ProjectBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.PropertyTypeBO;
@@ -102,6 +104,11 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac
         return new ExperimentTable(getDaoFactory(), session);
     }
 
+    public IMaterialTable createMaterialTable(final Session session)
+    {
+        return new MaterialTable(getDaoFactory(), session);
+    }
+
     public final IExperimentBO createExperimentBO(final Session session)
     {
         return new ExperimentBO(getDaoFactory(), session);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index f6e023da730..e32c8cde546 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypePropertyTy
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IGroupBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IProjectBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeTable;
@@ -43,8 +44,8 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
@@ -54,6 +55,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ListSampleCriteriaDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewRoleAssignment;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
@@ -93,7 +96,7 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements
         this.authenticationService = authenticationService;
         this.businessObjectFactory = businessObjectFactory;
     }
-    
+
     ICommonBusinessObjectFactory getBusinessObjectFactory()
     {
         return businessObjectFactory;
@@ -475,7 +478,8 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements
 
     }
 
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken, DataSetSearchCriteria criteria)
+    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
+            DataSetSearchCriteria criteria)
     {
         // Not needed but just to refresh/check the session.
         getSessionManager().getSession(sessionToken);
@@ -488,4 +492,25 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements
             throw new UserFailureException(ex.getMostSpecificCause().getMessage(), ex);
         }
     }
+
+    public List<MaterialTypePE> listMaterialTypes(String sessionToken)
+    {
+        // Not needed but just to refresh/check the session.
+        getSessionManager().getSession(sessionToken);
+        final List<MaterialTypePE> types =
+                getDAOFactory().getEntityTypeDAO(EntityKind.MATERIAL).listEntityTypes();
+        Collections.sort(types);
+        return types;
+    }
+
+    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType)
+    {
+        final Session session = getSessionManager().getSession(sessionToken);
+        final IMaterialTable materialTable = businessObjectFactory.createMaterialTable(session);
+        materialTable.load(materialType.getCode());
+        materialTable.enrichWithProperties();
+        final List<MaterialPE> materials = materialTable.getMaterials();
+        Collections.sort(materials);
+        return materials;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index cf86d36c30b..6a7b285217e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -21,9 +21,9 @@ import java.util.List;
 
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
@@ -32,6 +32,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ListSampleCriteriaDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -266,9 +268,22 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
         logTracking(sessionToken, "register_project", "PROJECT(%s)", projectIdentifier);
     }
 
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken, DataSetSearchCriteria criteria)
+    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
+            DataSetSearchCriteria criteria)
     {
         logAccess(sessionToken, "search_for_datasets");
         return null;
     }
+
+    public List<MaterialTypePE> listMaterialTypes(String sessionToken)
+    {
+        logAccess(sessionToken, "list_material_types");
+        return null;
+    }
+
+    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType)
+    {
+        logAccess(sessionToken, "list_materials", "TYPE(%s)", materialType);
+        return null;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
index e662624364a..cadfa38f719 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java
@@ -31,6 +31,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGroupDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ILocatorTypeDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMaterialDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureTypeDAO;
@@ -186,4 +187,9 @@ abstract class AbstractBusinessObject implements IDAOFactory
     {
         return daoFactory.getLocatorTypeDAO();
     }
+
+    public IMaterialDAO getMaterialDAO()
+    {
+        return daoFactory.getMaterialDAO();
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
index 897693f39e4..314382657fd 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java
@@ -41,7 +41,7 @@ public interface ICommonBusinessObjectFactory
      * Creates a {@link IExternalDataBO} <i>Business Object</i>.
      */
     public IExternalDataBO createExternalDataBO(Session session);
-    
+
     /**
      * Creates a {@link IExternalDataTable} <i>Business Object</i>.
      */
@@ -87,5 +87,10 @@ public interface ICommonBusinessObjectFactory
      * Creates a {@link IProjectBO} <i>Business Object</i>.
      */
     public IProjectBO createProjectBO(final Session session);
-    
+
+    /**
+     * Creates a {@link IMaterialTable} <i>Business Object</i>.
+     */
+    public IMaterialTable createMaterialTable(Session session);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java
new file mode 100644
index 00000000000..0c82ef04cb4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IMaterialTable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 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.generic.server.business.bo;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+
+/**
+ * Read-only table for materials. Holds a collection of instances of {@link MaterialPE}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public interface IMaterialTable
+{
+    /**
+     * Loads all materials of given type.
+     * 
+     * @param materialTypeCodeOrNull the material type code or <code>null</code>.
+     */
+    public void load(String materialTypeCodeOrNull);
+
+    /**
+     * Enriches the materials with their property type values.
+     */
+    public void enrichWithProperties();
+
+    /** Returns the loaded {@link MaterialPE}. */
+    public List<MaterialPE> getMaterials();
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTable.java
new file mode 100644
index 00000000000..6497745505b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTable.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2007 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.generic.server.business.bo;
+
+import java.util.List;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
+
+/**
+ * The only productive implementation of {@link IMaterialTable}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialTable extends AbstractBusinessObject implements IMaterialTable
+{
+    private List<MaterialPE> materials;
+
+    public MaterialTable(final IDAOFactory daoFactory, final Session session)
+    {
+        super(daoFactory, session);
+    }
+
+    public final void load(final String materialTypeCode)
+    {
+        checkNotNull(materialTypeCode);
+        final EntityTypePE entityType =
+                getEntityTypeDAO(EntityKind.MATERIAL).tryToFindEntityTypeByCode(materialTypeCode);
+        checkNotNull(materialTypeCode, entityType);
+        materials = getMaterialDAO().listMaterials((MaterialTypePE) entityType);
+    }
+
+    private void checkNotNull(final String materialTypeCode, final EntityTypePE entityType)
+    {
+        if (entityType == null)
+        {
+            throw new UserFailureException("Unknown material type '" + materialTypeCode + "'.");
+        }
+    }
+
+    private void checkNotNull(final String materialTypeCode)
+    {
+        if (materialTypeCode == null)
+        {
+            throw new UserFailureException("Material type not specified.");
+        }
+    }
+
+    public final void enrichWithProperties()
+    {
+        if (materials != null)
+        {
+            for (final MaterialPE material : materials)
+            {
+                HibernateUtils.initialize(material.getProperties());
+            }
+        }
+    }
+
+    public final List<MaterialPE> getMaterials()
+    {
+        assert materials != null : "Materials have not been loaded.";
+        return materials;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
index 0bc83b2aa8c..53d118f54dd 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDAOFactory.java
@@ -88,13 +88,18 @@ public interface IDAOFactory extends IAuthorizationDAOFactory
 
     /** Returns an implementation of {@link IExperimentAttachmentDAO}. */
     public IExperimentAttachmentDAO getExperimentAttachmentDAO();
-    
+
     /** Returns an implementation of {@link IDataSetTypeDAO}. */
     public IDataSetTypeDAO getDataSetTypeDAO();
-    
+
     /** Returns an implementation of {@link IFileFormatTypeDAO}. */
     public IFileFormatTypeDAO getFileFormatTypeDAO();
-    
+
     /** Returns an implementation of {@link ILocatorTypeDAO}. */
     public ILocatorTypeDAO getLocatorTypeDAO();
+
+    /**
+     * Returns the {@link IMaterialDAO} implementation.
+     */
+    public IMaterialDAO getMaterialDAO();
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java
new file mode 100644
index 00000000000..4a41a394c94
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMaterialDAO.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 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.generic.server.dataaccess;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+
+/**
+ * <i>Data Access Object</i> for {@link MaterialPE}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public interface IMaterialDAO
+{
+
+    /**
+     * Lists materials of given type.
+     */
+    public List<MaterialPE> listMaterials(MaterialTypePE type);
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
index 356259b1125..9d33ae95f33 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DAOFactory.java
@@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ILocatorTypeDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMaterialDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
@@ -84,6 +85,8 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
 
     private final LocatorTypeDAO locatorTypeDAO;
 
+    private final IMaterialDAO materialDAO;
+
     public DAOFactory(final DatabaseConfigurationContext context,
             final SessionFactory sessionFactory)
     {
@@ -103,6 +106,7 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
         dataSetTypeDAO = new DataSetTypeDAO(sessionFactory, databaseInstance);
         fileFormatTypeDAO = new FileFormatTypeDAO(sessionFactory, databaseInstance);
         locatorTypeDAO = new LocatorTypeDAO(sessionFactory, databaseInstance);
+        materialDAO = new MaterialDAO(sessionFactory, databaseInstance);
         final EntityKind[] entityKinds = EntityKind.values();
         for (final EntityKind entityKind : entityKinds)
         {
@@ -197,4 +201,9 @@ public final class DAOFactory extends AuthorizationDAOFactory implements IDAOFac
     {
         return locatorTypeDAO;
     }
+
+    public IMaterialDAO getMaterialDAO()
+    {
+        return materialDAO;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
new file mode 100644
index 00000000000..261f403a09e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAO.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 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.generic.server.dataaccess.db;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SessionFactory;
+import org.hibernate.criterion.DetachedCriteria;
+import org.hibernate.criterion.Restrictions;
+import org.springframework.dao.DataAccessException;
+
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMaterialDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+
+/**
+ * Data access object for {@link MaterialPE}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class MaterialDAO extends AbstractDAO implements IMaterialDAO
+{
+
+    private static final Class<MaterialPE> ENTITY_CLASS = MaterialPE.class;
+
+    private static final Logger operationLog =
+            LogFactory.getLogger(LogCategory.OPERATION, MaterialDAO.class);
+
+    protected MaterialDAO(final SessionFactory sessionFactory,
+            final DatabaseInstancePE databaseInstance)
+    {
+        super(sessionFactory, databaseInstance);
+    }
+
+    public List<MaterialPE> listMaterials(final MaterialTypePE materialType)
+            throws DataAccessException
+    {
+        assert materialType != null : "Unspecified material type.";
+
+        final DetachedCriteria criteria = DetachedCriteria.forClass(ENTITY_CLASS);
+        criteria.add(Restrictions.eq("materialType", materialType));
+        final List<MaterialPE> list = cast(getHibernateTemplate().findByCriteria(criteria));
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format(
+                    "%d materials have been found for material type '%s'.", list.size(),
+                    materialType));
+        }
+        return list;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index cb6e01195a3..c388ebac0d8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -29,8 +29,8 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwn
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.GroupValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.MatchingEntityValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
@@ -39,6 +39,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ListSampleCriteriaDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -283,6 +285,25 @@ public interface ICommonServer extends IServer
      */
     @Transactional(readOnly = true)
     @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken, DataSetSearchCriteria criteria);
+    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
+            DataSetSearchCriteria criteria);
+
+    /**
+     * List material types.
+     * 
+     * @return a sorted list of {@link MaterialTypePE}.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleSet.OBSERVER)
+    public List<MaterialTypePE> listMaterialTypes(String sessionToken);
+
+    /**
+     * Lists materials.
+     * 
+     * @return a sorted list of {@link MaterialPE}.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleSet.OBSERVER)
+    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialProperty.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialProperty.java
new file mode 100644
index 00000000000..8f9e6f51ae3
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialProperty.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 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.generic.shared.basic.dto;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * The {@link EntityProperty} extension for <i>Material</i>.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialProperty extends EntityProperty<MaterialType, MaterialTypePropertyType>
+        implements IsSerializable
+{
+    public static final MaterialProperty[] EMPTY_ARRAY = new MaterialProperty[0];
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java
index 1f09486a602..9cd094399ed 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MaterialType.java
@@ -16,6 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.List;
+
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 
 /**
@@ -26,4 +28,17 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 public class MaterialType extends EntityType
 {
 
+    private List<MaterialTypePropertyType> materialTypePropertyTypes;
+
+    public List<MaterialTypePropertyType> getMaterialTypePropertyTypes()
+    {
+        return materialTypePropertyTypes;
+    }
+
+    public void setMaterialTypePropertyTypes(
+            List<MaterialTypePropertyType> materialTypePropertyTypes)
+    {
+        this.materialTypePropertyTypes = materialTypePropertyTypes;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
index a3f387ac580..15afa3b8795 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
@@ -16,12 +16,18 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.dto;
 
+import java.util.Set;
+
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
 import javax.persistence.SequenceGenerator;
 import javax.persistence.Table;
+import javax.persistence.Transient;
 import javax.persistence.UniqueConstraint;
 
 import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
@@ -40,6 +46,8 @@ public final class MaterialTypePE extends EntityTypePE
 {
     private static final long serialVersionUID = GenericSharedConstants.VERSION;
 
+    private Set<MaterialTypePropertyTypePE> materialTypePropertyTypes;
+
     //
     // EntityTypePE
     //
@@ -51,4 +59,46 @@ public final class MaterialTypePE extends EntityTypePE
     {
         return id;
     }
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "entityTypeInternal")
+    @JoinColumn(name = ColumnNames.MATERIAL_TYPE_COLUMN, updatable = false)
+    private Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypesInternal()
+    {
+        return materialTypePropertyTypes;
+    }
+
+    // Required by Hibernate.
+    @SuppressWarnings("unused")
+    private void setMaterialTypePropertyTypesInternal(
+            final Set<MaterialTypePropertyTypePE> materialTypePropertyTypes)
+    {
+        this.materialTypePropertyTypes = materialTypePropertyTypes;
+    }
+
+    @Transient
+    public Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypes()
+    {
+        return getMaterialTypePropertyTypesInternal();
+    }
+
+    public final void setMaterialTypePropertyTypes(
+            final Set<MaterialTypePropertyTypePE> materialTypePropertyTypes)
+    {
+        getMaterialTypePropertyTypesInternal().clear();
+        for (final MaterialTypePropertyTypePE child : materialTypePropertyTypes)
+        {
+            addMaterialTypePropertyType(child);
+        }
+    }
+
+    public void addMaterialTypePropertyType(final MaterialTypePropertyTypePE child)
+    {
+        final MaterialTypePE parent = (MaterialTypePE) child.getEntityType();
+        if (parent != null)
+        {
+            parent.getMaterialTypePropertyTypesInternal().remove(child);
+        }
+        child.setEntityTypeInternal(this);
+        getMaterialTypePropertyTypesInternal().add(child);
+    }
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index fc1bdd765ee..1ab80ce5305 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -215,6 +215,12 @@ var common = {
  production_date: "Production Date",
  data_producer_code: "Producer",
  
+ //
+ // Material Browser
+ //
+ material_type: "Material Type",
+ material_browser: "Material Browser", 
+ 
   // LAST LINE: KEEP IT AT THE END
   lastline: "" // we need a line without a comma
 };
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
index b536c7bdcb9..5a2053f727d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/SystemTestSuite.java
@@ -26,6 +26,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.Authorizat
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.DataSetSearchTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.EntityTypePropertyTypeAssignmentTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ExperimentBrowserTest;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.MaterialBrowserTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ProjectRegistrationTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.PropertyTypeAssignmentBrowserTest;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.PropertyTypeBrowserTest;
@@ -54,6 +55,7 @@ public class SystemTestSuite extends GWTTestSuite
         testSuite.addTestSuite(SearchTest.class);
         testSuite.addTestSuite(GenericSampleRegistrationTest.class);
         testSuite.addTestSuite(ExperimentBrowserTest.class);
+        testSuite.addTestSuite(MaterialBrowserTest.class);
         // TODO 2009-01-21, IA: Uncomment after it's clear how to deal with
         // (NS_ERROR_DOM_SECURITY_ERR): Security error on CC
         // testSuite.addTestSuite(GenericExperimentRegistrationTest.class);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MaterialBrowserTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MaterialBrowserTest.java
new file mode 100644
index 00000000000..e723b54d9a1
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/MaterialBrowserTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 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.generic.client.web.client.application;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.CategoriesBuilder;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.Login;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.OpenTab;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.CheckMaterialTable;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.ListMaterials;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialRow;
+import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
+
+/**
+ * A {@link AbstractGWTTestCase} extension to test material browser.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class MaterialBrowserTest extends AbstractGWTTestCase
+{
+
+    public final void testListMaterials()
+    {
+        loginAndGotoListMaterialsTab();
+
+        remoteConsole.prepare(new ListMaterials("BACTERIUM"));
+        CheckMaterialTable table = new CheckMaterialTable();
+        table.expectedRow(new MaterialRow("BACTERIUM-X").userProperty("ORGANISM", "FLY"));
+        table.expectedRow(new MaterialRow("BACTERIUM-Y"));
+        table.expectedRow(new MaterialRow("BACTERIUM1"));
+        table.expectedRow(new MaterialRow("BACTERIUM2"));
+        remoteConsole.prepare(table.expectedSize(4));
+
+        launchTest(20000);
+    }
+
+    private void loginAndGotoListMaterialsTab()
+    {
+        remoteConsole.prepare(new Login("test", "a"));
+        remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.MATERIALS,
+                CategoriesBuilder.MENU_ELEMENTS.LIST));
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
index c27ac61005c..c1c81bdb357 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
@@ -38,6 +38,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -495,9 +496,9 @@ public final class CommonServerTest extends AbstractServerTestCase
             {
                 {
                     one(daoFactory).getEntityTypeDAO(EntityKind.EXPERIMENT);
-                    will(returnValue(experimentTypeDAO));
+                    will(returnValue(entityTypeDAO));
 
-                    one(experimentTypeDAO).listEntityTypes();
+                    one(entityTypeDAO).listEntityTypes();
                     will(returnValue(types));
                 }
             });
@@ -647,4 +648,47 @@ public final class CommonServerTest extends AbstractServerTestCase
         context.assertIsSatisfied();
     }
 
+    @Test
+    public void testListMaterials()
+    {
+        final Session session = prepareGetSession();
+        final MaterialTypePE materialType = CommonTestUtils.createMaterialType();
+        context.checking(new Expectations()
+            {
+                {
+                    one(commonBusinessObjectFactory).createMaterialTable(session);
+                    will(returnValue(materialTable));
+
+                    one(materialTable).load(materialType.getCode());
+
+                    one(materialTable).enrichWithProperties();
+
+                    one(materialTable).getMaterials();
+                    will(returnValue(new ArrayList<MaterialTypePE>()));
+                }
+            });
+        createServer().listMaterials(session.getSessionToken(), materialType);
+        context.assertIsSatisfied();
+    }
+
+    @Test
+    public void testListMaterialTypes()
+    {
+        final Session session = prepareGetSession();
+        final List<EntityTypePE> types = new ArrayList<EntityTypePE>();
+        types.add(CommonTestUtils.createMaterialType());
+        context.checking(new Expectations()
+            {
+                {
+                    one(daoFactory).getEntityTypeDAO(EntityKind.MATERIAL);
+                    will(returnValue(entityTypeDAO));
+
+                    one(entityTypeDAO).listEntityTypes();
+                    will(returnValue(types));
+                }
+            });
+        assertEquals(types, createServer().listMaterialTypes(session.getSessionToken()));
+        context.assertIsSatisfied();
+    }
+
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
index bcafddfaf09..96de62e8ed3 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
@@ -28,6 +28,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGroupDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMaterialDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProcedureTypeDAO;
@@ -56,6 +57,8 @@ public abstract class AbstractBOTest extends AssertJUnit
 
     IEntityTypeDAO entityTypeDAO;
 
+    IMaterialDAO materialDAO;
+
     IExternalDataDAO externalDataDAO;
 
     IDatabaseInstanceDAO databaseInstanceDAO;
@@ -98,6 +101,7 @@ public abstract class AbstractBOTest extends AssertJUnit
         vocabularyDAO = context.mock(IVocabularyDAO.class);
         procedureDAO = context.mock(IProcedureDAO.class);
         procedureTypeDAO = context.mock(IProcedureTypeDAO.class);
+        materialDAO = context.mock(IMaterialDAO.class);
     }
 
     @AfterMethod
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTableTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTableTest.java
new file mode 100644
index 00000000000..6c02331566f
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/MaterialTableTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 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.generic.server.business.bo;
+
+import java.util.ArrayList;
+
+import org.jmock.Expectations;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool;
+import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * Test cases for corresponding {@link MaterialTable} class.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialTableTest extends AbstractBOTest
+{
+    private final MaterialTable createMaterialTable()
+    {
+        return new MaterialTable(daoFactory, ManagerTestTool.EXAMPLE_SESSION);
+    }
+
+    @Test
+    public void testLoad() throws Exception
+    {
+        final MaterialTypePE materialType = CommonTestUtils.createMaterialType();
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(daoFactory).getEntityTypeDAO(EntityKind.MATERIAL);
+                    will(returnValue(entityTypeDAO));
+
+                    allowing(daoFactory).getMaterialDAO();
+                    will(returnValue(materialDAO));
+
+                    one(entityTypeDAO).tryToFindEntityTypeByCode(materialType.getCode());
+                    will(returnValue(materialType));
+
+                    one(materialDAO).listMaterials(materialType);
+                    will(returnValue(new ArrayList<MaterialPE>()));
+                }
+            });
+        createMaterialTable().load(materialType.getCode());
+        context.assertIsSatisfied();
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAOTest.java
new file mode 100644
index 00000000000..d7bd21c7800
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MaterialDAOTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007 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.generic.server.dataaccess.db;
+
+import java.util.Collections;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * Test cases for corresponding {@link MaterialDAO} class.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Test(groups =
+    { "db", "material" })
+public final class MaterialDAOTest extends AbstractDAOTest
+{
+
+    @Test
+    public void testListMaterials() throws Exception
+    {
+        MaterialTypePE type =
+                (MaterialTypePE) daoFactory.getEntityTypeDAO(EntityKind.MATERIAL)
+                        .tryToFindEntityTypeByCode("BACTERIUM");
+        List<MaterialPE> list = daoFactory.getMaterialDAO().listMaterials(type);
+        Assert.assertEquals(4, list.size());
+        Collections.sort(list);
+        Assert.assertEquals(list.get(0).getCode(), "BACTERIUM-X");
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
index 8aad1de35fe..538cff05117 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
@@ -31,6 +31,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExternalDataTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IGroupBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialTable;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IProcedureBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeTable;
@@ -98,7 +99,9 @@ public abstract class AbstractServerTestCase extends AssertJUnit
 
     protected IExperimentTable experimentTable;
 
-    protected IEntityTypeDAO experimentTypeDAO;
+    protected IMaterialTable materialTable;
+
+    protected IEntityTypeDAO entityTypeDAO;
 
     protected IProjectDAO projectDAO;
 
@@ -136,7 +139,7 @@ public abstract class AbstractServerTestCase extends AssertJUnit
         sampleDAO = context.mock(ISampleDAO.class);
         roleAssignmentDAO = context.mock(IRoleAssignmentDAO.class);
         externalDataDAO = context.mock(IExternalDataDAO.class);
-        experimentTypeDAO = context.mock(IEntityTypeDAO.class);
+        entityTypeDAO = context.mock(IEntityTypeDAO.class);
         projectDAO = context.mock(IProjectDAO.class);
         sampleTypeDAO = context.mock(ISampleTypeDAO.class);
         propertyTypeDAO = context.mock(IPropertyTypeDAO.class);
@@ -153,6 +156,7 @@ public abstract class AbstractServerTestCase extends AssertJUnit
         experimentTable = context.mock(IExperimentTable.class);
         propertyTypeTable = context.mock(IPropertyTypeTable.class);
         procedureBO = context.mock(IProcedureBO.class);
+        materialTable = context.mock(IMaterialTable.class);
 
         homeDatabaseInstance =
                 CommonTestUtils.createDatabaseInstance(CommonTestUtils.HOME_DATABASE_INSTANCE_CODE);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java
index 305bf2016aa..51906d9eed4 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/CommonTestUtils.java
@@ -23,6 +23,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
@@ -137,6 +138,8 @@ public class CommonTestUtils
 
     public static final String USER_ID = "test";
 
+    private static final String MATERIAL_TYPE_VIRUS = "MATERIAL_TYPE_VIRUS";
+
     public static final ExperimentIdentifier createExperimentIdentifier()
     {
         final ExperimentIdentifier identifier =
@@ -169,4 +172,13 @@ public class CommonTestUtils
         return attachmentContentPE;
     }
 
+    public static MaterialTypePE createMaterialType()
+    {
+
+        final MaterialTypePE type = new MaterialTypePE();
+        type.setCode(MATERIAL_TYPE_VIRUS);
+        type.setDatabaseInstance(createDatabaseInstance(HOME_DATABASE_INSTANCE_CODE));
+        return type;
+    }
+
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
index cfc6f6359d2..f476ae11c44 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
@@ -29,8 +29,8 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwn
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.GroupValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.MatchingEntityValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
@@ -39,6 +39,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ListSampleCriteriaDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
@@ -283,6 +285,25 @@ public interface ICommonServer extends IServer
      */
     @Transactional(readOnly = true)
     @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken, DataSetSearchCriteria criteria);
+    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
+            DataSetSearchCriteria criteria);
+
+    /**
+     * Lists material types.
+     * 
+     * @return a sorted list of {@link MaterialTypePE}.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleSet.OBSERVER)
+    public List<MaterialTypePE> listMaterialTypes(String sessionToken);
+
+    /**
+     * Lists materials.
+     * 
+     * @return a sorted list of {@link MaterialPE}.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleSet.OBSERVER)
+    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType);
 
 }
-- 
GitLab