diff --git a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/dataset/create/UploadedDataSetCreation.java b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/dataset/create/UploadedDataSetCreation.java
index a6c8ac7585725e5dc593a523c1108f9745bd0033..e9833b851857e8b4f63833b46a15748300353699 100644
--- a/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/dataset/create/UploadedDataSetCreation.java
+++ b/api-openbis-java/source/java/ch/ethz/sis/openbis/generic/dssapi/v3/dto/dataset/create/UploadedDataSetCreation.java
@@ -15,10 +15,12 @@
  */
 package ch.ethz.sis.openbis.generic.dssapi.v3.dto.dataset.create;
 
+import java.io.Serializable;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.property.PropertiesDeserializer;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.ObjectToString;
@@ -28,6 +30,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.entitytype.id.IEntityTypeId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.experiment.id.IExperimentId;
 import ch.ethz.sis.openbis.generic.asapi.v3.dto.sample.id.ISampleId;
 import ch.systemsx.cisd.base.annotation.JsonObject;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 
 /**
  * @author pkupczyk
@@ -47,7 +50,8 @@ public class UploadedDataSetCreation implements ICreation
     private ISampleId sampleId;
 
     @JsonProperty
-    private Map<String, String> properties = new HashMap<String, String>();
+    @JsonDeserialize(contentUsing =  PropertiesDeserializer.class)
+    private Map<String, Serializable> properties = new HashMap<String, Serializable>();
 
     @JsonProperty
     private List<? extends IDataSetId> parentIds;
@@ -85,12 +89,12 @@ public class UploadedDataSetCreation implements ICreation
         this.sampleId = sampleId;
     }
 
-    public Map<String, String> getProperties()
+    public Map<String, Serializable> getProperties()
     {
         return properties;
     }
 
-    public void setProperties(Map<String, String> properties)
+    public void setProperties(Map<String, Serializable> properties)
     {
         this.properties = properties;
     }
diff --git a/docs/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.md b/docs/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.md
index a17af2e178e029ac03f0699635c9b17d4c5ca92e..55aec609ba8070c200afd6b6dbb60705f9a6952b 100644
--- a/docs/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.md
+++ b/docs/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.md
@@ -1,9 +1,205 @@
 New Entity Type Registration
 ====
- 
-## Enable Rich Text Editor or Spreadsheet Widgets
 
 
+Entity types, i.e. *Experiment/Collection*, *Object* and *Dataset*
+types, as well as *Property types* and *Controlled Vocabularies*
+constitute the openBIS **masterdata**. They can be created by someone
+with *Instance admin* role in the **new Admin openBIS UI**. 
+
+ 
+
+Note: *Material* types are also part of the openBIS masterdata. However,
+they are no longer supported and will be decommissioned soon. They
+should NOT be used. 
+
+ 
+
+The new Admin openBIS UI can be accessed via a URL of this type:
+**https://openbis-xxx/openbis/webapp/openbis-ng-ui/**
+
+
+where openbis-xxx is the name of the server specified in the openBIS
+configuration file, during the installation by a system admin.
+
+
+## Register a new Object Type
+
+
+1.  Select **Types -&gt; Object Types** from the menu.
+2.  Click **Add** at the bottom of the page.
+ 
+
+![](img/add-object-type-1024x382.png)
+ 
+
+![](img/add-new-object-type-1024x539.png)
+ 
+
+3. Enter a ***Code***. E.g. **INSTRUMENT**. This is the name of the
+Object to create and is unique. Please note that Codes should be in
+capital letters, and they can only contain A-Z, a-z, 0-9 and \_, -, .
+
+4. Provide a description (not mandatory).
+
+5. Entity validation plugin is used when we want to have validation on
+some data entries. This is done via a custom script (see [Entity Validation Scripts](https://unlimited.ethz.ch/display/openBISDoc2010/Entity+validation+scripts))
+
+6. Enter the **Generated Code Prefix**. As a convention, we recommended
+to use the first 3 letters of the *Object* *type* code (e.g. **INS**, in
+this case). This field is used by openBIS to automatically generate
+Object codes: the codes will be for example INS1, INS2, INS3, etc.
+
+7. Leave **Generate Codes** selected if you want to have codes
+automatically generated by openBIS.
+
+8. **Unique Subcodes** is used for contained objects, which are not
+used in the ELN. Ignore this option. 
+
+9. Click **Add Section** at the bottom of the page. Sections are ways
+of grouping together similar properties. Examples of sections used in
+the ELN are *General info*, *Storage info*, *Experimental Details*, etc.
+ 
+
+![](img/add-section-new-object-type-1024x536.png)
+ 
+
+10. Add properties inside the Section, by clicking the **Add Property**
+button at the bottom of the page. To remove a property, use the
+**Remove** button at the bottom of the page. 
+
+![](img/add-propert-new-obejct-type-1024x537.png)
+
+
+11. Click **Save** at the bottom of the page.
+ 
+
+Please note that new *Object types* created in the admin UI, do not
+automatically appear in ELN drop downs, but they have to be manually
+enabled, as described here: [Enable Objects in dropdowns](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.html#enable-objects-in-dropdowns) 
+
+
+## Registration of Properties
+
+When registering new properties, the fields below need to be filled in.
+
+![](img/new-property.png)
+
+
+1.  **Code.** Unique identifier of the property. Codes can only contain
+    A-Z, a-z, 0-9 and \_, -, .
+2.  **Data Type.** See below for data types definitions.
+3.  **Label.** This is the property/column header that the user can see
+    in the ELN.
+4.  **Description**: The description is shown inside a field, to give
+    hints about the field itself. In most cases, label and description
+    can be the same.
+5.  **Dynamic Property Plugin**: Script for calculated properties.
+    See [Dynamic properties](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/properties-handled-by-scripts.html#dynamic-properties)
+6.  **Editable**: Editable in the ELN interface. In some cases, metadata
+    is automatically imported by scripts and this should not be changed
+    by users in the interface.
+7.  **Mandatory**: Field can be set as mandatory.
+ 
+
+### Property Data Types
+ 
+
+![](img/property-types.png)
+
+
+1.  **BOOLEAN**: yes or no
+2.  **CONTROLLEDVOCABULARY**: list of predefined values
+3.  **DATE**. Date field
+4.  **HYPERLINK**: URL
+5.  **INTEGER**: integer number
+6.  **MATERIAL**. Not used in ELN. It will be dismissed.
+7.  **MULTILINE\_VARCHAR**: long text. It is possible to enable a Rich
+    Text Editor for this type of property. This is described
+    here: [Enable Rich Text Editor or Spreadsheet Widgets](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.html#enable-rich-text-editor-or-spreadsheet-widgets)
+8.  **REAL**: decimal number
+9.  **OBJECT**. 1-1 connection to a specific object type.
+10. **TIMESTAMP**: date with timestamp
+11. **VARCHAR**: one-line text
+12. **XML**: to be used by *Managed Properties* (see [openBIS Managed Properties](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/properties-handled-by-scripts.html#managed-properties)or[openBIS Managed Properties](https://wiki-bsse.ethz.ch/display/openBISDoc1906/Managed+Properties)
+    and for *Spreadsheet component*s, as described here:[Enable Rich
+    Text Editor or Spreadsheet Widgets](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/admins-documentation/new-entity-type-registration.html#enable-rich-text-editor-or-spreadsheet-widgets)
+ 
+
+### Considerations on properties registration
+
+
+1.  If you create a property with code “PROJECT”, you should not use the
+    label “Project”. This will give an error if you use XLS Batch
+    registration/update, because openBIS considers this to be an openBIS
+    *Project*.
+2.  You should not assign more than 1 property with same label to the
+    same *Object* type. If two or more properties with the same label
+    are present in the same *Object* type, this will result in an error
+    in the XLS Batch registration/update.
+ 
+
+### Controlled Vocabularies
+
+
+Controlled vocabularies are pre-defined lists of values for a given
+field.
+ 
+
+Existing Vocabularies can be visualised from the Types -&gt;
+Vocabularies Tab. Vocabularies staring with the “**$**” symbol are
+internal: they cannot be deleted and their terms cannot be deleted.
+However, it is possible to add new terms to these vocabularies and these
+can also be deleted.
+
+
+New Vocabularies can be added, by clicking the **Add** button at the
+bottom of the page.
+
+![](img/controlled_vocabularies-1024x480.png)
+
+
+When registering a new vocabulary, a Code for the vocabulary needs to be
+entered. This corresponds to the name of the vocabulary, and it is a
+unique identifier. Codes can only contain A-Z, a-z, 0-9 and \_, -, .
+
+
+![](img/add-terms-to-vocabulary-1024x481.png)
+
+
+To add terms to the list click **Add Term** at the bottom of the page.
+Vocabulary terms always have a code and a label: the code is unique and
+contain only alpha-numeric characters; labels are not necessarily unique
+and allow also special characters. If the label is not defined, codes
+are shown.
+
+After creating the vocabulary and registering the terms, remember to **Save**.
+
+## Register a new Experiment/Collection type
+
+
+The registration of a new **Collection** type is very similar to the
+registration of **Object** types. For Collection Types, you only need to
+provide a Code (which is a unique identifier), Description and add a
+validation plugin if you want to have metadata validation (see [Entity
+Validation Scripts](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/properties-handled-by-scripts.html#entity-validation-scripts)).
+
+
+![](img/Collection-type-1024x481.png)
+
+
+## Register a new Dataset type
+
+
+The registration of a new Dataset types is similar to the registration
+of object types. 
+
+It is possible to disallow deletion for a given dataset type.
+
+![](img/Dataset-type-1024x478.png)
+
+ 
+## Enable Rich Text Editor or Spreadsheet Widgets
 
   
 For certain fields, it is possible to enable the use of a Rich Text
diff --git a/docs/user-documentation/general-admin-users/admins-documentation/user-registration.md b/docs/user-documentation/general-admin-users/admins-documentation/user-registration.md
index 12bda025ef3ebfbe57381e99bc42707fb6f5bde8..12064c991b2fb59723f449c15cee8f633ad946fc 100644
--- a/docs/user-documentation/general-admin-users/admins-documentation/user-registration.md
+++ b/docs/user-documentation/general-admin-users/admins-documentation/user-registration.md
@@ -77,7 +77,7 @@ To register new users from the admin UI:
 8. To assign a role to a user, first the **Level** needs to be selected
 (Instance, Space, Project) .
 
-9.If level is Instance, you can directly select a role (Admin, Observer). If the level is Space or Project, you first need to select the Space or Project and then assign a [Role](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/admins-documentation/user-registration.html#openbis-roles).
+9. If level is Instance, you can directly select a role (Admin, Observer). If the level is Space or Project, you first need to select the Space or Project and then assign a [Role](https://openbis.readthedocs.io/en/latest/user-documentation/general-admin-users/admins-documentation/user-registration.html#openbis-roles).
 
 ![](https://openbis.ch/wp-content/uploads/2020/02/admin-ui-roles-300x293.png)
 
@@ -217,9 +217,6 @@ Can do everything that Space/Project Admin and additionally:
 Please note that this role cannot be assigned via the ELN UI, only via
 admin UI.
 
- 
-
-
 Updated on April 26, 2023
  
 ## User Profile
diff --git a/docs/user-documentation/general-admin-users/properties-handled-by-scripts.md b/docs/user-documentation/general-admin-users/properties-handled-by-scripts.md
index eda47d8a9c577399e77c26ed0e57db1302ec79f8..4ddd48e981455a597f481eb8d18163af80916126 100644
--- a/docs/user-documentation/general-admin-users/properties-handled-by-scripts.md
+++ b/docs/user-documentation/general-admin-users/properties-handled-by-scripts.md
@@ -343,6 +343,8 @@ If the value of a dynamic property has not yet been calculated, it will
 be shown as `(pending evaluation)`.
 
 -   No labels
+
+## Entity validation scripts
  
 ### Introduction
 
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
index 59750244076b8328cc169eea9279eef0acdb1f5f..e652cbb0ce16d312461008751a4bfc5f933e60f6 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
@@ -29,9 +29,11 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Stream;
 
 import javax.servlet.http.HttpServletRequest;
 
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.*;
 import org.apache.commons.collections4.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -145,18 +147,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.experime
 import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetRegistrationCache;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.DynamicPropertyEvaluationOperation;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataSetTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDataSourceManager;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDynamicPropertyEvaluationScheduler;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityPropertyTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMetaprojectDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
 import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
 import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager;
@@ -2632,7 +2622,21 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
             {
                 for (NewProperty property : newData.getDataSetProperties())
                 {
-                    creation.setProperty(property.getPropertyCode(), property.getValue());
+                    if(isPropertyMultiValue(property.getPropertyCode())) {
+                        String value = property.getValue();
+                        if(value != null && value.startsWith("[")) {
+                            value = value.substring(1, value.length()-1);
+                            String[] propertyValues = Stream.of(value.split(","))
+                                    .map(String::trim)
+                                    .toArray(String[]::new);
+                            creation.setProperty(property.getPropertyCode(), propertyValues);
+                        } else {
+                            creation.setProperty(property.getPropertyCode(), property.getValue());
+                        }
+                    } else
+                    {
+                        creation.setProperty(property.getPropertyCode(), property.getValue());
+                    }
                 }
             }
 
@@ -2737,6 +2741,17 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         }
     }
 
+    private boolean isPropertyMultiValue(String propertyTypeCode) {
+        IPropertyTypeDAO propertyTypeDAO = daoFactory.getPropertyTypeDAO();
+        PropertyTypePE propertyTypePE = propertyTypeDAO.tryFindPropertyTypeByCode(propertyTypeCode);
+        if (propertyTypePE == null)
+        {
+            throw new UserFailureException(String.format("Property type '%s' does not exist.",
+                    propertyTypeCode));
+        }
+        return propertyTypePE.isMultiValue();
+    }
+
     private DataSetKind map(ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind dataSetKind)
     {
         if (dataSetKind != null)
diff --git a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
index 36518c41550af78835ea2842d73516513ad9786e..2c8f111115c0431ccb7e6e925ef9cbd360c5cd9c 100644
--- a/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
+++ b/server-application-server/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
@@ -15,6 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.generic.shared.util;
 
+import java.io.Serializable;
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.Date;
@@ -121,20 +122,35 @@ public class SimplePropertyValidator
     // IPropertyValidator
     //
 
-    public final String validatePropertyValue(final DataTypeCode entityDataType, final String value)
+    public final String validatePropertyValue(final DataTypeCode entityDataType, final Serializable value)
             throws UserFailureException
     {
         assert value != null : "Unspecified value.";
 
-        // don't validate error messages and placeholders
-        if (value.startsWith(BasicConstant.ERROR_PROPERTY_PREFIX))
+        if(value.getClass().isArray()) {
+            Serializable[] values = (Serializable[]) value;
+            StringBuilder builder = new StringBuilder("[");
+            for(Serializable val : values) {
+                if(builder.length()>1) {
+                    builder.append(",");
+                }
+                builder.append((String) val);
+            }
+            builder.append("]");
+            return builder.toString();
+        } else
         {
-            return value;
+            String propertyValue = (String) value;
+            // don't validate error messages and placeholders
+            if (propertyValue.startsWith(BasicConstant.ERROR_PROPERTY_PREFIX))
+            {
+                return propertyValue;
+            }
+            final IDataTypeValidator dataTypeValidator = dataTypeValidators.get(entityDataType);
+            assert dataTypeValidator != null : String.format("No IDataTypeValidator implementation "
+                    + "specified for '%s'.", entityDataType);
+            return dataTypeValidator.validate(propertyValue);
         }
-        final IDataTypeValidator dataTypeValidator = dataTypeValidators.get(entityDataType);
-        assert dataTypeValidator != null : String.format("No IDataTypeValidator implementation "
-                + "specified for '%s'.", entityDataType);
-        return dataTypeValidator.validate(value);
     }
 
     //
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java b/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
index 53a63ea12034be8068d490e5732cec068224490c..eb4ce6cb8502c7903446ae8e41f31b1325e2fba6 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java
@@ -15,13 +15,7 @@
  */
 package ch.systemsx.cisd.etlserver.api.v1;
 
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -342,7 +336,7 @@ class PutDataSetExecutor implements IDataSetHandlerRpc
         }
         dataSetInfo.setDataSetKind(DataSetKind.PHYSICAL);
 
-        Map<String, String> primitiveProps = newDataSet.getProperties();
+        Map<String, Serializable> primitiveProps = newDataSet.getProperties();
         if (false == primitiveProps.isEmpty())
         {
             ArrayList<NewProperty> properties = new ArrayList<NewProperty>();
@@ -746,7 +740,7 @@ class PutDataSetExecutor implements IDataSetHandlerRpc
             }
             dataSetInfo.setDataSetKind(DataSetKind.PHYSICAL);
 
-            Map<String, String> primitiveProps = newDataSet.getProperties();
+            Map<String, Serializable> primitiveProps = newDataSet.getProperties();
             if (false == primitiveProps.isEmpty())
             {
                 ArrayList<NewProperty> properties = new ArrayList<NewProperty>();
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandler.java b/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandler.java
index 16a5820fbd3fd33e11bae27c92b1d7f336dd2c6d..e49483b956d4ff4205d9c3ef710d0f4f3ab06612 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandler.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandler.java
@@ -15,13 +15,7 @@
  */
 package ch.systemsx.cisd.etlserver.api.v1;
 
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -249,7 +243,7 @@ class PutDataSetTopLevelDataSetHandler
         }
         dataSetInfo.setDataSetKind(DataSetKind.PHYSICAL);
 
-        Map<String, String> primitiveProps = newDataSet.getProperties();
+        Map<String, Serializable> primitiveProps = newDataSet.getProperties();
         if (false == primitiveProps.isEmpty())
         {
             ArrayList<NewProperty> properties = new ArrayList<NewProperty>();
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandPut.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandPut.java
index a21caef9f3494c257a148cde86b5a197714a5f4b..c48fad0480edf98b6b994c4f434c64ee4216886d 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandPut.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandPut.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.dss.client.api.cli;
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -76,9 +77,9 @@ class CommandPut extends AbstractDssCommand<CommandPut.CommandPutArguments>
             return new File(getFilePath());
         }
 
-        public HashMap<String, String> getProperties()
+        public HashMap<String, Serializable> getProperties()
         {
-            HashMap<String, String> propsMap = new HashMap<String, String>();
+            HashMap<String, Serializable> propsMap = new HashMap<String, Serializable>();
             String propsString = propertiesString;
             if (propsString == null || propsString.length() == 0)
             {
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestExtractMetadata.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestExtractMetadata.java
index e3c5311cbd721d68801744a1c20c7ec6fe24a917..218449b286fb1a08626fec01aaaf7872b7b53cb0 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestExtractMetadata.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestExtractMetadata.java
@@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.dss.client.api.cli;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Map;
@@ -73,7 +74,7 @@ public class CommandTestExtractMetadata extends CommandTestValid
                 }
 
                 // If no script was provided, validate against the server's script
-                Map<String, String> properties;
+                Map<String, Serializable> properties;
                 if (null == arguments.getScriptPathsOrNull())
                 {
                     properties = component.extractMetadata(newDataSet, arguments.getFile());
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
index d8bd995da29d599e9418ef1427bc350ea60c57b7..99bea53c5bf0decf03066c0d06e17f3440f1a99f 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/cli/CommandTestValid.java
@@ -15,10 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.dss.client.api.cli;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -334,10 +331,10 @@ class CommandTestValid extends AbstractDssCommand<CommandTestValid.CommandTestVa
                 }
 
                 @Override
-                public Map<String, String> extractMetadata(NewDataSetDTO newDataset,
+                public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset,
                         File dataSetFile) throws IllegalStateException, EnvironmentFailureException
                 {
-                    return new HashMap<String, String>();
+                    return new HashMap<String, Serializable>();
                 }
 
             };
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
index 83f0552843d8261dd1732eed435805152fb854a1..1381e83551edd8740fdea45cd804ef6d20ba2f3e 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
@@ -33,6 +33,7 @@ import java.awt.event.FocusListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.File;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -673,7 +674,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
         if (newDataSetInfo.getNewDataSetBuilder() != null
                 && newDataSetInfo.getNewDataSetBuilder().getFile() != null)
         {
-            Map<String, String> properties =
+            Map<String, Serializable> properties =
                     clientModel.getOpenBISService().extractMetadata(
                             newDataSetInfo.getNewDataSetBuilder().asNewDataSetDTO(),
                             newDataSetInfo.getNewDataSetBuilder().getFile());
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java
index c436145b628a248edf43e3db1726fe41caba6806..e928dc312c56db9feb1ffd14bdf9dbf9911c10ff 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPropertiesPanel.java
@@ -31,6 +31,7 @@ import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -273,7 +274,7 @@ public class DataSetPropertiesPanel extends JPanel
         add(field, c);
     }
 
-    private String setPropertyValue(PropertyType propertyType, String text)
+    private Serializable setPropertyValue(PropertyType propertyType, String text)
     {
         if (null == newDataSetInfo)
         {
@@ -282,9 +283,9 @@ public class DataSetPropertiesPanel extends JPanel
 
         NewDataSetDTOBuilder builder = newDataSetInfo.getNewDataSetBuilder();
         NewDataSetMetadataDTO metadata = builder.getDataSetMetadata();
-        Map<String, String> props = metadata.getProperties();
-        HashMap<String, String> newProps = new HashMap<String, String>(props);
-        String oldValue;
+        Map<String, Serializable> props = metadata.getProperties();
+        HashMap<String, Serializable> newProps = new HashMap<String, Serializable>(props);
+        Serializable oldValue;
         if (null == text || text.trim().length() < 1)
         {
             oldValue = newProps.remove(propertyType.getCode());
@@ -305,32 +306,65 @@ public class DataSetPropertiesPanel extends JPanel
     {
         NewDataSetDTOBuilder builder = newDataSetInfo.getNewDataSetBuilder();
         NewDataSetMetadataDTO metadata = builder.getDataSetMetadata();
-        Map<String, String> props = metadata.getProperties();
+        Map<String, Serializable> props = metadata.getProperties();
         for (String propertyTypeCode : formFields.keySet())
         {
-            String propertyValue = props.get(propertyTypeCode);
+            Serializable propertyValue = props.get(propertyTypeCode);
             JComponent formField = formFields.get(propertyTypeCode);
             formField.setEnabled(false == metadata.isUnmodifiableProperty(propertyTypeCode));
             if (formField instanceof JTextField)
             {
                 JTextField textField = (JTextField) formField;
-                textField.setText(propertyValue);
+                textField.setText(serializableToString(propertyValue));
             } else if (formField instanceof VocabularyTermsComboBoxPanel)
             {
                 VocabularyTermsComboBoxPanel comboBox = (VocabularyTermsComboBoxPanel) formField;
-                for (int i = 0; i < comboBox.getItemCount(); ++i)
-                {
-                    VocabularyTerm term = comboBox.getItemAt(i);
-                    if (term.getCode().equals(propertyValue))
-                    {
-                        comboBox.setSelectedIndex(i);
+                if(propertyValue.getClass().isArray()){
+                    Serializable[] values = (Serializable[]) propertyValue;
+                    for(Serializable val : values) {
+                        setVocabToComboBox(comboBox, (String) val);
                     }
+                } else {
+                    setVocabToComboBox(comboBox, (String) propertyValue);
                 }
+
             } else if (formField instanceof JCheckBox)
             {
                 JCheckBox checkBox = (JCheckBox) formField;
-                checkBox.setSelected(Boolean.parseBoolean(propertyValue));
+                checkBox.setSelected(Boolean.parseBoolean((String)propertyValue));
+            }
+        }
+    }
+
+    private void setVocabToComboBox(VocabularyTermsComboBoxPanel comboBox, String value) {
+
+        for (int i = 0; i < comboBox.getItemCount(); ++i)
+        {
+            VocabularyTerm term = comboBox.getItemAt(i);
+            if (term.getCode().equals(value))
+            {
+                comboBox.setSelectedIndex(i);
+            }
+        }
+    }
+
+    private String serializableToString(Serializable value) {
+        if(value == null) {
+            return null;
+        }
+        if(value.getClass().isArray()) {
+            Serializable[] values = (Serializable[]) value;
+            StringBuilder builder = new StringBuilder("[");
+            for(Serializable val : values) {
+                if(builder.length() > 1) {
+                    builder.append(", ");
+                }
+                builder.append((String)val);
             }
+            builder.append("]");
+            return builder.toString();
+        } else {
+            return (String) value;
         }
     }
 
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadClientModel.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadClientModel.java
index dd18bce29cfa2a1cf8e15c8fe0524b45a5092a86..c31e573b7c97e22ed0b1d9ae700f2b829bc2c482 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadClientModel.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadClientModel.java
@@ -15,6 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.dss.client.api.gui.model;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -665,7 +666,7 @@ public class DataSetUploadClientModel
         } else
         {
             DataSetType type = dataSetTypes.get(getIndexOfDataSetType(typeCode));
-            Map<String, String> properties = builderMetadata.getProperties();
+            Map<String, Serializable> properties = builderMetadata.getProperties();
             for (PropertyTypeGroup ptGroup : type.getPropertyTypeGroups())
             {
                 for (PropertyType propertyType : ptGroup.getPropertyTypes())
@@ -686,10 +687,11 @@ public class DataSetUploadClientModel
 
     }
 
-    protected void validatePropertyType(PropertyType propertyType, String valueOrNull,
+    protected void validatePropertyType(PropertyType propertyType, Serializable valueOrNull,
             ArrayList<ValidationError> errors)
     {
-        if (null == valueOrNull || valueOrNull.trim().length() < 1)
+        if (null == valueOrNull || (valueOrNull instanceof String && ((String) valueOrNull).trim()
+                .isEmpty()))
         {
             if (propertyType.isMandatory())
             {
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
index c9f0712e72db62626d67484d28d520c0b1acf1cf..cd026b0f8c0bb543d3ecdf39d2064f6a63ef9665 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/model/DataSetUploadOperation.java
@@ -15,6 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.dss.client.api.gui.model;
 
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -119,7 +120,7 @@ final class DataSetUploadOperation implements Runnable
             return;
         }
 
-        Map<String, String> dataSetProperties = metadata.getProperties();
+        Map<String, Serializable> dataSetProperties = metadata.getProperties();
         Collection<String> unmodifiableProperties =
                 new ArrayList<String>(metadata.getUnmodifiableProperties());
 
@@ -127,7 +128,7 @@ final class DataSetUploadOperation implements Runnable
         {
             if (vocabularyProperties.keySet().contains(property))
             {
-                String term = dataSetProperties.get(property);
+                Serializable term = dataSetProperties.get(property);
                 if (null == term)
                 {
                     continue;
@@ -140,19 +141,20 @@ final class DataSetUploadOperation implements Runnable
                 }
                 if (false == hasTerm(vocabulary, term))
                 {
-                    clientModel.addUnofficialVocabularyTerm(vocabulary, term, term.trim(), term,
-                            getMaxOrdinal(vocabulary));
+                    String stringTerm = (String) term;
+                    clientModel.addUnofficialVocabularyTerm(vocabulary, stringTerm, stringTerm.trim(),
+                            stringTerm, getMaxOrdinal(vocabulary));
                 }
             }
         }
 
     }
 
-    private boolean hasTerm(Vocabulary vocabulary, String termCode)
+    private boolean hasTerm(Vocabulary vocabulary, Serializable termCode)
     {
         for (VocabularyTerm term : vocabulary.getTerms())
         {
-            if (termCode.equalsIgnoreCase(term.getCode()))
+            if (term.getCode().equalsIgnoreCase((String)termCode))
             {
                 return true;
             }
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
index 2cbace54a77ba3b91842341e407c45750db88642..cb864ca04c4ec3d69154aca993b74e06554e0703 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDssComponent.java
@@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.dss.client.api.v1;
 
 import java.io.File;
 import java.io.InputStream;
+import java.io.Serializable;
 import java.util.List;
 import java.util.Map;
 
@@ -149,7 +150,7 @@ public interface IDssComponent
      * @throws IllegalStateException Thrown if the user has not yet been authenticated.
      * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to the server.
      */
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException,
             EnvironmentFailureException;
 
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java
index 7e3efa836374238eef21a54b25e7fad6f90df547..cdb5a0dafb4d22cbed6ae680bd11aa3d1df489bb 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java
@@ -16,6 +16,7 @@
 package ch.systemsx.cisd.openbis.dss.client.api.v1;
 
 import java.io.File;
+import java.io.Serializable;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
@@ -266,7 +267,7 @@ public interface ISimpleOpenbisServiceFacade
      * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to the server.
      */
     @Retry
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException;
 
     /**
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
index d708f234e541878568c8cf4dfa25ed546e96389b..242771f1098e5b7d36ee25b68847ee1edaa0f0c5 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
@@ -15,13 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.dss.client.api.v1.impl;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
+import java.io.*;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -261,7 +255,7 @@ public class DssComponent implements IDssComponent
     }
 
     @Override
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException
     {
         return state.extractMetadata(newDataset, dataSetFile);
@@ -344,7 +338,7 @@ abstract class AbstractDssComponentState implements IDssComponent
     }
 
     @Override
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException
     {
         throw new IllegalStateException("Please log in");
@@ -884,7 +878,7 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     @Override
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException
     {
         ValidationScriptRunner runner = null;
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java
index 2fa56b847f2c6b17165af1c0b74eb4f742f5a896..066595ad4bed1067c9328cfdedbbf0ca6aadec2a 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java
@@ -16,6 +16,7 @@
 package ch.systemsx.cisd.openbis.dss.client.api.v1.impl;
 
 import java.io.File;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
@@ -540,7 +541,7 @@ public class OpenbisServiceFacade implements IOpenbisServiceFacade
     }
 
     @Override
-    public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
+    public Map<String, Serializable> extractMetadata(NewDataSetDTO newDataset, File dataSetFile)
             throws IllegalStateException, EnvironmentFailureException
     {
         return dssComponent.extractMetadata(newDataset, dataSetFile);
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
index 50b9a99ab318d0ac8d04ee7f299eb8bca80de5e5..66ef7c60b86a4f1f8ace9af545e743016263a377 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTO.java
@@ -262,12 +262,12 @@ public class NewDataSetDTO implements Serializable
         dataSetMetadata.setDataSetTypeOrNull(dataSetTypeOrNull);
     }
 
-    public Map<String, String> getProperties()
+    public Map<String, Serializable> getProperties()
     {
         return dataSetMetadata.getProperties();
     }
 
-    public void setProperties(Map<String, String> props)
+    public void setProperties(Map<String, Serializable> props)
     {
         dataSetMetadata.setProperties(props);
     }
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
index 8d477d5b9bfbd3bc0e11d2b8e05c11fa57cec28c..c166cd1ff9ec91d876ebaa6f1fb8b1889dcedfdd 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
@@ -17,6 +17,7 @@ package ch.systemsx.cisd.openbis.dss.generic.shared.api.v1;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -156,8 +157,8 @@ public class NewDataSetDTOBuilder
         dataSetMetadata.setDataSetTypeOrNull(otherMetadata.tryDataSetType());
 
         // Create a new map initialized from the other properties (a shallow copy).
-        HashMap<String, String> otherProps =
-                new HashMap<String, String>(otherMetadata.getProperties());
+        HashMap<String, Serializable> otherProps =
+                new HashMap<String, Serializable>(otherMetadata.getProperties());
         dataSetMetadata.setProperties(otherProps);
         dataSetMetadata.setUnmodifiableProperties(new HashSet<String>(otherMetadata
                 .getUnmodifiableProperties()));
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetMetadataDTO.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetMetadataDTO.java
index 399937e178cfaabb5e71fff1221f4c559c3c4c20..5ea5425994ee49fb28e08c690027ae2b2f95e85d 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetMetadataDTO.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetMetadataDTO.java
@@ -39,7 +39,7 @@ public class NewDataSetMetadataDTO implements Serializable
 {
     private static final long serialVersionUID = 1L;
 
-    private final Map<String, String> properties = new HashMap<String, String>();
+    private final Map<String, Serializable> properties = new HashMap<String, Serializable>();
 
     private final Set<String> unmodifiableProperties = new HashSet<String>();
 
@@ -47,12 +47,12 @@ public class NewDataSetMetadataDTO implements Serializable
 
     private final ArrayList<String> parentDataSetCodes = new ArrayList<String>();
 
-    public NewDataSetMetadataDTO(String dataSetTypeOrNull, Map<String, String> propertiesOrNull)
+    public NewDataSetMetadataDTO(String dataSetTypeOrNull, Map<String, Serializable> propertiesOrNull)
     {
         this(dataSetTypeOrNull, propertiesOrNull, null);
     }
 
-    public NewDataSetMetadataDTO(String dataSetTypeOrNull, Map<String, String> propertiesOrNull,
+    public NewDataSetMetadataDTO(String dataSetTypeOrNull, Map<String, Serializable> propertiesOrNull,
             List<String> parentDataSetCodesOrNull)
     {
         this.dataSetTypeOrNull = dataSetTypeOrNull;
@@ -83,7 +83,7 @@ public class NewDataSetMetadataDTO implements Serializable
     /**
      * The properties for the new data set. Key is the property code, value is the value (as a string).
      */
-    public Map<String, String> getProperties()
+    public Map<String, Serializable> getProperties()
     {
         return properties;
     }
@@ -96,7 +96,7 @@ public class NewDataSetMetadataDTO implements Serializable
         return unmodifiableProperties;
     }
 
-    public void setProperties(Map<String, String> props)
+    public void setProperties(Map<String, Serializable> props)
     {
         if (props != null)
         {
@@ -113,7 +113,7 @@ public class NewDataSetMetadataDTO implements Serializable
         }
     }
 
-    public void setUnmodifiableProperties(Map<String, String> props)
+    public void setUnmodifiableProperties(Map<String, Serializable> props)
     {
         setProperties(props);
         setUnmodifiableProperties(props.keySet());
@@ -158,7 +158,7 @@ public class NewDataSetMetadataDTO implements Serializable
         {
             sb.append("data set type", myDataSetTypeOrNull);
         }
-        for (Entry<String, String> entry : getProperties().entrySet())
+        for (Entry<String, Serializable> entry : getProperties().entrySet())
         {
             sb.append("property " + entry.getKey(), entry.getValue());
         }
diff --git a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/validation/ValidationScriptRunner.java b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/validation/ValidationScriptRunner.java
index f4b2f7bb3e21e4dd66e6ecc89b2a9f7aa2487c11..ed96650a06df55404e27fdc7dacd82e23a64ca15 100644
--- a/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/validation/ValidationScriptRunner.java
+++ b/server-original-data-store/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/validation/ValidationScriptRunner.java
@@ -16,6 +16,7 @@
 package ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.validation;
 
 import java.io.File;
+import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -146,9 +147,9 @@ public class ValidationScriptRunner
     }
 
     @SuppressWarnings("unchecked")
-    public Map<String, String> extractMetadata(File dataSetFile)
+    public Map<String, Serializable> extractMetadata(File dataSetFile)
     {
-        Map<String, String> metadata = new HashMap<String, String>();
+        Map<String, Serializable> metadata = new HashMap<String, Serializable>();
         PyFunction function = tryJythonFunction(EXTRACT_METADATA_FUNCTION_NAME);
         if (function == null)
         {
@@ -214,7 +215,7 @@ public class ValidationScriptRunner
         }
 
         @Override
-        public Map<String, String> extractMetadata(File dataSetFile)
+        public Map<String, Serializable> extractMetadata(File dataSetFile)
         {
             return Collections.emptyMap();
         }
diff --git a/server-original-data-store/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateUploadedDataSetsTest.java b/server-original-data-store/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateUploadedDataSetsTest.java
index 4ceadfd81653b839c77e0803063d8414e4e9e994..33dc12bafc30d5001a4101258ebc6ec674b5ea12 100644
--- a/server-original-data-store/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateUploadedDataSetsTest.java
+++ b/server-original-data-store/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateUploadedDataSetsTest.java
@@ -15,10 +15,7 @@
  */
 package ch.ethz.sis.openbis.generic.dss.systemtest.api.v3;
 
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -465,7 +462,7 @@ public class CreateUploadedDataSetsTest extends AbstractFileTest
         String dataSetType = "HCS_IMAGE";
         String experimentIdentifier = "/CISD/NEMO/EXP1";
 
-        Map<String, String> properties = new HashMap<String, String>();
+        Map<String, Serializable> properties = new HashMap<String, Serializable>();
         properties.put("COMMENT", "test comment");
 
         UploadedDataSetCreation creation = new UploadedDataSetCreation();
@@ -826,7 +823,7 @@ public class CreateUploadedDataSetsTest extends AbstractFileTest
         String dataSetType = "UNKNOWN";
         String experimentIdentifier = "/CISD/NEMO/EXP1";
 
-        Map<String, String> properties = new HashMap<String, String>();
+        Map<String, Serializable> properties = new HashMap<String, Serializable>();
         properties.put("IDONTEXIST", "test value");
 
         FileToUpload file = new FileToUpload("file", "test.txt", "test content");
diff --git a/server-original-data-store/sourceTest/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandlerTest.java b/server-original-data-store/sourceTest/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandlerTest.java
index de867d909122102cefae2e669a573709e362b08b..ee2580dfd2e0231c552f6dc578b1d765d4df0758 100644
--- a/server-original-data-store/sourceTest/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandlerTest.java
+++ b/server-original-data-store/sourceTest/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetTopLevelDataSetHandlerTest.java
@@ -17,6 +17,7 @@ package ch.systemsx.cisd.etlserver.api.v1;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -172,7 +173,7 @@ public class PutDataSetTopLevelDataSetHandlerTest extends AbstractFileSystemTest
                         dataSetInfoMatcher);
         NewDataSetDTO newDataSet = new NewDataSetDTO(dataSetOwner, null, Arrays.asList(f1));
         newDataSet.setDataSetTypeOrNull("MY-TYPE");
-        HashMap<String, String> props = new HashMap<String, String>();
+        HashMap<String, Serializable> props = new HashMap<String, Serializable>();
         props.put("name", "Albert");
         newDataSet.setProperties(props);
         ConcatenatedContentInputStream inputStream =
diff --git a/server-original-data-store/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java b/server-original-data-store/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
index e7dd4c59ed4db896afb3ecac5d0fbb6c21e582eb..f70ce03282681dc189e8a2b0d1b2ec04234b5ba7 100644
--- a/server-original-data-store/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
+++ b/server-original-data-store/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
@@ -15,11 +15,7 @@
  */
 package ch.systemsx.cisd.openbis.dss.client.api.v1.impl;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -334,7 +330,7 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         File dataSetFile = new File(ValidationScriptRunnerTest.INVALID_DATA_SET);
         NewDataSetDTOBuilder builder = new NewDataSetDTOBuilder();
         builder.setFile(dataSetFile);
-        Map<String, String> result =
+        Map<String, Serializable> result =
                 dssComponent.extractMetadata(builder.asNewDataSetDTO(), dataSetFile);
 
         assertEquals(1, result.size());