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 65085dd291ae374ba73dcea39c8fb0b32e32e2ab..33d74b73fe753f081d0de58ea536a4ea915ba848 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
@@ -398,6 +398,11 @@ public abstract class Dict
 
     public static final String INHIBITOR_OF = "infibitor_of";
 
+    // 
+    // Material Import
+    //
+    public static final String MATERIAL_IMPORT = "material_import";
+
     //
     // 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 afbf0457899b6150b70afb18708227f0e6eda417..f33241e517b1ab7a437d5c20454a207926e2faec 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
@@ -29,6 +29,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.MenuElemen
  */
 public class CategoriesBuilder
 {
+    private static final String IMPORT_LABEL = "Import";
+
     private static final String LABEL_REGISTER = "Register";
 
     private static final String LABEL_BROWSE = "Browse";
@@ -69,9 +71,9 @@ public class CategoriesBuilder
 
         public static final String REGISTER = "REGISTER";
 
-        public static final String REGISTER_FROM_FILE = "REGISTER_FROM_FILE";
+        public static final String IMPORT = "REGISTER_FROM_FILE";
 
-        public static final String LIST = "LIST";
+        public static final String BROWSE = "LIST";
 
         public static final String MANAGE = "MANAGE";
 
@@ -108,34 +110,34 @@ public class CategoriesBuilder
     private MenuCategory createSampleCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements
-                .add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getSampleBrowser()));
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
+                .getSampleBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
                 .getSampleRegistration()));
-        elements.add(new MenuElement(MENU_ELEMENTS.REGISTER_FROM_FILE, "Register from File",
-                provider.getSampleBatchRegistration()));
+        elements.add(new MenuElement(MENU_ELEMENTS.IMPORT, IMPORT_LABEL, provider
+                .getSampleBatchRegistration()));
         return new MenuCategory(CATEGORIES.SAMPLES, "Samples", elements);
     }
 
     private MenuCategory createRolesCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getRolesView()));
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider.getRolesView()));
         return new MenuCategory(CATEGORIES.ROLES, "Roles", elements);
     }
 
     private MenuCategory createGroupsCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getGroupsView()));
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider.getGroupsView()));
         return new MenuCategory(CATEGORIES.GROUPS, "Groups", elements);
     }
 
     private MenuCategory createProjectsTypesCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements
-                .add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getProjectBrowser()));
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
+                .getProjectBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
                 .getProjectRegistration()));
         return new MenuCategory(CATEGORIES.PROJECTS, "Projects", elements);
@@ -144,14 +146,15 @@ public class CategoriesBuilder
     private MenuCategory createPersonsCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider.getPersonsView()));
+        elements
+                .add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider.getPersonsView()));
         return new MenuCategory(CATEGORIES.PERSONS, "Persons", elements);
     }
 
     private MenuCategory createPropertyTypesCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
                 .getPropertyTypeBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.LIST_ASSIGNMENTS, "Browse Assignments", provider
                 .getPropertyTypeAssignmentBrowser()));
@@ -174,7 +177,7 @@ public class CategoriesBuilder
     private MenuCategory createVocabulariesCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
                 .getVocabularyBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
                 .getVocabularyRegistration()));
@@ -184,17 +187,17 @@ public class CategoriesBuilder
     private MenuCategory createMaterialCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
                 .getMaterialBrowser()));
-        elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
-                .getDummyComponent()));
+        elements.add(new MenuElement(MENU_ELEMENTS.IMPORT, IMPORT_LABEL, provider
+                .getMaterialBatchRegistration()));
         return new MenuCategory(CATEGORIES.MATERIALS, "Materials", elements);
     }
 
     private MenuCategory createExperimentCategory()
     {
         final List<MenuElement> elements = new ArrayList<MenuElement>();
-        elements.add(new MenuElement(MENU_ELEMENTS.LIST, LABEL_BROWSE, provider
+        elements.add(new MenuElement(MENU_ELEMENTS.BROWSE, LABEL_BROWSE, provider
                 .getExperimentBrowser()));
         elements.add(new MenuElement(MENU_ELEMENTS.REGISTER, LABEL_REGISTER, provider
                 .getExperimentRegistration()));
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 d9ff9b726d3ecb251c9ba9bb8ea452fc5d39cd34..4e165ffc774ade9ad4168fc791244af3af449d43 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.MaterialBatchRegistrationPanel;
 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;
@@ -215,6 +216,23 @@ final class ComponentProvider
             };
     }
 
+    public final ITabItemFactory getMaterialBatchRegistration()
+    {
+        return new ITabItemFactory()
+            {
+                public ITabItem create()
+                {
+                    Component component = new MaterialBatchRegistrationPanel(viewContext);
+                    return new DefaultTabItem(getMessage(Dict.MATERIAL_IMPORT), component, true);
+                }
+
+                public String getId()
+                {
+                    return MaterialBatchRegistrationPanel.ID;
+                }
+            };
+    }
+
     public final ITabItemFactory getVocabularyRegistration()
     {
         return new ITabItemFactory()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBatchRegistrationPanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBatchRegistrationPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5d3dfa7ccd8246a281dc52de78464338597b338
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/material/MaterialBatchRegistrationPanel.java
@@ -0,0 +1,87 @@
+/*
+ * 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.Style.Scroll;
+import com.extjs.gxt.ui.client.data.ModelData;
+import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
+import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+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 ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext;
+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.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+
+/**
+ * The {@link LayoutContainer} extension for importing materials.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MaterialBatchRegistrationPanel extends LayoutContainer
+{
+    private static final String ID_SUFFIX = "material-batch-registration";
+
+    public static final String ID = GenericConstants.ID_PREFIX + ID_SUFFIX;
+
+    private final MaterialTypeSelectionWidget materialTypeSelection;
+
+    private final CommonViewContext viewContext;
+
+    public MaterialBatchRegistrationPanel(final CommonViewContext viewContext)
+    {
+        this.viewContext = viewContext;
+        setId(ID);
+        setScrollMode(Scroll.AUTO);
+        materialTypeSelection = new MaterialTypeSelectionWidget(viewContext, ID_SUFFIX);
+        final ToolBar toolBar = createToolBar();
+        add(toolBar);
+        materialTypeSelection.addSelectionChangedListener(new SelectionChangedListener<ModelData>()
+            {
+
+                @Override
+                public final void selectionChanged(final SelectionChangedEvent<ModelData> se)
+                {
+                    final MaterialType materialType =
+                            materialTypeSelection.tryGetSelectedMaterialType();
+                    if (materialType != null)
+                    {
+                        removeAll();
+                        final EntityKind entityKind = EntityKind.MATERIAL;
+                        add(toolBar);
+                        add(viewContext.getClientPluginFactoryProvider().getClientPluginFactory(
+                                entityKind, materialType).createClientPlugin(entityKind)
+                                .createBatchRegistrationForEntityType(materialType));
+                        layout();
+                    }
+                }
+            });
+    }
+
+    private final ToolBar createToolBar()
+    {
+        final ToolBar toolBar = new ToolBar();
+        toolBar.add(new LabelToolItem(viewContext.getMessage(Dict.MATERIAL_TYPE)
+                + GenericConstants.LABEL_SEPARATOR));
+        toolBar.add(new AdapterToolItem(materialTypeSelection));
+        return toolBar;
+    }
+}
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 c649ed4666c97e0141b06d619d388879cea0b936..58c327fc7b0a3e3e4600b67d31a0cd6f302bbbed 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
@@ -681,7 +681,8 @@ public final class CommonClientService extends AbstractClientService implements
         {
             final String sessionToken = getSessionToken();
             final List<ExperimentType> result = new ArrayList<ExperimentType>();
-            final List<ExperimentTypePE> experiments = commonServer.listExperimentTypes(sessionToken);
+            final List<ExperimentTypePE> experiments =
+                    commonServer.listExperimentTypes(sessionToken);
             for (final ExperimentTypePE expType : experiments)
             {
                 result.add(ExperimentTranslator.translate(expType));
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 e652aea807934119e176d90b62aaaa07b4ab518e..271f9cacd4897bdf0f9d22702cb34a07807357c6 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
@@ -508,10 +508,9 @@ public final class CommonServer extends AbstractServer<ICommonServer> implements
         final Session session = getSessionManager().getSession(sessionToken);
         final IMaterialTable materialTable = businessObjectFactory.createMaterialTable(session);
         materialTable.load(materialType.getCode());
-        materialTable.enrichWithProperties();
-        materialTable.enrichWithInhibitors();
         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 6a7b285217ef3b8e188b8914a64e6725d0c96864..df7625a448a5ed6adcee9e4ca6667a6d5ae27e1b 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
@@ -286,4 +286,5 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
         logAccess(sessionToken, "list_materials", "TYPE(%s)", materialType);
         return null;
     }
+
 }
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
index 3fe97503e449cffbfed894477f44f31e2373bc31..437489966c92f341eb463e8b687780ffb5220204 100644
--- 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
@@ -18,7 +18,9 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
 import java.util.List;
 
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 
 /**
  * Read-only table for materials. Holds a collection of instances of {@link MaterialPE}.
@@ -34,17 +36,17 @@ public interface IMaterialTable
      */
     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();
 
     /**
-     * Enriches the materials with inhibitors.
+     * Defines new materials of specified type.
+     */
+    public void add(List<NewMaterial> newMaterials, MaterialTypePE materialTypePE);
+
+    /**
+     * Saves new materials in the database.
      */
-    public void enrichWithInhibitors();
+    public void save();
 
 }
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
index 3c3eac6bc1559ea949c92e882f5a3c7a6f24d1e0..222e3838a189019fb96ec21af185ea3a0fce7098 100644
--- 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
@@ -16,16 +16,21 @@
 
 package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
+import java.util.ArrayList;
 import java.util.List;
 
+import org.springframework.dao.DataAccessException;
+
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 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.MaterialPropertyPE;
 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}.
@@ -36,9 +41,20 @@ public final class MaterialTable extends AbstractBusinessObject implements IMate
 {
     private List<MaterialPE> materials;
 
+    private boolean dataChanged;
+
+    private final IEntityPropertiesConverter entityPropertiesConverter;
+
     public MaterialTable(final IDAOFactory daoFactory, final Session session)
+    {
+        this(daoFactory, session, new EntityPropertiesConverter(EntityKind.MATERIAL, daoFactory));
+    }
+
+    MaterialTable(final IDAOFactory daoFactory, final Session session,
+            final IEntityPropertiesConverter entityPropertiesConverter)
     {
         super(daoFactory, session);
+        this.entityPropertiesConverter = entityPropertiesConverter;
     }
 
     public final void load(final String materialTypeCode)
@@ -47,7 +63,9 @@ public final class MaterialTable extends AbstractBusinessObject implements IMate
         final EntityTypePE entityType =
                 getEntityTypeDAO(EntityKind.MATERIAL).tryToFindEntityTypeByCode(materialTypeCode);
         checkNotNull(materialTypeCode, entityType);
-        materials = getMaterialDAO().listMaterials((MaterialTypePE) entityType);
+        materials =
+                getMaterialDAO().listMaterialsWithPropertiesAndInhibitor(
+                        (MaterialTypePE) entityType);
     }
 
     private void checkNotNull(final String materialTypeCode, final EntityTypePE entityType)
@@ -66,31 +84,62 @@ public final class MaterialTable extends AbstractBusinessObject implements IMate
         }
     }
 
-    public final void enrichWithProperties()
+    public final List<MaterialPE> getMaterials()
+    {
+        assert materials != null : "Materials have not been loaded.";
+        return materials;
+    }
+
+    public void add(List<NewMaterial> newMaterials, MaterialTypePE materialTypePE)
     {
-        if (materials != null)
+        assert newMaterials != null : "New materials undefined.";
+        assert materialTypePE != null : "Material type undefined.";
+        if (materials == null)
         {
-            for (final MaterialPE material : materials)
-            {
-                HibernateUtils.initialize(material.getProperties());
-            }
+            materials = new ArrayList<MaterialPE>();
         }
+        for (NewMaterial newMaterial : newMaterials)
+        {
+            materials.add(createMaterial(newMaterial, materialTypePE));
+        }
+        dataChanged = true;
     }
 
-    public final void enrichWithInhibitors()
+    public void save()
     {
-        if (materials != null)
+        assert materials != null : "Materials have not been loaded.";
+        assert dataChanged == true : "Data not changed";
+        try
         {
-            for (final MaterialPE material : materials)
-            {
-                HibernateUtils.initialize(material.getInhibitorOf());
-            }
+            getMaterialDAO().createMaterials(materials);
+        } catch (final DataAccessException ex)
+        {
+            throwException(ex, String.format("One of materials"));
         }
+        dataChanged = false;
     }
 
-    public final List<MaterialPE> getMaterials()
+    private MaterialPE createMaterial(NewMaterial newMaterial, MaterialTypePE materialTypePE)
     {
-        assert materials != null : "Materials have not been loaded.";
-        return materials;
+        final MaterialPE material = new MaterialPE();
+        material.setCode(newMaterial.getCode());
+        material.setRegistrator(findRegistrator());
+        material.setMaterialType(materialTypePE);
+        material.setDatabaseInstance(getHomeDatabaseInstance());
+        defineMaterialProperties(material, newMaterial.getProperties());
+        return material;
+    }
+
+    private final void defineMaterialProperties(final MaterialPE material,
+            final MaterialProperty[] materialProperties)
+    {
+        final String materialTypeCode = material.getMaterialType().getCode();
+        final List<MaterialPropertyPE> properties =
+                entityPropertiesConverter.convertProperties(materialProperties, materialTypeCode,
+                        material.getRegistrator());
+        for (final MaterialPropertyPE materialProperty : properties)
+        {
+            material.addProperty(materialProperty);
+        }
     }
 }
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
index 4a41a394c941a295b8580502410641f36a0e1621..3b9a39f14dd6221dba43413f7ac957e113113a01 100644
--- 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
@@ -30,8 +30,11 @@ public interface IMaterialDAO
 {
 
     /**
-     * Lists materials of given type.
+     * Lists materials of given type. Fetches also properties and inhibitor.
      */
-    public List<MaterialPE> listMaterials(MaterialTypePE type);
+    public List<MaterialPE> listMaterialsWithPropertiesAndInhibitor(MaterialTypePE type);
+
+    /** Inserts given {@link MaterialPE}s into the database. */
+    public void createMaterials(List<MaterialPE> materials);
 
 }
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
index 261f403a09ec1d85c891d6f9c9e948dd54587536..6cb1aacc35ac1f9d352e2f57197e88bd0c539fe1 100644
--- 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
@@ -19,14 +19,17 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
 import java.util.List;
 
 import org.apache.log4j.Logger;
+import org.hibernate.Criteria;
+import org.hibernate.FetchMode;
 import org.hibernate.SessionFactory;
-import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Restrictions;
 import org.springframework.dao.DataAccessException;
+import org.springframework.orm.hibernate3.HibernateTemplate;
 
 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.CodeConverter;
 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;
@@ -50,14 +53,17 @@ public class MaterialDAO extends AbstractDAO implements IMaterialDAO
         super(sessionFactory, databaseInstance);
     }
 
-    public List<MaterialPE> listMaterials(final MaterialTypePE materialType)
-            throws DataAccessException
+    public List<MaterialPE> listMaterialsWithPropertiesAndInhibitor(
+            final MaterialTypePE materialType) throws DataAccessException
     {
         assert materialType != null : "Unspecified material type.";
 
-        final DetachedCriteria criteria = DetachedCriteria.forClass(ENTITY_CLASS);
+        final Criteria criteria = getSession().createCriteria(ENTITY_CLASS);
         criteria.add(Restrictions.eq("materialType", materialType));
-        final List<MaterialPE> list = cast(getHibernateTemplate().findByCriteria(criteria));
+        criteria.setFetchMode("inhibitorOf", FetchMode.JOIN);
+        criteria.setFetchMode("materialProperties", FetchMode.JOIN);
+        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
+        final List<MaterialPE> list = cast(criteria.list());
         if (operationLog.isDebugEnabled())
         {
             operationLog.debug(String.format(
@@ -67,4 +73,28 @@ public class MaterialDAO extends AbstractDAO implements IMaterialDAO
         return list;
     }
 
+    public void createMaterials(List<MaterialPE> materials)
+    {
+        assert materials != null && materials.size() > 0 : "Unspecified or empty materials.";
+
+        final HibernateTemplate hibernateTemplate = getHibernateTemplate();
+        for (final MaterialPE materialPE : materials)
+        {
+            internalCreateMaterial(materialPE, hibernateTemplate);
+        }
+        hibernateTemplate.flush();
+    }
+
+    private void internalCreateMaterial(MaterialPE material, HibernateTemplate hibernateTemplate)
+    {
+        assert material.getDatabaseInstance().isOriginalSource() : "Registration on a non-home database is not allowed";
+        validatePE(material);
+        material.setCode(CodeConverter.tryToDatabase(material.getCode()));
+        hibernateTemplate.save(material);
+        if (operationLog.isInfoEnabled())
+        {
+            operationLog.info(String.format("ADD: material '%s'.", material));
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Code.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Code.java
index bbb3135fd96a02b0ac1062db8cc90b891cd47c63..2cdb937e8d7b7e48ff984d6dbf5459f198d2f293 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Code.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/Code.java
@@ -21,6 +21,7 @@ import java.util.Comparator;
 
 import com.google.gwt.user.client.rpc.IsSerializable;
 
+import ch.systemsx.cisd.common.annotation.BeanProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.ICodeProvider;
 
 /**
@@ -35,6 +36,7 @@ public class Code<T extends Code<T>> implements IsSerializable, ICodeProvider, C
 
     private String code;
 
+    @BeanProperty(label = "code")
     public final void setCode(final String code)
     {
         this.code = code;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewMaterial.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewMaterial.java
new file mode 100644
index 0000000000000000000000000000000000000000..56a857854b4e35f4b427909d82af927bd59e58c1
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewMaterial.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+/**
+ * A material to register.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class NewMaterial extends Code<NewMaterial>
+{
+
+    private MaterialProperty[] properties = MaterialProperty.EMPTY_ARRAY;
+
+    public NewMaterial()
+    {
+    }
+
+    public NewMaterial(final String code)
+    {
+        setCode(code);
+    }
+
+    public final MaterialProperty[] getProperties()
+    {
+        return properties;
+    }
+
+    public final void setProperties(final MaterialProperty[] properties)
+    {
+        this.properties = properties;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        return getCode();
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java
index 891fa83aebc5a41b04ee2678ec6185045db562ed..b5b0658825b5d2c7a468c164c1aeff8645ab5195 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientService.java
@@ -24,6 +24,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGeneration;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
@@ -67,4 +68,13 @@ public interface IGenericClientService extends IClientService
      */
     public void registerExperiment(final String sessionKey, final NewExperiment experiment)
             throws UserFailureException;
+
+    /**
+     * Registers new materials from files which have been previously uploaded.
+     * <p>
+     * Uploaded files can be found as session attribute under given <var>sessionKey</var>.
+     * </p>
+     */
+    public List<BatchRegistrationResult> registerMaterials(final MaterialType materialType,
+            final String sessionKey) throws UserFailureException;
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java
index fa388bedf6effac7bd8b37caf9f9b76155897c5a..beb1d627dbe0977b29ced431b1d8294716b2ac0e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/IGenericClientServiceAsync.java
@@ -25,6 +25,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.BatchRegistrationR
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SampleGeneration;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
@@ -68,4 +69,10 @@ public interface IGenericClientServiceAsync extends IClientServiceAsync
     public void registerExperiment(final String sessionKey, NewExperiment newExp,
             AsyncCallback<Void> assyncCallback) throws UserFailureException;
 
+    /**
+     * @see IGenericClientService#registerMaterials(MaterialType, String)
+     */
+    public void registerMaterials(MaterialType materialType, String sessionKey,
+            final AsyncCallback<List<BatchRegistrationResult>> asyncCallback);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
index eb44182c4172599d1b7196e9ec0fe31ebe8decba..1219f8fa01afa170526794c84039237874e2013d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/ClientPluginFactory.java
@@ -33,10 +33,12 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
 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.SampleType;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentRegistrationForm;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.experiment.GenericExperimentViewer;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.material.GenericMaterialBatchRegistrationForm;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleBatchRegistrationForm;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleRegistrationForm;
 import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.sample.GenericSampleViewer;
@@ -81,6 +83,10 @@ public final class ClientPluginFactory extends
         {
             return (IClientPlugin<T, I>) new SampleClientPlugin();
         }
+        if (EntityKind.MATERIAL.equals(entityKind))
+        {
+            return (IClientPlugin<T, I>) new MaterialClientPlugin();
+        }
         throw new UnsupportedOperationException("IClientPlugin for entity kind '" + entityKind
                 + "' not implemented yet.");
     }
@@ -132,6 +138,17 @@ public final class ClientPluginFactory extends
         }
     }
 
+    private final class MaterialClientPlugin extends
+            ClientPluginAdapter<MaterialType, IIdentifierHolder>
+    {
+
+        @Override
+        public final Widget createBatchRegistrationForEntityType(final MaterialType materialType)
+        {
+            return new GenericMaterialBatchRegistrationForm(getViewContext(), materialType);
+        }
+    }
+
     private final class ExperimentClientPlugin extends
             ClientPluginAdapter<ExperimentType, IIdentifierHolder>
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d99bb9c085761b268e0f09e6a7d91a0c89b0ab7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/material/GenericMaterialBatchRegistrationForm.java
@@ -0,0 +1,252 @@
+/*
+ * 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.plugin.generic.client.web.client.application.material;
+
+import java.util.List;
+
+import com.extjs.gxt.ui.client.Events;
+import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
+import com.extjs.gxt.ui.client.Style.Scroll;
+import com.extjs.gxt.ui.client.event.ButtonEvent;
+import com.extjs.gxt.ui.client.event.SelectionListener;
+import com.extjs.gxt.ui.client.util.Format;
+import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.form.FieldSet;
+import com.extjs.gxt.ui.client.widget.form.FileUploadField;
+import com.extjs.gxt.ui.client.widget.form.FormPanel;
+import com.extjs.gxt.ui.client.widget.form.HiddenField;
+import com.extjs.gxt.ui.client.widget.form.FormPanel.Encoding;
+import com.extjs.gxt.ui.client.widget.form.FormPanel.Method;
+import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
+import com.extjs.gxt.ui.client.widget.layout.FormLayout;
+import com.google.gwt.user.client.ui.HTML;
+
+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.InfoBoxCallbackListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.ClickableFormPanel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.HelpHtml;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.InfoBox;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.BatchRegistrationResult;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.IGenericClientServiceAsync;
+import ch.systemsx.cisd.openbis.plugin.generic.client.web.client.application.FormPanelListener;
+
+/**
+ * The <i>generic</i> material batch registration panel.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+public final class GenericMaterialBatchRegistrationForm extends LayoutContainer
+{
+    private static final String PREFIX = "material-batch-registration";
+
+    public final static String ID = GenericConstants.ID_PREFIX + PREFIX;
+
+    private static final String SESSION_KEY = PREFIX;
+
+    private static final String FIELD_LABEL_TEMPLATE = "File";
+
+    private static final String FIELD_NAME_TEMPLATE = SESSION_KEY + "_{0}";
+
+    private static final int NUMBER_OF_FIELDS = 1;
+
+    private final IViewContext<IGenericClientServiceAsync> viewContext;
+
+    private FormPanel formPanel;
+
+    private Button submitButton;
+
+    private final InfoBox infoBox;
+
+    private final MaterialType materialType;
+
+    public GenericMaterialBatchRegistrationForm(
+            final IViewContext<IGenericClientServiceAsync> viewContext,
+            final MaterialType materialType)
+    {
+        super(new FlowLayout(5));
+        setScrollMode(Scroll.AUTO);
+        this.viewContext = viewContext;
+        this.materialType = materialType;
+        add(infoBox = createInfoBox());
+        add(createUI());
+        add(createHelp());
+    }
+
+    private final static HTML createHelp()
+    {
+        return new HelpHtml(PREFIX);
+    }
+
+    private final static InfoBox createInfoBox()
+    {
+        final InfoBox infoBox = new InfoBox();
+        return infoBox;
+    }
+
+    private final Component createUI()
+    {
+        submitButton = createButton();
+        formPanel = createFormPanel(submitButton);
+        final FieldSet fieldSet = createFieldSet();
+        for (int i = 0; i < NUMBER_OF_FIELDS; i++)
+        {
+            fieldSet.add(createFileUploadField(i));
+        }
+        formPanel.add(fieldSet);
+        return formPanel;
+    }
+
+    private final static FieldSet createFieldSet()
+    {
+        final FieldSet fieldSet = new FieldSet();
+        fieldSet.setHeading("Upload files");
+        fieldSet.setLayout(createFormLayout());
+        return fieldSet;
+    }
+
+    private final static FormLayout createFormLayout()
+    {
+        final FormLayout formLayout = new FormLayout();
+        formLayout.setLabelWidth(AbstractRegistrationForm.DEFAULT_LABEL_WIDTH);
+        formLayout.setDefaultWidth(AbstractRegistrationForm.DEFAULT_FIELD_WIDTH);
+        return formLayout;
+    }
+
+    private final FormPanel createFormPanel(final Button button)
+    {
+        final ClickableFormPanel panel = new ClickableFormPanel();
+        panel.addClickListener(new AbstractRegistrationForm.InfoBoxResetListener(infoBox));
+        panel.setLayout(new FlowLayout());
+        panel.setWidth(AbstractRegistrationForm.DEFAULT_LABEL_WIDTH
+                + AbstractRegistrationForm.DEFAULT_FIELD_WIDTH + 50);
+        panel.setHeaderVisible(false);
+        panel.setBodyBorder(false);
+        panel.setAction(GenericConstants.createServicePath("upload"));
+        panel.setEncoding(Encoding.MULTIPART);
+        panel.setMethod(Method.POST);
+        panel.setButtonAlign(HorizontalAlignment.RIGHT);
+        final HiddenField<String> sessionKeyField =
+                AbstractRegistrationForm.createHiddenSessionField(SESSION_KEY);
+        panel.add(sessionKeyField);
+        panel.addButton(button);
+        final GenericMaterialBatchRegistrationForm thisForm = this;
+        // Does some action after the form has been successfully submitted. Note that the response
+        // coming from the server could be an error message. Even in case of error on the server
+        // side this listener will be informed.
+        panel.addListener(Events.Submit, new FormPanelListener(infoBox)
+            {
+                @Override
+                protected void onSuccessfullUpload()
+                {
+                    viewContext.getService().registerMaterials(materialType, SESSION_KEY,
+                            new RegisterMaterialsCallback(viewContext));
+                }
+
+                @Override
+                protected void setUploadEnabled()
+                {
+                    thisForm.setUploadEnabled(true);
+                }
+            });
+        return panel;
+    }
+
+    private final Button createButton()
+    {
+        final Button button = new Button(viewContext.getMessage(Dict.BUTTON_SUBMIT));
+        button.addSelectionListener(new SelectionListener<ButtonEvent>()
+            {
+
+                //
+                // SelectionListener
+                //
+
+                @Override
+                public final void componentSelected(final ButtonEvent ce)
+                {
+                    if (formPanel.isValid())
+                    {
+                        setUploadEnabled(false);
+                        formPanel.submit();
+                    }
+                }
+            });
+        return button;
+    }
+
+    private final FileUploadField createFileUploadField(final int counter)
+    {
+        final FileUploadField file = new FileUploadField();
+        file.setAllowBlank(counter > 0);
+        final int number = counter + 1;
+        file.setFieldLabel(Format.substitute(FIELD_LABEL_TEMPLATE, number));
+        file.setName(Format.substitute(FIELD_NAME_TEMPLATE, number));
+        return file;
+    }
+
+    private void setUploadEnabled(final boolean enabled)
+    {
+        submitButton.setEnabled(enabled);
+    }
+
+    //
+    // Helper classes
+    //
+
+    private final class RegisterMaterialsCallback extends
+            AbstractAsyncCallback<List<BatchRegistrationResult>>
+    {
+        RegisterMaterialsCallback(final IViewContext<IGenericClientServiceAsync> viewContext)
+        {
+            super(viewContext, new InfoBoxCallbackListener<List<BatchRegistrationResult>>(infoBox));
+        }
+
+        //
+        // AbstractAsyncCallback
+        //
+
+        @Override
+        protected final void process(final List<BatchRegistrationResult> result)
+        {
+            final StringBuilder builder = new StringBuilder();
+            for (final BatchRegistrationResult batchRegistrationResult : result)
+            {
+                builder.append("<b>" + batchRegistrationResult.getFileName() + "</b>:");
+                builder.append(batchRegistrationResult.getMessage());
+                builder.append("<br />");
+            }
+            infoBox.displayInfo(builder.toString());
+            formPanel.reset();
+            setUploadEnabled(true);
+        }
+
+        @Override
+        protected final void finishOnFailure(final Throwable caught)
+        {
+            setUploadEnabled(true);
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java
index e12e255dcebae3d7bce961fcc500fb4d2434c2cd..1e17930956a0630bdaa7a49787498ec783fe7e7a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientService.java
@@ -43,7 +43,9 @@ 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.UserFailureExceptionTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentContentPE;
@@ -254,4 +256,63 @@ public final class GenericClientService extends AbstractClientService implements
         return attachment;
     }
 
+    public final List<BatchRegistrationResult> registerMaterials(final MaterialType materialType,
+            final String sessionKey)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        HttpSession session = null;
+        UploadedFilesBean uploadedFiles = null;
+        try
+        {
+            final String sessionToken = getSessionToken();
+            session = getHttpSession();
+            assert session.getAttribute(sessionKey) != null
+                    && session.getAttribute(sessionKey) instanceof UploadedFilesBean : String
+                    .format("No UploadedFilesBean object as session attribute '%s' found.",
+                            sessionKey);
+            uploadedFiles = (UploadedFilesBean) session.getAttribute(sessionKey);
+            final BisTabFileLoader<NewMaterial> tabFileLoader =
+                    new BisTabFileLoader<NewMaterial>(
+                            new IParserObjectFactoryFactory<NewMaterial>()
+                                {
+                                    public final IParserObjectFactory<NewMaterial> createFactory(
+                                            final IPropertyMapper propertyMapper)
+                                            throws ParserException
+                                    {
+                                        return new NewMaterialParserObjectFactory(materialType,
+                                                propertyMapper);
+                                    }
+                                });
+            final List<NewMaterial> newMaterials = new ArrayList<NewMaterial>();
+            final List<BatchRegistrationResult> results =
+                    new ArrayList<BatchRegistrationResult>(uploadedFiles.size());
+            for (final IUncheckedMultipartFile multipartFile : uploadedFiles.iterable())
+            {
+                final StringReader stringReader =
+                        new StringReader(new String(multipartFile.getBytes()));
+                final List<NewMaterial> loadedMaterials =
+                        tabFileLoader.load(new DelegatedReader(stringReader, multipartFile
+                                .getOriginalFilename()));
+                newMaterials.addAll(loadedMaterials);
+                results.add(new BatchRegistrationResult(multipartFile.getOriginalFilename(), String
+                        .format("%d material(s) found and registered.", loadedMaterials.size())));
+            }
+            genericServer.registerMaterials(sessionToken, materialType.getCode(), newMaterials);
+            return results;
+        } catch (final UserFailureException e)
+        {
+            throw UserFailureExceptionTranslator.translate(e);
+        } finally
+        {
+            if (uploadedFiles != null)
+            {
+                uploadedFiles.deleteTransferredFiles();
+            }
+            if (session != null)
+            {
+                session.removeAttribute(sessionKey);
+            }
+        }
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/NewMaterialParserObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/NewMaterialParserObjectFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..32ddbd1739fc8a20fb7ff2efeae9ff7aa0a6d99b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/NewMaterialParserObjectFactory.java
@@ -0,0 +1,94 @@
+/*
+ * 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.plugin.generic.client.web.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import ch.systemsx.cisd.common.parser.AbstractParserObjectFactory;
+import ch.systemsx.cisd.common.parser.IPropertyMapper;
+import ch.systemsx.cisd.common.parser.IPropertyModel;
+import ch.systemsx.cisd.common.parser.ParserException;
+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.basic.dto.MaterialTypePropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+
+/**
+ * A {@link AbstractParserObjectFactory} extension for creating {@link NewMaterial}.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+final class NewMaterialParserObjectFactory extends AbstractParserObjectFactory<NewMaterial>
+{
+    private final MaterialType materialType;
+
+    NewMaterialParserObjectFactory(final MaterialType materialType,
+            final IPropertyMapper propertyMapper)
+    {
+        super(NewMaterial.class, propertyMapper);
+        this.materialType = materialType;
+    }
+
+    private final MaterialTypePropertyType createMaterialTypePropertyType(
+            final String propertyTypeCode)
+    {
+        final MaterialTypePropertyType materialTypePropertyType = new MaterialTypePropertyType();
+        final PropertyType propertyType = new PropertyType();
+        propertyType.setCode(propertyTypeCode);
+        materialTypePropertyType.setPropertyType(propertyType);
+        materialTypePropertyType.setEntityType(materialType);
+        return materialTypePropertyType;
+    }
+
+    private final void setProperties(final NewMaterial newMaterial, final String[] lineTokens)
+    {
+        final List<MaterialProperty> properties = new ArrayList<MaterialProperty>();
+        for (final String unmatchedProperty : getUnmatchedProperties())
+        {
+            final IPropertyModel propertyModel = tryGetPropertyModel(unmatchedProperty);
+            final String propertyValue = getPropertyValue(lineTokens, propertyModel);
+            if (StringUtils.isEmpty(propertyValue) == false)
+            {
+                final MaterialProperty property = new MaterialProperty();
+                property
+                        .setEntityTypePropertyType(createMaterialTypePropertyType(unmatchedProperty));
+                property.setValue(propertyValue);
+                properties.add(property);
+            }
+        }
+        newMaterial.setProperties(properties.toArray(MaterialProperty.EMPTY_ARRAY));
+    }
+
+    @Override
+    protected final boolean ignoreUnmatchedProperties()
+    {
+        return true;
+    }
+
+    @Override
+    public final NewMaterial createObject(final String[] lineTokens) throws ParserException
+    {
+        final NewMaterial newMaterial = super.createObject(lineTokens);
+        setProperties(newMaterial, lineTokens);
+        return newMaterial;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericBusinessObjectFactory.java
index 5f892280d834203ada90a80ad649aa916afea93a..9aa9c79218b9ff3f1523eb6f2605ee62d69c0132 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericBusinessObjectFactory.java
@@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.generic.server;
 import org.springframework.stereotype.Component;
 
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
+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.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable;
@@ -59,4 +60,9 @@ public final class GenericBusinessObjectFactory extends AbstractPluginBusinessOb
     {
         return getCommonBusinessObjectFactory().createProcedureBO(session);
     }
+
+    public IMaterialTable createMaterialTable(Session session)
+    {
+        return getCommonBusinessObjectFactory().createMaterialTable(session);
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index 339d5749d7fd9d2a8608b51f5429e3c3993bda05..4421672be7a8169bea4f83ffd9a64b4ce7461a58 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -28,14 +28,17 @@ import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
+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.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProcedurePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleGenerationDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
@@ -44,6 +47,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.dto.types.ProcedureTypeCode;
 import ch.systemsx.cisd.openbis.plugin.AbstractPluginServer;
 import ch.systemsx.cisd.openbis.plugin.ISampleTypeSlaveServerPlugin;
@@ -218,4 +222,38 @@ public final class GenericServer extends AbstractPluginServer<IGenericServer> im
             }
         }
     }
+
+    public void registerMaterials(String sessionToken, String materialTypeCode,
+            List<NewMaterial> newMaterials)
+    {
+        assert sessionToken != null : "Unspecified session token.";
+        assert materialTypeCode != null : "Unspecified material type.";
+        assert newMaterials != null : "Unspecified new materials.";
+
+        final Session session = getSessionManager().getSession(sessionToken);
+        // Does nothing if material list is empty.
+        if (newMaterials.size() == 0)
+        {
+            return;
+        }
+        // Check uniqueness of given list based on material code.
+        final HashSet<NewMaterial> materialSet = new HashSet<NewMaterial>(newMaterials);
+        if (materialSet.size() != newMaterials.size())
+        {
+            newMaterials.removeAll(materialSet);
+            throw UserFailureException.fromTemplate("Following materials '%s' are duplicated.",
+                    CollectionUtils.abbreviate(newMaterials, 20));
+        }
+        final MaterialTypePE materialTypePE =
+                (MaterialTypePE) getDAOFactory().getEntityTypeDAO(EntityKind.MATERIAL)
+                        .tryToFindEntityTypeByCode(materialTypeCode);
+        if (materialTypePE == null)
+        {
+            throw UserFailureException.fromTemplate("Material type with code '%s' does not exist.",
+                    materialTypeCode);
+        }
+        final IMaterialTable materialTable = businessObjectFactory.createMaterialTable(session);
+        materialTable.add(newMaterials, materialTypePE);
+        materialTable.save();
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
index 5c45b3f674c3ae75a045c5eb9a8fdf1ae6f2f726..d7cd41e173cd6d08531ce522c67195bcfb07416a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerLogger.java
@@ -23,6 +23,7 @@ import ch.systemsx.cisd.common.collections.CollectionUtils;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.AbstractServerLogger;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
@@ -96,6 +97,12 @@ final class GenericServerLogger extends AbstractServerLogger implements IGeneric
         logTracking(sessionToken, "register_experiment",
                 "EXPERIMENT_TYPE(%s) EXPERIMENT(%S) ATTACHMENTS(%S)", experiment
                         .getExperimentTypeCode(), experiment.getIdentifier(), attachments.size());
+    }
 
+    public void registerMaterials(String sessionToken, String materialTypeCode,
+            List<NewMaterial> newMaterials)
+    {
+        logAccess(sessionToken, "register_materials", "MATERIAL_TYPE(%s) MATERIALS(%s)",
+                materialTypeCode, CollectionUtils.abbreviate(newMaterials, 20));
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IGenericBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IGenericBusinessObjectFactory.java
index 30df3b36e1a987993c524ea698bbd1fa87635b96..b07f8d961c174734b7bc53d2a5b157d2b4cf925d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IGenericBusinessObjectFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IGenericBusinessObjectFactory.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.plugin.generic.server;
 
 import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
+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.ISampleBO;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable;
@@ -29,7 +30,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
  */
 public interface IGenericBusinessObjectFactory
 {
-
     /**
      * Creates a {@link ISampleBO} <i>Business Object</i>.
      */
@@ -49,4 +49,9 @@ public interface IGenericBusinessObjectFactory
      * Creates a {@link IProcedureBO} <i>Business Object</i>.
      */
     public IProcedureBO createProcedureBO(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/plugin/generic/shared/IGenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java
index 0fa39b1ea3ae66186b80867afa6ac4245cafa1e2..02ca8d9d88793d2f6eed2d11e8aba9adf1cf5a67 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.GroupIden
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
@@ -81,4 +82,13 @@ public interface IGenericServer extends IPluginCommonServer
     public void registerExperiment(String sessionToken,
             @AuthorizationGuard(guardClass = NewExperimentPredicate.class)
             final NewExperiment experiment, List<AttachmentPE> attachments);
+
+    /**
+     * Registers materials in batch.
+     */
+    @Transactional
+    @RolesAllowed(RoleSet.USER)
+    public void registerMaterials(String sessionToken, String materialTypeCode,
+            List<NewMaterial> newMaterials);
+
 }
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 90fb980c43ad8a20cc4825d61af3ab585b36423b..45706e842603643eed24f114679033a195260939 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
@@ -222,6 +222,10 @@ var common = {
  material_browser: "Material Browser", 
  infibitor_of: "Inhibitor of",
  
+ //
+ // Import Materials
+ //
+ material_import: "Import Materials",
   // LAST LINE: KEEP IT AT THE END
   lastline: "" // we need a line without a comma
 };
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/help/material-batch-registration.html b/openbis/source/java/ch/systemsx/cisd/openbis/public/help/material-batch-registration.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a4fd2b3fea54b168f58f6694deba129237a7b58
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/help/material-batch-registration.html
@@ -0,0 +1,5 @@
+File format example:<br /><br />
+<pre>
+code	user.description
+MATERIAL_ABC	Example description.
+</pre>
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
index 303cd65992fd87ad806dd624aad6c746f23cc722..7e05b365e878663311f194a8b0396e28d66495b8 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
@@ -48,7 +48,7 @@ public class AuthorizationManagementConsolTest extends AbstractGWTTestCase
         remoteConsole.prepare(new Login("test", "a"));
         final String groupCode = TEST_GROUP;
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.GROUPS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new CreateGroup(groupCode));
         remoteConsole.prepare(new CheckGroup(groupCode.toUpperCase()));
 
@@ -61,7 +61,7 @@ public class AuthorizationManagementConsolTest extends AbstractGWTTestCase
         // This userId must be one of the ones located on 'etc/passwd' (file based authentication).
         final String userId = USER_ID;
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.PERSONS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new CreatePerson(userId));
         remoteConsole.prepare(new CheckPerson(userId));
 
@@ -72,7 +72,7 @@ public class AuthorizationManagementConsolTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.ROLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new CreateRole(TEST_GROUP.toUpperCase(), USER_ID,
                 RoleSetCode.OBSERVER.toString()));
         remoteConsole.prepare(new CheckRole(TEST_GROUP.toUpperCase(), USER_ID, RoleSetCode.OBSERVER
@@ -90,7 +90,7 @@ public class AuthorizationManagementConsolTest extends AbstractGWTTestCase
         remoteConsole.prepare(new Login("o", "o"));
         final String userId = "u";
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.PERSONS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new CreatePerson(userId));
         FailureExpectation failureExpectation =
                 new FailureExpectation(AddPersonDialog.RegisterPersonCallback.class)
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
index 0516f074d2d6eb912dedfa9ab84168b0928f6165..7eb88b4fe81fbbf6663082212290be3846e6c8e2 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/EntityTypePropertyTypeAssignmentTest.java
@@ -92,7 +92,7 @@ public class EntityTypePropertyTypeAssignmentTest extends AbstractGWTTestCase
         remoteConsole.prepare(new FillPropertyTypeAssignmentForm(false, USER_COMMENT,
                 CONTROL_LAYOUT, NO_COMMENT, SAMPLE));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 PropertyTypeAssignmentForm.AssignPropertyTypeCallback.class));
         remoteConsole.prepare(new ListSamples(CISD, CONTROL_LAYOUT));
         CheckSampleTable table = new CheckSampleTable();
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ExperimentBrowserTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ExperimentBrowserTest.java
index 51ad0a438522a94235e947d7231e7834c25263f1..9206377c046e7127b4bc81a092ef8f2d01ce6696 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ExperimentBrowserTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ExperimentBrowserTest.java
@@ -48,6 +48,6 @@ public class ExperimentBrowserTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.EXPERIMENTS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
     }   
 }
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
index e723b54d9a148fb8d1ccaa120811647e8a2dab71..e3812780ced560fd1f5326144408a46b995fb0e9 100644
--- 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
@@ -51,6 +51,6 @@ public class MaterialBrowserTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.MATERIALS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ProjectRegistrationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ProjectRegistrationTest.java
index a7e23d7459e61ad68769bc2b79a9952e0f274deb..ed6f2a90392e3b2871e874c4c6a2b36de02c6259 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ProjectRegistrationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ProjectRegistrationTest.java
@@ -46,7 +46,7 @@ public class ProjectRegistrationTest extends AbstractGWTTestCase
                 DESCRIPTION_PROJECT_007));
 
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.PROJECTS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 ProjectRegistrationForm.ProjectRegistrationCallback.class));
         final CheckProjectTable table = new CheckProjectTable();
         table.expectedRow(new Row().withCell(ProjectColDefKind.CODE.id(), PROJECT_CODE_HER_MAJESTY)
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeBrowserTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeBrowserTest.java
index 8ba3fc5f10b6363493ca50b929ec8e79cdf5f834..072133135375e363cf8af445488b5bddae394853 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeBrowserTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeBrowserTest.java
@@ -36,7 +36,7 @@ public class PropertyTypeBrowserTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.PROPERTY_TYPES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         CheckPropertyTypeTable table = new CheckPropertyTypeTable();
         table.expectedRow(new Row().withCell(PropertyTypeColDefKind.CODE.id(), "PLATE_GEOMETRY"));
         remoteConsole.prepare(table.expectedSize(14));
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeRegistrationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeRegistrationTest.java
index 9b16fbcd5336d87b6c0f6e5a32c9d3da90fbed54..130b6a87f77dad254ae8a8a5a1cf6e41553e964a 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeRegistrationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/PropertyTypeRegistrationTest.java
@@ -53,7 +53,7 @@ public class PropertyTypeRegistrationTest extends AbstractGWTTestCase
         remoteConsole.prepare(createFillPropertyTypeRegistrationForm());
 
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.PROPERTY_TYPES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 PropertyTypeRegistrationForm.PropertyTypeRegistrationCallback.class));
         final CheckPropertyTypeTable table = new CheckPropertyTypeTable();
         table.expectedRow(new Row().withCell(PropertyTypeColDefKind.CODE.id(),
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SampleBrowserTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SampleBrowserTest.java
index a1fc98086831019f3abae3043b0de8526f729f2e..88f89ee6139f127b5e955f8419173328445eedaf 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SampleBrowserTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/SampleBrowserTest.java
@@ -107,6 +107,6 @@ public class SampleBrowserTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
     }
 }
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 44f924a02d3dce00deaec8c4f4e81e243134c370..c1b6049bb0e41e4f613218eb89a8a56955a5985d 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
@@ -661,9 +661,6 @@ public final class CommonServerTest extends AbstractServerTestCase
 
                     one(materialTable).load(materialType.getCode());
 
-                    one(materialTable).enrichWithProperties();
-                    one(materialTable).enrichWithInhibitors();
-
                     one(materialTable).getMaterials();
                     will(returnValue(new ArrayList<MaterialTypePE>()));
                 }
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
index 6c02331566f5b80b0ec8c5d3cd0657e89e14042d..4f801a2c20244f42f371716d9ade8712769059ed 100644
--- 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
@@ -55,7 +55,7 @@ public final class MaterialTableTest extends AbstractBOTest
                     one(entityTypeDAO).tryToFindEntityTypeByCode(materialType.getCode());
                     will(returnValue(materialType));
 
-                    one(materialDAO).listMaterials(materialType);
+                    one(materialDAO).listMaterialsWithPropertiesAndInhibitor(materialType);
                     will(returnValue(new ArrayList<MaterialPE>()));
                 }
             });
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
index d7bd21c78003bf1166ffda598ee60e1ed29f4d66..3a8f2492d2659db49697831ae3c5c6149ea14995 100644
--- 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
@@ -43,7 +43,7 @@ public final class MaterialDAOTest extends AbstractDAOTest
         MaterialTypePE type =
                 (MaterialTypePE) daoFactory.getEntityTypeDAO(EntityKind.MATERIAL)
                         .tryToFindEntityTypeByCode("BACTERIUM");
-        List<MaterialPE> list = daoFactory.getMaterialDAO().listMaterials(type);
+        List<MaterialPE> list = daoFactory.getMaterialDAO().listMaterialsWithPropertiesAndInhibitor(type);
         Assert.assertEquals(4, list.size());
         Collections.sort(list);
         Assert.assertEquals(list.get(0).getCode(), "BACTERIUM-X");
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentAttachmentDownloadTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentAttachmentDownloadTest.java
index 5ab8925468c80ea668d0f4e0dc8265ba99a53a85..b61c0caf944292e2a1c48d8c3df25828dea86fb3 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentAttachmentDownloadTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentAttachmentDownloadTest.java
@@ -53,7 +53,7 @@ public class GenericExperimentAttachmentDownloadTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.EXPERIMENTS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new ListExperiments(projectName, experimentTypeName));
         remoteConsole.prepare(new ShowExperiment(experimentCode));
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationTest.java
index 3e7d68cf55eaa0361da14ced4a92ed95a42bb50b..76ecd7147a2829114b29b1d589c6deb5e75c9981 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentRegistrationTest.java
@@ -59,7 +59,7 @@ public class GenericExperimentRegistrationTest extends AbstractGWTTestCase
                         new PropertyField(GenericExperimentRegistrationForm.ID
                                 + "user-purchase-date", "2008-12-17")));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.EXPERIMENTS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericExperimentRegistrationForm.RegisterExperimentCallback.class));
         remoteConsole.prepare(new ListExperiments("DEFAULT", experimentTypeCode));
         remoteConsole.prepare(new CheckExperimentTable()
@@ -83,7 +83,7 @@ public class GenericExperimentRegistrationTest extends AbstractGWTTestCase
                         new PropertyField(GenericExperimentRegistrationForm.ID
                                 + "user-purchase-date", "2008-12-18")));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericExperimentRegistrationForm.RegisterExperimentCallback.class));
         remoteConsole.prepare(new ListSamples("CISD", "CELL_PLATE"));
         CheckSampleTable table = new CheckSampleTable();
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewerTest.java
index ff918dc20b8365042214808925efeed913945f47..ce7ed1d20270798d20b06f3a82aea7c602caef24 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/experiment/GenericExperimentViewerTest.java
@@ -205,7 +205,7 @@ public class GenericExperimentViewerTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.EXPERIMENTS,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new ListExperiments(projectName, experimentTypeName));
         remoteConsole.prepare(new ShowExperiment(experimentCode));
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationTest.java
index abcfe0b3a0f8eda6c6df4069cd94c7aa63ae19ae..fc1b5cf4669ec9333814b8c440efc6dd25c49a3e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleRegistrationTest.java
@@ -63,7 +63,7 @@ public class GenericSampleRegistrationTest extends AbstractGWTTestCase
                 .addProperty(new PropertyField(GenericSampleRegistrationForm.ID + "plate-geometry",
                         "1536_WELLS_32X48")));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericSampleRegistrationForm.RegisterSampleCallback.class));
         remoteConsole.prepare(new ListSamples("CISD", sampleTypeCode));
         remoteConsole.prepare(new CheckSampleTable().expectedRow(new SampleRow(GROUP_CL)
@@ -101,7 +101,7 @@ public class GenericSampleRegistrationTest extends AbstractGWTTestCase
         remoteConsole.prepare(new FillSampleRegistrationForm("CISD", sampleCode)
                 .parent("MP1-MIXED"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericSampleRegistrationForm.RegisterSampleCallback.class));
         remoteConsole.prepare(new ListSamples("CISD", sampleTypeCode));
         remoteConsole.prepare(new CheckSampleTable().expectedRow(new SampleRow(sampleCode
@@ -118,7 +118,7 @@ public class GenericSampleRegistrationTest extends AbstractGWTTestCase
         remoteConsole.prepare(new FillSampleRegistrationForm("CISD", sampleCode)
                 .container(containerCode));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericSampleRegistrationForm.RegisterSampleCallback.class));
         remoteConsole.prepare(new ListSamples("CISD", SampleTypeCode.CELL_PLATE.getCode()));
         remoteConsole.prepare(new ShowSample(containerCode));
@@ -146,7 +146,7 @@ public class GenericSampleRegistrationTest extends AbstractGWTTestCase
                 new PropertyField(GenericSampleRegistrationForm.ID + "plate-geometry",
                         "1536_WELLS_32X48")));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST,
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE,
                 GenericSampleRegistrationForm.RegisterSampleCallback.class));
         remoteConsole.prepare(new ListSamples(GroupSelectionWidget.SHARED_GROUP_CODE,
                 sampleTypeCode));
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
index 8768f480d084ef4ef6fc320d73d5fe78d2e42d03..419976ca82efbff4c46028d6a557c65dec445c7d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/client/application/sample/GenericSampleViewerTest.java
@@ -47,7 +47,7 @@ public class GenericSampleViewerTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new ListSamples("CISD", "CONTROL_LAYOUT"));
         remoteConsole.prepare(new ShowSample(CONTROL_LAYOUT_EXAMPLE));
         final CheckSample checkSample = new CheckSample(GROUP_IDENTIFIER, CONTROL_LAYOUT_EXAMPLE);
@@ -72,7 +72,7 @@ public class GenericSampleViewerTest extends AbstractGWTTestCase
     {
         remoteConsole.prepare(new Login("test", "a"));
         remoteConsole.prepare(new OpenTab(CategoriesBuilder.CATEGORIES.SAMPLES,
-                CategoriesBuilder.MENU_ELEMENTS.LIST));
+                CategoriesBuilder.MENU_ELEMENTS.BROWSE));
         remoteConsole.prepare(new ListSamples("CISD", "CELL_PLATE"));
         remoteConsole.prepare(new ShowSample(RendererTestUtil.invalidCode(CELL_PLATE_EXAMPLE)));
         final CheckSample checkSample = new CheckSample(GROUP_IDENTIFIER, CELL_PLATE_EXAMPLE);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected
index 9b152521ec1279c066584a6b1473aa3a2a2bd7d1..4b2695d701e69d68f9b37941ed113c85217bdafd 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/shared/IGenericServer.java.expected
@@ -1,3 +1,19 @@
+/*
+ * 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.plugin.generic.shared;
 
 import java.util.List;
@@ -13,21 +29,33 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.GroupIden
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewExperimentPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NewSamplePredicate;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
 
+/**
+ * Definition of the client-server interface.
+ * 
+ * @author Franz-Josef Elmer
+ */
 public interface IGenericServer extends IPluginCommonServer
 {
 
+    /**
+     * For given {@link ExperimentIdentifier} returns the corresponding {@link ExperimentPE}.
+     */
     @Transactional(readOnly = true)
     @RolesAllowed(RoleSet.OBSERVER)
     public ExperimentPE getExperimentInfo(String sessionToken,
             @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
             ExperimentIdentifier identifier);
 
+    /**
+     * Returns attachment described by given experiment identifier, filename and version.
+     */
     @Transactional
     @RolesAllowed(RoleSet.OBSERVER)
     public AttachmentPE getExperimentFileAttachment(String sessionToken,
@@ -35,15 +63,32 @@ public interface IGenericServer extends IPluginCommonServer
             ExperimentIdentifier experimentIdentifier, String filename, int version)
             throws UserFailureException;
 
+    /**
+     * Registers samples in batch.
+     */
     @Transactional
     @RolesAllowed(RoleSet.USER)
     public void registerSamples(final String sessionToken, SampleType sampleType,
             @AuthorizationGuard(guardClass = NewSamplePredicate.class)
             final List<NewSample> newSamples) throws UserFailureException;
-    
+
+    /**
+     * Registers experiment.
+     * 
+     * @param attachments
+     */
+    @Transactional
+    @RolesAllowed(RoleSet.USER)
+    public void registerExperiment(String sessionToken,
+            @AuthorizationGuard(guardClass = NewExperimentPredicate.class)
+            final NewExperiment experiment, List<AttachmentPE> attachments);
+
+    /**
+     * Registers materials in batch.
+     */
     @Transactional
     @RolesAllowed(RoleSet.USER)
-    public void registerExperiment(String sessionToken, 
-    		@AuthorizationGuard(guardClass = NewExperimentPredicate.class)
-    		final NewExperiment experiment, List<AttachmentPE> attachments);
+    public void registerMaterials(String sessionToken, String materialTypeCode,
+            List<NewMaterial> newMaterials);
+
 }