diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java
index 7dbf1bca2d5373c0b52a15f982c6e668fd9a419f..dda9e45d301c4e79694488493873cce7eb77d183 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java
@@ -336,7 +336,7 @@ public class ScriptExecutionFramework
 
     private void updateEvaluationResultField(String result)
     {
-        html.setHTML(result);
+        html.setHTML(result == null ? "(null)" : result);
     }
 
     private static void updateVisibleEntityLink(State state, Field<?> entityLink)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluator.java
index 3e7af59a069cba8c43e4d84c6b28ba0c6d0c0331..26fde02a435c86113eed644d58185232b365bdcf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluator.java
@@ -154,8 +154,7 @@ public class DynamicPropertyEvaluator implements IDynamicPropertyEvaluator
 
     public String evaluateProperty(IEntityAdaptor entityAdaptor, EntityTypePropertyTypePE etpt)
     {
-        // TODO 2010-11-22, Piotr Buczek: will dependency with Vocabulary/Material fail?
-        // are values computed by dependent properties thrown away?
+        // TODO 2010-11-22, Piotr Buczek: are values computed by dependent properties thrown away?
         return evaluateProperty(entityAdaptor, etpt, false);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java
index 1722c880f9dd67c1d313a1a40e060cff85a8788a..935e4e9a00d63a5b9cd092c09ba8297e0c757981 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/PropertyValidator.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.ValidationUtilities.HyperlinkValidationHelper;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE;
@@ -140,6 +141,10 @@ public final class PropertyValidator implements IPropertyValueValidator
                 ((ControlledVocabularyValidator) dataTypeValidator).setVocabulary(propertyType
                         .getVocabulary());
                 break;
+            case MATERIAL:
+                ((MaterialValidator) dataTypeValidator).setMaterialType(propertyType
+                        .getMaterialType());
+                break;
             case XML:
                 ((XmlValidator) dataTypeValidator).setXmlSchema(propertyType.getSchema());
                 ((XmlValidator) dataTypeValidator).setPropertyTypeLabel(propertyType.getLabel());
@@ -336,6 +341,13 @@ public final class PropertyValidator implements IPropertyValueValidator
     private final static class MaterialValidator implements IDataTypeValidator
     {
 
+        private MaterialTypePE materialTypeOrNull;
+
+        public void setMaterialType(MaterialTypePE materialType)
+        {
+            this.materialTypeOrNull = materialType;
+        }
+
         //
         // IDataTypeValidator
         //
@@ -343,15 +355,25 @@ public final class PropertyValidator implements IPropertyValueValidator
         public final String validate(final String value) throws UserFailureException
         {
             assert value != null : "Unspecified value.";
+
             if (StringUtils.isBlank(value))
             {
                 return null;
             }
-            if (MaterialIdentifier.tryParseIdentifier(value) == null)
+            final MaterialIdentifier identifierOrNull =
+                    MaterialIdentifier.tryParseIdentifier(value);
+            if (identifierOrNull == null)
             {
                 throw UserFailureException.fromTemplate(
                         "Material specification '%s' has improper format.", value);
             }
+            if (materialTypeOrNull != null
+                    && identifierOrNull.getTypeCode().equals(materialTypeOrNull.getCode()) == false)
+            {
+                throw UserFailureException.fromTemplate(
+                        "Material '%s' is of wrong type. Expected: '%'.", value,
+                        materialTypeOrNull.getCode());
+            }
             return value;
         }
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/PropertyType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/PropertyType.java
index e2859a45d038d6455156145ab16e93cf5b44451d..3c53a2233729df91c40284724427318ce4951dc3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/PropertyType.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/PropertyType.java
@@ -64,7 +64,7 @@ public class PropertyType extends Code<PropertyType> implements IPropertyTypeUpd
 
     private List<DataSetTypePropertyType> dataSetTypePropertyTypes;
 
-    // xml type specifig
+    // xml type specific
 
     private String schema;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluatorTest.java
index 5218fb7a289e3c415e59f1138fdd199f54f97dc0..badb6018f831f2c23304d5dde92a7f84e608564b 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/DynamicPropertyEvaluatorTest.java
@@ -35,15 +35,20 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calc
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePropertyTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ScriptPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE;
 
 /**
  * @author Piotr Buczek
@@ -139,6 +144,126 @@ public class DynamicPropertyEvaluatorTest extends AssertJUnit
         assertEquals(expectedDp3ErrorValue, dp3Error.getValue());
     }
 
+    @Test
+    public void testEvaluateVocabularyProperties()
+    {
+        // check handling of vocabulary properties
+        Set<SamplePropertyPE> properties = new HashSet<SamplePropertyPE>();
+
+        PropertyTypePE vocabularyPropertyType =
+                createPropertyType("vp", DataTypeCode.CONTROLLEDVOCABULARY);
+        VocabularyPE vocabulary = new VocabularyPE();
+        vocabulary.setCode("v");
+        vocabulary.setChosenFromList(true);
+        VocabularyTermPE term1 = createTerm("t1");
+        VocabularyTermPE term2 = createTerm("t2");
+        VocabularyTermPE term3 = createTerm("t3");
+        vocabulary.addTerm(term1);
+        vocabulary.addTerm(term2);
+        vocabulary.addTerm(term3);
+        vocabularyPropertyType.setVocabulary(vocabulary);
+
+        SamplePropertyPE vp = createSampleVocabularyProperty(vocabularyPropertyType, term2);
+        properties.add(vp);
+
+        // create dynamic properties
+        final ScriptPE script1 = createScript("s1", "entity.propertyValue('vp')");
+        final SamplePropertyPE dpVarchar = createDynamicSampleProperty("dpVarchar", script1);
+        final PropertyTypePE dynamicPropertyType =
+                createPropertyType("dpVocabulary", DataTypeCode.CONTROLLEDVOCABULARY);
+        dynamicPropertyType.setVocabulary(vocabulary);
+        final SamplePropertyPE dpVocabulary =
+                createDynamicSampleProperty(dynamicPropertyType, script1);
+        final ScriptPE script2 = createScript("s2", "'fake_term'");
+        final PropertyTypePE dynamicPropertyTypeError =
+                createPropertyType("dpVocabularyError", DataTypeCode.CONTROLLEDVOCABULARY);
+        dynamicPropertyTypeError.setVocabulary(vocabulary);
+        final SamplePropertyPE dpVocabularyError =
+                createDynamicSampleProperty(dynamicPropertyTypeError, script2);
+        properties.add(dpVarchar);
+        properties.add(dpVocabulary);
+        properties.add(dpVocabularyError);
+
+        // create sample with all properties created above and evaluate dynamic properties
+        final SamplePE sample = createSample("s1", properties);
+        evaluator.evaluateProperties(sample);
+
+        // check if evaluated values are correct
+        assertEquals(term2.getCode(), dpVarchar.getValue());
+        assertEquals(null, dpVarchar.getVocabularyTerm());
+        assertEquals(null, dpVocabulary.getValue());
+        assertEquals(term2, dpVocabulary.getVocabularyTerm());
+        final String expectedDpVocabularyErrorValue =
+                expectedErrorMessage("Vocabulary value 'FAKE_TERM' is not valid. "
+                        + "It must exist in '" + vocabulary.getCode()
+                        + "' controlled vocabulary [T1, T2, T3]");
+        assertEquals(expectedDpVocabularyErrorValue, dpVocabularyError.getValue());
+        assertEquals(null, dpVocabularyError.getVocabularyTerm());
+    }
+
+    @Test(groups = "broken")
+    public void testEvaluateMaterialProperties()
+    {
+        // check handling of material properties
+        Set<SamplePropertyPE> properties = new HashSet<SamplePropertyPE>();
+
+        PropertyTypePE materialPropertyType = createPropertyType("mp", DataTypeCode.MATERIAL);
+        String materialTypeCode = "M_TYPE";
+        MaterialTypePE materialType = new MaterialTypePE();
+        materialType.setCode(materialTypeCode);
+        materialPropertyType.setMaterialType(materialType);
+
+        MaterialPE material = new MaterialPE();
+        material.setCode("M_CODE");
+        material.setMaterialType(materialType);
+
+        SamplePropertyPE mp = createSampleMaterialProperty(materialPropertyType, material);
+        properties.add(mp);
+
+        // create dynamic properties
+        final ScriptPE script1 = createScript("s1", "entity.propertyValue('mp')");
+        final SamplePropertyPE dpVarchar = createDynamicSampleProperty("dpVarchar", script1);
+        final PropertyTypePE dynamicPropertyType =
+                createPropertyType("dpMaterial", DataTypeCode.MATERIAL);
+        dynamicPropertyType.setMaterialType(materialType);
+        final SamplePropertyPE dpMaterial =
+                createDynamicSampleProperty(dynamicPropertyType, script1);
+        final ScriptPE scriptError1 = createScript("se1", "'fake_material'");
+        final PropertyTypePE dynamicPropertyTypeError1 =
+                createPropertyType("dpMaterialError1", DataTypeCode.MATERIAL);
+        dynamicPropertyTypeError1.setMaterialType(materialType);
+        final SamplePropertyPE dpMaterialError1 =
+                createDynamicSampleProperty(dynamicPropertyTypeError1, scriptError1);
+        final ScriptPE scriptError2 = createScript("se2", "'fake_material (fake_type)'");
+        final PropertyTypePE dynamicPropertyTypeError2 =
+                createPropertyType("dpMaterialError2", DataTypeCode.MATERIAL);
+        final SamplePropertyPE dpMaterialError2 =
+                createDynamicSampleProperty(dynamicPropertyTypeError2, scriptError2);
+        properties.add(dpVarchar);
+        properties.add(dpMaterial);
+        properties.add(dpMaterialError1);
+        properties.add(dpMaterialError2);
+
+        // create sample with all properties created above and evaluate dynamic properties
+        final SamplePE sample = createSample("s1", properties);
+        evaluator.evaluateProperties(sample);
+
+        // check if evaluated values are correct
+        final String materialIdentifier =
+                MaterialIdentifier.print(material.getCode(), materialTypeCode);
+        assertEquals(materialIdentifier, dpVarchar.getValue());
+        assertEquals(null, dpVarchar.getMaterialValue());
+        assertEquals(null, dpMaterial.getValue());
+        assertEquals(material, dpMaterial.getMaterialValue());
+        final String expectedDpMaterialError1Value =
+                expectedErrorMessage("Material specification 'fake_material' has improper format.");
+        assertEquals(expectedDpMaterialError1Value, dpMaterialError1.getValue());
+        assertEquals(null, dpMaterialError1.getVocabularyTerm());
+        final String expectedDpMaterialError2Value = expectedErrorMessage("");
+        assertEquals(expectedDpMaterialError2Value, dpMaterialError2.getValue());
+        assertEquals(null, dpMaterialError2.getVocabularyTerm());
+    }
+
     @Test
     public void testEvaluatePropertyDependingOnAnotherDynamicProperty()
     {
@@ -281,6 +406,28 @@ public class DynamicPropertyEvaluatorTest extends AssertJUnit
         return result;
     }
 
+    private static SamplePropertyPE createSampleVocabularyProperty(
+            final PropertyTypePE propertyType, final VocabularyTermPE term)
+    {
+        final SamplePropertyPE result = new SamplePropertyPE();
+        final SampleTypePropertyTypePE entityTypePropertyType = new SampleTypePropertyTypePE();
+        entityTypePropertyType.setPropertyType(propertyType);
+        result.setEntityTypePropertyType(entityTypePropertyType);
+        result.setVocabularyTerm(term);
+        return result;
+    }
+
+    private static SamplePropertyPE createSampleMaterialProperty(final PropertyTypePE propertyType,
+            final MaterialPE material)
+    {
+        final SamplePropertyPE result = new SamplePropertyPE();
+        final SampleTypePropertyTypePE entityTypePropertyType = new SampleTypePropertyTypePE();
+        entityTypePropertyType.setPropertyType(propertyType);
+        result.setEntityTypePropertyType(entityTypePropertyType);
+        result.setMaterialValue(material);
+        return result;
+    }
+
     private static SamplePropertyPE createDynamicSampleProperty(final String propertyTypeCode,
             final ScriptPE script)
     {
@@ -329,4 +476,11 @@ public class DynamicPropertyEvaluatorTest extends AssertJUnit
         return new BasicPropertyAdaptor(propertyTypeCode, value);
     }
 
+    private static VocabularyTermPE createTerm(String termCode)
+    {
+        final VocabularyTermPE result = new VocabularyTermPE();
+        result.setCode(termCode);
+        return result;
+    }
+
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyCalculatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyCalculatorTest.java
index 4ca44bf4fbda552bd7b02fc1897e30a68a3fb8a9..578f08e2e0e6e05c5d08ef5256a9fdea6b0a9581 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyCalculatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyCalculatorTest.java
@@ -23,11 +23,7 @@ import org.testng.AssertJUnit;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.evaluator.EvaluatorException;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calculator.AbstractEntityAdaptor;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calculator.BasicPropertyAdaptor;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calculator.DynamicPropertyCalculator;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calculator.IEntityAdaptor;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calculator.IEntityPropertyAdaptor;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.util.XmlUtilsTest;
 
 /**
@@ -134,6 +130,17 @@ public class DynamicPropertyCalculatorTest extends AssertJUnit
         }
     }
 
+    @Test
+    public void testMaterialFunction()
+    {
+        final String code = "CODE";
+        final String typeCode = "TYPE";
+
+        final DynamicPropertyCalculator calculator =
+                DynamicPropertyCalculator.create("material(" + code + ", " + typeCode + ")");
+        assertEquals(MaterialIdentifier.print(code, typeCode), calculator.evalAsString());
+    }
+
     private static IEntityAdaptor createEntity(final String code,
             final Collection<IEntityPropertyAdaptor> properties)
     {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyFunctionsTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyFunctionsTest.java
index 29629ef698f7bfac75f7548e6e75b26055731587..f60bd0043d1596febad5b59e97f659a6ef0375de 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyFunctionsTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/dynamic_property/calculator/DynamicPropertyFunctionsTest.java
@@ -29,8 +29,8 @@ public class DynamicPropertyFunctionsTest extends AssertJUnit
     @Test
     public void testMaterial()
     {
-        String code = "CODE";
-        String typeCode = "TYPE";
+        final String code = "CODE";
+        final String typeCode = "TYPE";
 
         final String materialIdentifier = DynamicPropertyFunctions.material(code, typeCode);
         assertEquals(MaterialIdentifier.print(code, typeCode), materialIdentifier);