diff --git a/microscopy-migration-tool/src/ethz/ch/Main.java b/microscopy-migration-tool/src/ethz/ch/Main.java
index 30b1643c7e8527be582d31274e12f23a9bc8276b..fc8bcf9d7d6dd8ab950a6f76714e0df6f2f79db3 100644
--- a/microscopy-migration-tool/src/ethz/ch/Main.java
+++ b/microscopy-migration-tool/src/ethz/ch/Main.java
@@ -56,9 +56,10 @@ public class Main
             
             doTheWork(true, AS_URL, DSS_URL, user, pass, true, true, true);
         } else {
-            String AS_URL = OPENBIS_LOCAL_DEV + "/openbis/openbis" + IApplicationServerApi.SERVICE_URL;
-            String DSS_URL = DSS_LOCAL_DEV + "/datastore_server" + IDataStoreServerApi.SERVICE_URL;
-            doTheWork(true, AS_URL, DSS_URL, "pontia", "a", true, true, true);
+// Used for development
+//            String AS_URL = OPENBIS_LOCAL_DEV + "/openbis/openbis" + IApplicationServerApi.SERVICE_URL;
+//            String DSS_URL = DSS_LOCAL_DEV + "/datastore_server" + IDataStoreServerApi.SERVICE_URL;
+//            doTheWork(true, AS_URL, DSS_URL, "pontia", "test", true, true, true);
             System.out.println("Example: java -jar microscopy_migration_tool.jar https://openbis-as-domain.ethz.ch https://openbis-dss-domain.ethz.ch user password");
         }
     }
@@ -202,13 +203,13 @@ public class Main
 
         System.out.println("4. Translate Properties to Samples");
 
-        PropertyType2SampleType FACS_ARIA_TUBE =    new PropertyType2SampleType(        "FACS_ARIA_TUBE",   "FACS_ARIA_SPECIMEN",   "FACS_ARIA_SPECIMEN",   "$NAME");
-        PropertyType2SampleType FACS_ARIA_WELL =    new PropertyType2SampleType(        "FACS_ARIA_WELL",   "FACS_ARIA_SPECIMEN",   "FACS_ARIA_SPECIMEN",   "$NAME");
-        PropertyType2SampleType INFLUX_TUBE =       new PropertyType2SampleType(        "INFLUX_TUBE",      "INFLUX_SPECIMEN",      "INFLUX_SPECIMEN",      "$NAME");
-        PropertyType2SampleType LSR_FORTESSA_TUBE = new PropertyType2SampleType(        "LSR_FORTESSA_TUBE","LSR_FORTESSA_SPECIMEN","LSR_FORTESSA_SPECIMEN","$NAME");
-        PropertyType2SampleType LSR_FORTESSA_WELL = new PropertyType2SampleType(        "LSR_FORTESSA_WELL","LSR_FORTESSA_SPECIMEN","LSR_FORTESSA_SPECIMEN","$NAME");
-        PropertyType2SampleType MOFLO_XDP_TUBE =    new PropertyType2SampleType(        "MOFLO_XDP_TUBE",   "MOFLO_XDP_SPECIMEN",   "MOFLO_XDP_SPECIMEN",   "$NAME");
-        PropertyType2SampleType S3E_TUBE =          new PropertyType2SampleType(        "S3E_TUBE",         "S3E_SPECIMEN",         "S3E_SPECIMEN",         "$NAME");
+        PropertyType2SampleType FACS_ARIA_TUBE =    new PropertyType2SampleType(        "FACS_ARIA_TUBE",   "FACS_ARIA_SPECIMEN",   "FACS_ARIA_SPECIMEN",   "$NAME", true, false);
+        PropertyType2SampleType FACS_ARIA_WELL =    new PropertyType2SampleType(        "FACS_ARIA_WELL",   "FACS_ARIA_SPECIMEN",   "FACS_ARIA_SPECIMEN",   "$NAME", true, true);
+        PropertyType2SampleType INFLUX_TUBE =       new PropertyType2SampleType(        "INFLUX_TUBE",      "INFLUX_SPECIMEN",      "INFLUX_SPECIMEN",      "$NAME", true, true);
+        PropertyType2SampleType LSR_FORTESSA_TUBE = new PropertyType2SampleType(        "LSR_FORTESSA_TUBE","LSR_FORTESSA_SPECIMEN","LSR_FORTESSA_SPECIMEN","$NAME", true, false);
+        PropertyType2SampleType LSR_FORTESSA_WELL = new PropertyType2SampleType(        "LSR_FORTESSA_WELL","LSR_FORTESSA_SPECIMEN","LSR_FORTESSA_SPECIMEN","$NAME", true, true);
+        PropertyType2SampleType MOFLO_XDP_TUBE =    new PropertyType2SampleType(        "MOFLO_XDP_TUBE",   "MOFLO_XDP_SPECIMEN",   "MOFLO_XDP_SPECIMEN",   "$NAME", true, true);
+        PropertyType2SampleType S3E_TUBE =          new PropertyType2SampleType(        "S3E_TUBE",         "S3E_SPECIMEN",         "S3E_SPECIMEN",         "$NAME", true, true);
 
         List<PropertyType2SampleType> propertiesMigrationConfigs = Arrays.asList(FACS_ARIA_TUBE,
                 FACS_ARIA_WELL,
diff --git a/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyCopy.java b/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyCopy.java
index cf3f8f8d3fc75e2fa79f54c4f75587e36d15dcf4..947091644571577dd41a2f21b3e3f17689b8bbe3 100644
--- a/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyCopy.java
+++ b/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyCopy.java
@@ -38,6 +38,6 @@ public class DataSetPropertyCopy extends EntityPropertyCopy<DataSet> {
 
     @Override
     public EntityPropertyDelete getEntityPropertyDelete() {
-        return new DataSetPropertyDelete(typeCode, oldPropertyCode);
+        return new DataSetPropertyDelete(typeCode, oldPropertyCode, true, true);
     }
 }
diff --git a/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyDelete.java b/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyDelete.java
index b63a91ca3266c0c6c97c057b64a64b2bf53c33a0..43d48fcd3bcd82fd0fdc5ca06e55d88cf18f87c9 100644
--- a/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyDelete.java
+++ b/microscopy-migration-tool/src/ethz/ch/dataset/DataSetPropertyDelete.java
@@ -8,8 +8,8 @@ import ethz.ch.property.EntityPropertyDelete;
 
 public class DataSetPropertyDelete extends EntityPropertyDelete {
 
-    public DataSetPropertyDelete(String typeCode, String propertyCode) {
-        super(typeCode, propertyCode);
+    public DataSetPropertyDelete(String typeCode, String propertyCode, Boolean unassign, Boolean delete) {
+        super(typeCode, propertyCode, unassign, delete);
     }
 
     @Override
@@ -23,9 +23,14 @@ public class DataSetPropertyDelete extends EntityPropertyDelete {
             }
         }
         if (found) {
-            MasterdataHelper.updateDataSetType(sessionToken, v3, typeCode, MasterdataHelper.PropertyTypeUpdateAction.REMOVE, 1, propertyCode);
-            MasterdataHelper.deletePropertyType(sessionToken, v3, propertyCode);
-            System.out.println("[PROPERTY DELETE] " + "\t" + propertyCode);
+            if (unassign) {
+                MasterdataHelper.updateDataSetType(sessionToken, v3, typeCode, MasterdataHelper.PropertyTypeUpdateAction.REMOVE, 1, propertyCode);
+                System.out.println("[PROPERTY UNASSIGN] " + "\t" + propertyCode);
+            }
+            if (delete) {
+                MasterdataHelper.deletePropertyType(sessionToken, v3, propertyCode);
+                System.out.println("[PROPERTY DELETE] " + "\t" + propertyCode);
+            }
         }
     }
 }
diff --git a/microscopy-migration-tool/src/ethz/ch/experiment/ExperimentType2SampleType.java b/microscopy-migration-tool/src/ethz/ch/experiment/ExperimentType2SampleType.java
index bcea5c9d60b3d4d16482a6c9f87abc57a848fde8..7858a1aaa0da5317a245def47b615d1997371cec 100644
--- a/microscopy-migration-tool/src/ethz/ch/experiment/ExperimentType2SampleType.java
+++ b/microscopy-migration-tool/src/ethz/ch/experiment/ExperimentType2SampleType.java
@@ -36,6 +36,6 @@ public class ExperimentType2SampleType {
     }
 
     public SamplePropertyDelete getSamplePropertyDelete() {
-        return new SamplePropertyDelete(typeCode, propertyTypesToDeleteAfterMigration.get(0));
+        return new SamplePropertyDelete(typeCode, propertyTypesToDeleteAfterMigration.get(0), true, true);
     }
 }
\ No newline at end of file
diff --git a/microscopy-migration-tool/src/ethz/ch/property/EntityPropertyDelete.java b/microscopy-migration-tool/src/ethz/ch/property/EntityPropertyDelete.java
index c876c7d6b37b7041a0614027770df5b888b0b3b3..d02b56e761e84162850120e4ec40a5433eadd9f1 100644
--- a/microscopy-migration-tool/src/ethz/ch/property/EntityPropertyDelete.java
+++ b/microscopy-migration-tool/src/ethz/ch/property/EntityPropertyDelete.java
@@ -6,10 +6,14 @@ public abstract class EntityPropertyDelete {
 
     protected final String typeCode;
     protected final String propertyCode;
+    protected final Boolean unassign;
+    protected final Boolean delete;
 
-    public EntityPropertyDelete(String typeCode, String propertyCode) {
+    public EntityPropertyDelete(String typeCode, String propertyCode, Boolean unassign, Boolean delete) {
         this.typeCode = typeCode;
         this.propertyCode = propertyCode;
+        this.unassign = unassign;
+        this.delete = delete;
     }
 
     public abstract void deleteOldPropertyType(String sessionToken, IApplicationServerApi v3);
diff --git a/microscopy-migration-tool/src/ethz/ch/property/PropertyType2SampleType.java b/microscopy-migration-tool/src/ethz/ch/property/PropertyType2SampleType.java
index bed6b62795c30f76013166a06d72b7a328aecb53..28e9f4676d236a7a2345e463594450ed27182192 100644
--- a/microscopy-migration-tool/src/ethz/ch/property/PropertyType2SampleType.java
+++ b/microscopy-migration-tool/src/ethz/ch/property/PropertyType2SampleType.java
@@ -8,14 +8,18 @@ public class PropertyType2SampleType
     private String oldPropertyCode;
     private String newSampleTypeCode;
     private String newPropertyCode;
-    
-    public PropertyType2SampleType(String oldSampleType, String oldPropertyCode, String newSampleType, String newPropertyCode)
+    private Boolean oldPropertyUnassign;
+    private Boolean oldPropertyDelete;
+
+    public PropertyType2SampleType(String oldSampleType, String oldPropertyCode, String newSampleType, String newPropertyCode, Boolean oldPropertyUnassign, Boolean oldPropertyDelete)
     {
         super();
         this.oldSampleTypeCode = oldSampleType;
         this.oldPropertyCode = oldPropertyCode;
         this.newSampleTypeCode = newSampleType;
         this.newPropertyCode = newPropertyCode;
+        this.oldPropertyUnassign = oldPropertyUnassign;
+        this.oldPropertyDelete = oldPropertyDelete;
     }
 
     public String getOldSampleTypeCode()
@@ -39,7 +43,7 @@ public class PropertyType2SampleType
     }
 
     public EntityPropertyDelete getEntityPropertyDelete() {
-        return new SamplePropertyDelete(oldSampleTypeCode, oldPropertyCode);
+        return new SamplePropertyDelete(oldSampleTypeCode, oldPropertyCode, oldPropertyUnassign, oldPropertyDelete);
     }
     
 }
\ No newline at end of file
diff --git a/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyCopy.java b/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyCopy.java
index d820b3e2591a74f8da60eeaa4dacc74a9f6c98d7..faa0dfd58369c0e6fb072f54d39052617c41682c 100644
--- a/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyCopy.java
+++ b/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyCopy.java
@@ -38,6 +38,6 @@ public class SamplePropertyCopy extends EntityPropertyCopy<Sample> {
 
     @Override
     public EntityPropertyDelete getEntityPropertyDelete() {
-        return new SamplePropertyDelete(typeCode, oldPropertyCode);
+        return new SamplePropertyDelete(typeCode, oldPropertyCode, true, true);
     }
 }
diff --git a/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyDelete.java b/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyDelete.java
index 2884399846bea8791b32410b3cdb12bc19f429ad..18912ca10fb67bad63345d6e72b807be2a9ec617 100644
--- a/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyDelete.java
+++ b/microscopy-migration-tool/src/ethz/ch/sample/SamplePropertyDelete.java
@@ -8,8 +8,8 @@ import ethz.ch.property.EntityPropertyDelete;
 
 public class SamplePropertyDelete extends EntityPropertyDelete {
 
-    public SamplePropertyDelete(String typeCode, String propertyCode) {
-        super(typeCode, propertyCode);
+    public SamplePropertyDelete(String typeCode, String propertyCode, Boolean unassign, Boolean delete) {
+        super(typeCode, propertyCode, unassign, delete);
     }
 
     @Override
@@ -23,9 +23,14 @@ public class SamplePropertyDelete extends EntityPropertyDelete {
             }
         }
         if (found) {
-            MasterdataHelper.updateSampleType(sessionToken, v3, typeCode, MasterdataHelper.PropertyTypeUpdateAction.REMOVE, 1, propertyCode);
-            MasterdataHelper.deletePropertyType(sessionToken, v3, propertyCode);
-            System.out.println("[PROPERTY DELETE] " + "\t" + propertyCode);
+            if (unassign) {
+                MasterdataHelper.updateSampleType(sessionToken, v3, typeCode, MasterdataHelper.PropertyTypeUpdateAction.REMOVE, 1, propertyCode);
+                System.out.println("[PROPERTY UNASSIGN] " + "\t" + propertyCode);
+            }
+            if (delete) {
+                MasterdataHelper.deletePropertyType(sessionToken, v3, propertyCode);
+                System.out.println("[PROPERTY DELETE] " + "\t" + propertyCode);
+            }
         }
     }
 }
diff --git a/openbis_ng_ui/src/components/common/content/Content.jsx b/openbis_ng_ui/src/components/common/content/Content.jsx
index d9a62dcae445972bb6cde44ec1f857f7dcb8deed..406773592930770eabea3077016d2e482e3b3bbb 100644
--- a/openbis_ng_ui/src/components/common/content/Content.jsx
+++ b/openbis_ng_ui/src/components/common/content/Content.jsx
@@ -17,12 +17,10 @@ const styles = {
     width: '100px'
   },
   component: {
-    margin: '12px 0px 0px 12px',
-    overflowY: 'auto',
     flex: '1 1 100%'
   },
   visible: {
-    display: 'flex'
+    display: 'block'
   },
   hidden: {
     display: 'none',
diff --git a/openbis_ng_ui/src/components/login/Login.jsx b/openbis_ng_ui/src/components/login/Login.jsx
index 41597eb622db73faf7e2a52ebe18ef25e1322bf1..b9211c38390b432fd83cc3248721244b6bb54898 100644
--- a/openbis_ng_ui/src/components/login/Login.jsx
+++ b/openbis_ng_ui/src/components/login/Login.jsx
@@ -19,9 +19,6 @@ const styles = {
     width: '30em',
     margin: '0 auto',
   },
-  title: {
-    fontSize: 24,
-  },
   textField: {
     width: '100%',
   },
@@ -74,44 +71,47 @@ class WithLogin extends React.Component {
     return (
       <div>
         <div className={classes.container}>
-          <Card className={classes.card}>
-            <CardContent>
-              <Typography className={classes.title}>
+          <form>
+            <Card className={classes.card}>
+              <CardContent>
+                <Typography variant="h6">
                   Login
-              </Typography>
-              <TextField
-                id="standard-name"
-                label="User"
-                className={classes.textField}
-                margin="normal"
-                autoFocus={true}
-                onKeyPress={(e) => {
-                  this.keyPress(e)
-                }}
-                onChange={this.handleChange('user')}
-              />
-              <TextField
-                id="standard-password-input"
-                label="Password"
-                className={classes.textField}
-                type="password"
-                autoComplete="current-password"
-                margin="normal"
-                onKeyPress={(e) => {
-                  this.keyPress(e)
-                }}
-                onChange={this.handleChange('password')}
-              />
-              <Button
-                onClick={this.login}
-                color="primary"
-                className={classes.button}
-                variant="contained">
+                </Typography>
+                <TextField
+                  id="standard-name"
+                  label="User"
+                  className={classes.textField}
+                  margin="normal"
+                  autoComplete="username"
+                  autoFocus={true}
+                  onKeyPress={(e) => {
+                    this.keyPress(e)
+                  }}
+                  onChange={this.handleChange('user')}
+                />
+                <TextField
+                  id="standard-password-input"
+                  label="Password"
+                  className={classes.textField}
+                  type="password"
+                  autoComplete="current-password"
+                  margin="normal"
+                  onKeyPress={(e) => {
+                    this.keyPress(e)
+                  }}
+                  onChange={this.handleChange('password')}
+                />
+                <Button
+                  onClick={this.login}
+                  color="primary"
+                  className={classes.button}
+                  variant="contained">
                   Login
-              </Button>
+                </Button>
 
-            </CardContent>
-          </Card>
+              </CardContent>
+            </Card>
+          </form>
         </div>
       </div>
     )
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
index b56fcd2af5141ae7df64cd57e40b91e65ffff0e3..8ec183dacc9f8dfed42da8bfd63a4c771493ae26 100644
--- a/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectType.jsx
@@ -1,17 +1,28 @@
 import _ from 'lodash'
 import React from 'react'
-import TextField from '@material-ui/core/TextField'
-import Checkbox from '@material-ui/core/Checkbox'
-import Button from '@material-ui/core/Button'
-import Table from '@material-ui/core/Table'
-import TableBody from '@material-ui/core/TableBody'
-import TableCell from '@material-ui/core/TableCell'
-import TableHead from '@material-ui/core/TableHead'
-import TableRow from '@material-ui/core/TableRow'
-import FormControlLabel from '@material-ui/core/FormControlLabel'
+import {withStyles} from '@material-ui/core/styles'
+import ObjectTypeForm from './ObjectTypeForm.jsx'
+import ObjectTypeFooter from './ObjectTypeFooter.jsx'
 import logger from '../../../common/logger.js'
 import {facade, dto} from '../../../services/openbis.js'
 
+const styles = (theme) => ({
+  container: {
+    height: '100%',
+    display: 'flex',
+    flexDirection: 'column'
+  },
+  form: {
+    flex: '1 1 0',
+    overflow: 'auto',
+    padding: theme.spacing.unit * 2
+  },
+  footer: {
+    flex: '0 0',
+    padding: theme.spacing.unit * 2
+  }
+})
+
 class ObjectType extends React.Component {
 
   constructor(props){
@@ -19,60 +30,222 @@ class ObjectType extends React.Component {
     this.state = {
       loaded: false,
     }
+    this.handleChange = this.handleChange.bind(this)
+    this.handleAdd = this.handleAdd.bind(this)
+    this.handleSelect = this.handleSelect.bind(this)
+    this.handleReorder = this.handleReorder.bind(this)
+    this.handleRemove = this.handleRemove.bind(this)
     this.handleSave = this.handleSave.bind(this)
   }
 
   componentDidMount(){
-    let id = new dto.EntityTypePermId(this.props.objectId)
+    Promise.all([
+      this.loadObjectType(this.props.objectId),
+      this.loadPropertyTypes()
+    ]).then(([objectType, propertyTypes]) => {
+      this.setState(() => ({
+        loaded: true,
+        objectType: objectType,
+        propertyTypes: propertyTypes
+      }))
+    })
+  }
+
+  loadObjectType(objectTypeId){
+    let id = new dto.EntityTypePermId(objectTypeId)
     let fo = new dto.SampleTypeFetchOptions()
-    fo.withPropertyAssignments().withPropertyType()
+    fo.withPropertyAssignments().withPropertyType().withMaterialType()
+    fo.withPropertyAssignments().withPropertyType().withVocabulary()
     fo.withPropertyAssignments().sortBy().code()
 
-    facade.getSampleTypes([id], fo).then(map => {
-      let objectType = map[this.props.objectId]
+    return facade.getSampleTypes([id], fo).then(map => {
+      let objectType = map[objectTypeId]
       if(objectType){
-        this.setState(() => {
+        return {
+          code: objectType.code,
+          properties: objectType.propertyAssignments.map(assignment => ({
+            permId: assignment.permId,
+            propertyType: assignment.propertyType,
+            ordinal: assignment.ordinal,
+            mandatory: assignment.mandatory,
+            selected: false,
+            errors: {}
+          }))
+        }
+      }else{
+        return null
+      }
+    })
+  }
+
+  loadPropertyTypes(){
+    let criteria = new dto.PropertyTypeSearchCriteria()
+    let fo = new dto.PropertyTypeFetchOptions()
+    fo.withVocabulary().withTerms()
+    fo.withMaterialType()
+
+    return facade.searchPropertyTypes(criteria, fo).then(result => {
+      return result.objects
+    })
+  }
+
+  handleChange(ordinal, key, value){
+    this.setState((prevState) => {
+      let newProperties = prevState.objectType.properties.map((property) => {
+        if(property.ordinal === ordinal){
           return {
-            loaded: true,
-            data: {
-              code: objectType.code,
-              description: objectType.description || '',
-              listable: objectType.listable,
-              properties: objectType.propertyAssignments.map(assignment => ({
-                permId: assignment.permId,
-                code: assignment.propertyType.code,
-                label: assignment.propertyType.label,
-                description: assignment.propertyType.description,
-                ordinal: assignment.ordinal,
-                mandatory: assignment.mandatory
-              }))
-            }
+            ...property,
+            [key]: value
           }
-        })
+        }else{
+          return property
+        }
+      })
+      return {
+        ...prevState,
+        objectType: {
+          ...prevState.objectType,
+          properties: newProperties
+        }
+      }
+    }, () => {
+      if(this.state.validated){
+        this.validate()
       }
     })
   }
 
-  handleChange(name){
-    return event => {
-      let value = _.has(event.target, 'checked') ? event.target.checked : event.target.value
-      this.setState((prevState) => ({
+  handleRemove(){
+    this.setState((prevState) => {
+      let newProperties = prevState.objectType.properties.reduce((array, property) => {
+        if(!property.selected){
+          array.push(property)
+        }
+        return array
+      }, [])
+
+      return {
         ...prevState,
-        data: {
-          ...prevState.data,
-          [name]: value
+        objectType: {
+          ...prevState.objectType,
+          properties: newProperties
         }
-      }))
-    }
+      }
+    })
+  }
+
+  handleAdd(){
+    this.setState((prevState) => {
+      let newOrdinal = 0
+      let newProperties = prevState.objectType.properties.map(property => {
+        if(newOrdinal <= property.ordinal){
+          newOrdinal = property.ordinal + 1
+        }
+        return {
+          ...property,
+          selected: false
+        }
+      })
+      newProperties.push({
+        permId: null,
+        propertyType: null,
+        mandatory: false,
+        selected: true,
+        ordinal: newOrdinal,
+        errors: {}
+      })
+
+      return {
+        ...prevState,
+        objectType: {
+          ...prevState.objectType,
+          properties: newProperties
+        }
+      }
+    })
+  }
+
+  handleSelect(ordinal){
+    this.setState((prevState) => ({
+      ...prevState,
+      objectType: {
+        ...prevState.objectType,
+        properties: prevState.objectType.properties.map(property => {
+          return {
+            ...property,
+            selected: property.ordinal === ordinal ? !property.selected : false
+          }
+        })
+      }
+    }))
+  }
+
+  handleReorder(oldPropertyIndex, newPropertyIndex){
+    let oldProperties = this.state.objectType.properties
+    let newProperties = oldProperties.map(property => {
+      if(property.selected){
+        return {
+          ...property,
+          selected: false
+        }
+      }else{
+        return property
+      }
+    })
+
+    let [ property ] = newProperties.splice(oldPropertyIndex, 1)
+    newProperties.splice(newPropertyIndex, 0, {
+      ...property,
+      selected: true
+    })
+
+    this.setState((prevState) => ({
+      ...prevState,
+      objectType: {
+        ...prevState.objectType,
+        properties: newProperties
+      }
+    }))
+  }
+
+  validate(){
+    let valid = true
+
+    let newProperties = this.state.objectType.properties.map(property => {
+      let errors = {}
+
+      if(!property.propertyType){
+        errors['propertyType'] = 'Cannot be empty'
+      }
+
+      if(_.size(errors) > 0){
+        valid = false
+      }
+
+      return {
+        ...property,
+        errors: errors
+      }
+    })
+
+    this.setState((prevState) => ({
+      ...prevState,
+      validated: true,
+      objectType: {
+        ...prevState.objectType,
+        properties: newProperties
+      }
+    }))
+
+    return valid
   }
 
   handleSave(){
-    let {description, listable} = this.state.data
-    let update = new dto.SampleTypeUpdate()
-    update.setTypeId(new dto.EntityTypePermId(this.props.objectId))
-    update.setDescription(description)
-    update.setListable(listable)
-    facade.updateSampleTypes([update])
+    if(this.validate()){
+      let update = new dto.SampleTypeUpdate()
+      update.setTypeId(new dto.EntityTypePermId(this.props.objectId))
+      facade.updateSampleTypes([update])
+    }
   }
 
   render() {
@@ -82,54 +255,30 @@ class ObjectType extends React.Component {
       return <div></div>
     }
 
-    let { code, description, listable, properties } = this.state.data
+    let classes = this.props.classes
 
     return (
-      <div>
-        <h2>{code}</h2>
-        <form>
-          <FormControlLabel
-            label="Description"
-            labelPlacement="top"
-            control={
-              <TextField value={description} onChange={this.handleChange('description')} />
-            }
+      <div className={classes.container}>
+        <div className={classes.form}>
+          <ObjectTypeForm
+            objectType={this.state.objectType}
+            propertyTypes={this.state.propertyTypes}
+            onSelect={this.handleSelect}
+            onReorder={this.handleReorder}
+            onChange={this.handleChange}
           />
-          <FormControlLabel
-            label="Listable"
-            labelPlacement="top"
-            control={
-              <Checkbox checked={listable} value='listable' onChange={this.handleChange('listable')} />
-            }
+        </div>
+        <div className={classes.footer}>
+          <ObjectTypeFooter
+            onAdd={this.handleAdd}
+            onRemove={this.handleRemove}
+            onSave={this.handleSave}
           />
-          <Table>
-            <TableHead>
-              <TableRow>
-                <TableCell>Code</TableCell>
-                <TableCell>Label</TableCell>
-                <TableCell>Description</TableCell>
-                <TableCell>Mandatory</TableCell>
-              </TableRow>
-            </TableHead>
-            <TableBody>
-              {properties.map(property => (
-                <TableRow key={property.permId}>
-                  <TableCell>{property.code}</TableCell>
-                  <TableCell>{property.label}</TableCell>
-                  <TableCell>{property.description}</TableCell>
-                  <TableCell>{property.mandatory ? 'true' : 'false'}</TableCell>
-                </TableRow>
-              ))}
-            </TableBody>
-          </Table>
-          <div>
-            <Button variant='contained' color='primary' onClick={this.handleSave}>Save</Button>
-          </div>
-        </form>
+        </div>
       </div>
     )
   }
 
 }
 
-export default ObjectType
+export default withStyles(styles)(ObjectType)
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypeFooter.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypeFooter.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..6e4fe631512af8fb40dfecd31b91691b923374b7
--- /dev/null
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypeFooter.jsx
@@ -0,0 +1,30 @@
+import React from 'react'
+import Button from '@material-ui/core/Button'
+import {withStyles} from '@material-ui/core/styles'
+import logger from '../../../common/logger.js'
+
+const styles = (theme) => ({
+  button: {
+    marginRight: theme.spacing.unit * 2
+  }
+})
+
+class ObjectTypeFooter extends React.Component {
+
+  render() {
+    logger.log(logger.DEBUG, 'ObjectTypeFooter.render')
+
+    const classes = this.props.classes
+
+    return (
+      <div>
+        <Button classes={{ root: classes.button }} variant='contained' color='secondary' onClick={this.props.onAdd}>Add</Button>
+        <Button classes={{ root: classes.button }} variant='contained' color='secondary' onClick={this.props.onRemove}>Remove</Button>
+        <Button classes={{ root: classes.button }} variant='contained' color='primary' onClick={this.props.onSave}>Save</Button>
+      </div>
+    )
+  }
+
+}
+
+export default withStyles(styles)(ObjectTypeFooter)
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypeForm.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypeForm.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..0ae0b5c17dcdbee4bf18809ab32cae75a2badc43
--- /dev/null
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypeForm.jsx
@@ -0,0 +1,43 @@
+import _ from 'lodash'
+import React from 'react'
+import Typography from '@material-ui/core/Typography'
+import ObjectTypeTable from './ObjectTypeTable.jsx'
+import {withStyles} from '@material-ui/core/styles'
+import logger from '../../../common/logger.js'
+
+const styles = () => ({
+})
+
+class ObjectTypeForm extends React.Component {
+
+  render() {
+    logger.log(logger.DEBUG, 'ObjectTypeForm.render')
+
+    let { objectType, propertyTypes } = this.props
+    let { code, properties } = objectType
+
+    return (
+      <div>
+        <Typography variant="h6">
+          {code}
+        </Typography>
+        <form>
+          {properties && properties.length > 0 &&
+            <ObjectTypeTable
+              objectType={objectType}
+              propertyTypes={propertyTypes}
+              onSelect={this.props.onSelect}
+              onReorder={this.props.onReorder}
+              onChange={this.props.onChange}
+            />
+          }
+        </form>
+      </div>
+    )
+  }
+
+}
+
+export default _.flow(
+  withStyles(styles),
+)(ObjectTypeForm)
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..4ff1651daccf58719ddc0349d20ebd93fc998be8
--- /dev/null
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyPreview.jsx
@@ -0,0 +1,263 @@
+import _ from 'lodash'
+import React from 'react'
+import FormControlLabel from '@material-ui/core/FormControlLabel'
+import TextField from '@material-ui/core/TextField'
+import MenuItem from '@material-ui/core/MenuItem'
+import Checkbox from '@material-ui/core/Checkbox'
+import InfoIcon from '@material-ui/icons/InfoOutlined'
+import Tooltip from '@material-ui/core/Tooltip'
+import {withStyles} from '@material-ui/core/styles'
+import {facade, dto} from '../../../services/openbis.js'
+import logger from '../../../common/logger.js'
+
+const styles = () => ({
+  container: {
+    display: 'flex',
+    flexDirection: 'row',
+    alignItems: 'center'
+  },
+  boolean: {
+    width: '100%'
+  }
+})
+
+class ObjectTypePropertyPreview extends React.Component {
+
+  constructor(props){
+    super(props)
+    this.state = {
+      vocabularyValue: '',
+      materialValue: '',
+    }
+    this.setMaterial = this.setMaterial.bind(this)
+    this.setVocabulary = this.setVocabulary.bind(this)
+  }
+
+  static getDerivedStateFromProps(props, state) {
+    if(props.property !== state.property){
+      return {
+        loaded: false,
+        property: props.property,
+        vocabularyTerms: [],
+        materials: []
+      }
+    }else{
+      return null
+    }
+  }
+
+  componentDidMount(){
+    this.load()
+  }
+
+  componentDidUpdate(){
+    this.load()
+  }
+
+  load(){
+    if(this.state.loaded){
+      return
+    }
+
+    const {propertyType} = this.state.property
+
+    switch(propertyType.dataType){
+      case 'CONTROLLEDVOCABULARY':
+        this.loadVocabulary()
+        return
+      case 'MATERIAL':
+        this.loadMaterial()
+        return
+      default:
+        this.setState(() => ({
+          loaded: true
+        }))
+        return
+    }
+  }
+
+  render(){
+    logger.log(logger.DEBUG, 'ObjectTypePropertyPreview.render')
+
+    const {classes} = this.props
+
+    return (
+      <div className={classes.container} onClick={(event) => {event.stopPropagation()}}>
+        {this.renderField()}
+        <Tooltip title={this.getDescription()}>
+          <InfoIcon />
+        </Tooltip>
+      </div>
+    )
+  }
+
+  renderField(){
+    const {propertyType} = this.state.property
+
+    switch(propertyType.dataType){
+      case 'BOOLEAN':
+        return this.renderBoolean()
+      case 'VARCHAR':
+        return this.renderVarchar()
+      case 'MULTILINE_VARCHAR':
+        return this.renderMultilineVarchar()
+      case 'INTEGER':
+      case 'REAL':
+        return this.renderNumber()
+      case 'CONTROLLEDVOCABULARY':
+        return this.renderVocabulary()
+      case 'MATERIAL':
+        return this.renderMaterial()
+      default:
+        return this.renderUnsupported()
+    }
+  }
+
+  renderBoolean(){
+    const {classes} = this.props
+    return (
+      <FormControlLabel classes={{ root: classes.boolean }}
+        control={<Checkbox />}
+        label={this.getLabel()}
+      />
+    )
+  }
+
+  renderVarchar(){
+    return (
+      <TextField
+        label={this.getLabel()}
+        fullWidth={true}
+        variant="filled"
+      />
+    )
+  }
+
+  renderMultilineVarchar(){
+    return (
+      <TextField
+        label={this.getLabel()}
+        multiline={true}
+        fullWidth={true}
+        variant="filled"
+      />
+    )
+  }
+
+  renderNumber(){
+    return (
+      <TextField
+        label={this.getLabel()}
+        type="number"
+        fullWidth={true}
+        variant="filled"
+      />
+    )
+  }
+
+  loadVocabulary(){
+    let criteria = new dto.VocabularyTermSearchCriteria()
+    let fo = new dto.VocabularyTermFetchOptions()
+
+    criteria.withVocabulary().withCode().thatEquals(this.state.property.propertyType.vocabulary.code)
+
+    return facade.searchVocabularyTerms(criteria, fo).then(result => {
+      this.setState(() => ({
+        loaded: true,
+        vocabularyTerms: result.objects
+      }))
+    })
+  }
+
+  getVocabulary(){
+    return this.state.vocabularyValue
+  }
+
+  setVocabulary(event){
+    this.setState(() => ({
+      vocabularyValue: event.target.value
+    }))
+  }
+
+  renderVocabulary(){
+    return (
+      <TextField
+        select
+        label={this.getLabel()}
+        value={this.getVocabulary()}
+        onChange={this.setVocabulary}
+        fullWidth={true}
+        variant="filled"
+      >
+        <MenuItem value=""></MenuItem>
+        {this.state.vocabularyTerms.map(term => (
+          <MenuItem key={term.code} value={term.code}>{term.label || term.code}</MenuItem>
+        ))}
+      </TextField>
+    )
+  }
+
+  loadMaterial(){
+    let criteria = new dto.MaterialSearchCriteria()
+    let fo = new dto.MaterialFetchOptions()
+
+    let materialType = this.state.property.propertyType.materialType
+    if(materialType){
+      criteria.withType().withId().thatEquals(materialType.permId)
+    }
+
+    return facade.searchMaterials(criteria, fo).then(result => {
+      this.setState(() => ({
+        loaded: true,
+        materials: result.objects
+      }))
+    })
+  }
+
+  getMaterial(){
+    return this.state.materialValue
+  }
+
+  setMaterial(event){
+    this.setState(() => ({
+      materialValue: event.target.value
+    }))
+  }
+
+  renderMaterial(){
+    return (
+      <TextField
+        select
+        label={this.getLabel()}
+        value={this.getMaterial()}
+        onChange={this.setMaterial}
+        fullWidth={true}
+        variant="filled"
+      >
+        <MenuItem value=""></MenuItem>
+        {this.state.materials.map(material => (
+          <MenuItem key={material.code} value={material.code}>{material.code}</MenuItem>
+        ))}
+      </TextField>
+    )
+  }
+
+  renderUnsupported(){
+    return (<div>unsupported</div>)
+  }
+
+  getLabel(){
+    let mandatory = this.state.property.mandatory
+    let label = this.state.property.propertyType.label
+    return mandatory ? label + '*' : label
+  }
+
+  getDescription(){
+    return this.state.property.propertyType.description
+  }
+
+}
+
+export default _.flow(
+  withStyles(styles)
+)(ObjectTypePropertyPreview)
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..02b723a71801be1fa4b29195c239263138aa0065
--- /dev/null
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypePropertyRow.jsx
@@ -0,0 +1,183 @@
+import _ from 'lodash'
+import React from 'react'
+import { DragSource } from 'react-dnd'
+import { DropTarget } from 'react-dnd'
+import MenuItem from '@material-ui/core/MenuItem'
+import TableCell from '@material-ui/core/TableCell'
+import TableRow from '@material-ui/core/TableRow'
+import TextField from '@material-ui/core/TextField'
+import Checkbox from '@material-ui/core/Checkbox'
+import DragHandleIcon from '@material-ui/icons/DragHandle'
+import RootRef from '@material-ui/core/RootRef'
+import ObjectTypePropertyPreview from './ObjectTypePropertyPreview.jsx'
+import {withStyles} from '@material-ui/core/styles'
+import logger from '../../../common/logger.js'
+
+const styles = (theme) => ({
+  row: {
+    backgroundColor: theme.palette.background.paper,
+    '&:hover': {
+      backgroundColor: 'rgba(0, 0, 0, 0.08)',
+      cursor: 'pointer'
+    },
+    '&$selected': {
+      backgroundColor: 'rgba(0, 0, 0, 0.14)'
+    }
+  },
+  selected: {},
+  drag: {
+    cursor: 'grab'
+  }
+})
+
+const source = {
+  beginDrag(props) {
+    return { sourceIndex: props.index }
+  },
+  endDrag(props, monitor) {
+    if(monitor.getItem() && monitor.getDropResult()){
+      const { sourceIndex } = monitor.getItem()
+      const { targetIndex } = monitor.getDropResult()
+      props.onReorder(sourceIndex, targetIndex)
+    }
+  }
+}
+
+function sourceCollect(connect, monitor) {
+  return {
+    connectDragSource: connect.dragSource(),
+    connectDragPreview: connect.dragPreview(),
+    isDragging: monitor.isDragging()
+  }
+}
+
+const target = {
+  drop(props) {
+    return { targetIndex: props.index }
+  }
+}
+
+function targetCollect(connect, monitor) {
+  return {
+    connectDropTarget: connect.dropTarget(),
+    isDragging: monitor.getItem() !== null
+  }
+}
+
+class ObjectTypeTableRow extends React.Component {
+
+  constructor(props){
+    super(props)
+    this.handleRef = React.createRef()
+    this.rowRef = React.createRef()
+    this.handleSelect = this.handleSelect.bind(this)
+    this.handleChangePropertyType = this.handleChangePropertyType.bind(this)
+    this.handleChangeMandatory = this.handleChangeMandatory.bind(this)
+  }
+
+  componentDidMount(){
+    this.props.connectDragSource(this.handleRef.current)
+    this.props.connectDragPreview(this.rowRef.current)
+    this.props.connectDropTarget(this.rowRef.current)
+  }
+
+  handleSelect(){
+    this.props.onSelect(this.props.property.ordinal)
+  }
+
+  handleChangePropertyType(event){
+    event.stopPropagation()
+    let propertyType = _.find(this.props.propertyTypes, propertyType => {
+      return propertyType.code === event.target.value
+    })
+    this.props.onChange(this.props.property.ordinal, 'propertyType', propertyType)
+  }
+
+  handleChangeMandatory(event){
+    event.stopPropagation()
+    this.props.onChange(this.props.property.ordinal, 'mandatory', event.target.checked)
+  }
+
+  render(){
+    logger.log(logger.DEBUG, 'ObjectTypePropertyRow.render')
+
+    const {classes, property} = this.props
+
+    return (
+      <RootRef rootRef={this.rowRef}>
+        <TableRow
+          classes={{ root: classes.row, selected: classes.selected }}
+          selected={property.selected}
+          onClick={this.handleSelect}
+        >
+          <RootRef rootRef={this.handleRef}>
+            <TableCell classes={{ root: classes.drag }}>
+              <DragHandleIcon />
+            </TableCell>
+          </RootRef>
+          <TableCell>
+            {this.renderPreview()}
+          </TableCell>
+          <TableCell>
+            {this.renderPropertyType()}
+          </TableCell>
+          <TableCell>
+            {this.renderMandatory()}
+          </TableCell>
+        </TableRow>
+      </RootRef>
+    )
+  }
+
+  renderPreview(){
+    const {property} = this.props
+
+    if(property.propertyType){
+      return (
+        <ObjectTypePropertyPreview property={property} />
+      )
+    }else{
+      return (<div></div>)
+    }
+  }
+
+  renderPropertyType(){
+    const {property, propertyTypes} = this.props
+
+    return (
+      <TextField
+        select
+        value={property.propertyType ? property.propertyType.code : ''}
+        onClick={event => {event.stopPropagation()}}
+        onChange={this.handleChangePropertyType}
+        fullWidth={true}
+        error={property.errors['propertyType'] ? true : false}
+        helperText={property.errors['propertyType']}
+      >
+        <MenuItem value=""></MenuItem>
+        {propertyTypes && propertyTypes.map(propertyType => (
+          <MenuItem key={propertyType.code} value={propertyType.code}>{propertyType.code}</MenuItem>
+        ))}
+      </TextField>
+    )
+  }
+
+  renderMandatory(){
+    const {property} = this.props
+
+    return (
+      <Checkbox
+        checked={property.mandatory}
+        value='mandatory'
+        onClick={event => {event.stopPropagation()}}
+        onChange={this.handleChangeMandatory}
+      />
+    )
+  }
+}
+
+export default _.flow(
+  DragSource('property', source, sourceCollect),
+  DropTarget('property', target, targetCollect),
+  withStyles(styles)
+)(ObjectTypeTableRow)
diff --git a/openbis_ng_ui/src/components/types/objectType/ObjectTypeTable.jsx b/openbis_ng_ui/src/components/types/objectType/ObjectTypeTable.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..766964a853973440cc6c95026df8f94e680e9b77
--- /dev/null
+++ b/openbis_ng_ui/src/components/types/objectType/ObjectTypeTable.jsx
@@ -0,0 +1,62 @@
+import _ from 'lodash'
+import React from 'react'
+import Table from '@material-ui/core/Table'
+import TableBody from '@material-ui/core/TableBody'
+import TableHead from '@material-ui/core/TableHead'
+import TableCell from '@material-ui/core/TableCell'
+import TableRow from '@material-ui/core/TableRow'
+import ObjectTypePropertyRow from './ObjectTypePropertyRow.jsx'
+import {withStyles} from '@material-ui/core/styles'
+import logger from '../../../common/logger.js'
+
+const styles = () => ({
+  table: {
+    width: '100%'
+  }
+})
+
+class ObjectTypeTable extends React.Component {
+
+  constructor(props){
+    super(props)
+    this.state = {}
+  }
+
+  render() {
+    logger.log(logger.DEBUG, 'ObjectTypeTable.render')
+
+    const { classes, objectType, propertyTypes } = this.props
+    const { properties } = objectType
+
+    return (
+      <Table className={classes.table}>
+        <TableHead>
+          <TableRow>
+            <TableCell></TableCell>
+            <TableCell>Preview</TableCell>
+            <TableCell>Property Type*</TableCell>
+            <TableCell>Mandatory</TableCell>
+          </TableRow>
+        </TableHead>
+        <TableBody>
+          {properties.map((property, index) => (
+            <React.Fragment key={property.ordinal}>
+              <ObjectTypePropertyRow
+                index={index}
+                property={property}
+                propertyTypes={propertyTypes}
+                onChange={this.props.onChange}
+                onSelect={this.props.onSelect}
+                onReorder={this.props.onReorder}
+              />
+            </React.Fragment>
+          ))}
+        </TableBody>
+      </Table>)
+  }
+
+}
+
+export default _.flow(
+  withStyles(styles)
+)(ObjectTypeTable)
diff --git a/openbis_ng_ui/src/index.js b/openbis_ng_ui/src/index.js
index bcc09501df0371b3ebb40c49674b6f49e209d322..b0b85c7f7aadfc6960fac39651e337d280e91765 100644
--- a/openbis_ng_ui/src/index.js
+++ b/openbis_ng_ui/src/index.js
@@ -2,13 +2,37 @@ import 'regenerator-runtime/runtime'
 import React from 'react'
 import ReactDOM from 'react-dom'
 import { Provider } from 'react-redux'
+import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'
+import indigo from '@material-ui/core/colors/indigo'
+import lightBlue from '@material-ui/core/colors/lightBlue'
+import { DragDropContextProvider } from 'react-dnd'
+import HTML5Backend from 'react-dnd-html5-backend'
+
+const theme = createMuiTheme({
+  typography: {
+    useNextVariants: true
+  },
+  palette: {
+    primary: {
+      main: indigo[700]
+    },
+    secondary: {
+      main: lightBlue[600]
+    }
+  }
+})
 
 const render = () => {
   const App = require('./components/App.jsx').default
   const store = require('./store/store.js').default
+
   ReactDOM.render(
     <Provider store = { store }>
-      <App />
+      <MuiThemeProvider theme={ theme }>
+        <DragDropContextProvider backend={HTML5Backend}>
+          <App />
+        </DragDropContextProvider>
+      </MuiThemeProvider>
     </Provider>,
     document.getElementById('app')
   )
diff --git a/openbis_ng_ui/src/services/openbis/dto.js b/openbis_ng_ui/src/services/openbis/dto.js
index 5ee496bf9a2341cb39d58e3a52d5e023f83998dc..267f7e28cf3a6f460bde71c21f7ffaaf493f34b2 100644
--- a/openbis_ng_ui/src/services/openbis/dto.js
+++ b/openbis_ng_ui/src/services/openbis/dto.js
@@ -13,7 +13,15 @@ const CLASS_FULL_NAMES = [
   'as/dto/dataset/search/DataSetTypeSearchCriteria',
   'as/dto/dataset/fetchoptions/DataSetTypeFetchOptions',
   'as/dto/material/search/MaterialTypeSearchCriteria',
-  'as/dto/material/fetchoptions/MaterialTypeFetchOptions'
+  'as/dto/material/fetchoptions/MaterialTypeFetchOptions',
+  'as/dto/property/PropertyType',
+  'as/dto/property/search/PropertyTypeSearchCriteria',
+  'as/dto/property/fetchoptions/PropertyTypeFetchOptions',
+  'as/dto/property/fetchoptions/PropertyTypeFetchOptions',
+  'as/dto/material/fetchoptions/MaterialFetchOptions',
+  'as/dto/material/search/MaterialSearchCriteria',
+  'as/dto/vocabulary/search/VocabularyTermSearchCriteria',
+  'as/dto/vocabulary/fetchoptions/VocabularyTermFetchOptions'
 ]
 
 class Dto {
diff --git a/openbis_ng_ui/src/services/openbis/facade.js b/openbis_ng_ui/src/services/openbis/facade.js
index b9b6dea6b78f8d391f7d99a5d1b77772fdd0ae24..2a8835d79ebbccffc992122eefbeb7413116dde0 100644
--- a/openbis_ng_ui/src/services/openbis/facade.js
+++ b/openbis_ng_ui/src/services/openbis/facade.js
@@ -32,6 +32,18 @@ export class Facade {
     return this.v3.logout()
   }
 
+  searchPropertyTypes(criteria, fo) {
+    return this.v3.searchPropertyTypes(criteria, fo)
+  }
+
+  searchMaterials(criteria, fo) {
+    return this.v3.searchMaterials(criteria, fo)
+  }
+
+  searchVocabularyTerms(criteria, fo) {
+    return this.v3.searchVocabularyTerms(criteria, fo)
+  }
+
   searchPersons(criteria, fo) {
     return this.v3.searchPersons(criteria, fo)
   }
diff --git a/openbis_ng_ui/src/store/sagas/api.js b/openbis_ng_ui/src/store/sagas/api.js
index 740f0eafa6d2af8714957f326db0d3f61538b599..e1cf527237829b6ddf414723d084599bc5e9530f 100644
--- a/openbis_ng_ui/src/store/sagas/api.js
+++ b/openbis_ng_ui/src/store/sagas/api.js
@@ -2,7 +2,7 @@ import {put, takeEvery, apply} from 'redux-saga/effects'
 import {facade} from '../../services/openbis.js'
 import * as actions from '../actions/actions.js'
 
-export default function* api() {
+export default function* apiSaga() {
   yield takeEvery(actions.API_REQUEST, apiRequest)
 }
 
diff --git a/openbis_ng_ui/src/store/sagas/app.js b/openbis_ng_ui/src/store/sagas/app.js
index 2a2fd8d6a289ee1c51121ea811374f39e955031b..403c23364335ced855d6bb8fd61140d5798d0af4 100644
--- a/openbis_ng_ui/src/store/sagas/app.js
+++ b/openbis_ng_ui/src/store/sagas/app.js
@@ -3,7 +3,7 @@ import {facade, dto} from '../../services/openbis.js'
 import * as actions from '../actions/actions.js'
 import * as pages from '../consts/pages.js'
 
-export default function* app() {
+export default function* appSaga() {
   yield takeEvery(actions.INIT, init)
   yield takeEvery(actions.LOGIN, login)
   yield takeEvery(actions.LOGOUT, logout)
diff --git a/openbis_ng_ui/src/store/sagas/browser/browser.js b/openbis_ng_ui/src/store/sagas/browser/browser.js
index 2eb63d0f3e95ecad7d28711a9a268673def48c4a..d3ea19032d82197b4425b4e19e0b03a0b129ae17 100644
--- a/openbis_ng_ui/src/store/sagas/browser/browser.js
+++ b/openbis_ng_ui/src/store/sagas/browser/browser.js
@@ -9,7 +9,7 @@ import * as common from '../../common/browser.js'
 import * as typesBrowser from './types.js'
 import * as usersBrowser from './users.js'
 
-export default function* browser() {
+export default function* browserSaga() {
   yield takeEvery(actions.BROWSER_INIT, browserInit)
   yield takeEvery(actions.BROWSER_FILTER_CHANGE, browserFilterChange)
   yield takeEvery(actions.BROWSER_NODE_SELECT, browserNodeSelect)
diff --git a/openbis_ng_ui/src/store/sagas/page.js b/openbis_ng_ui/src/store/sagas/page.js
index 84adbb5bfb54c4de153ebdde78d9900bd4aeeb75..077baaf59ce6b594ff2ed4e68044648e52dad7e3 100644
--- a/openbis_ng_ui/src/store/sagas/page.js
+++ b/openbis_ng_ui/src/store/sagas/page.js
@@ -3,7 +3,7 @@ import {put, takeEvery, select} from './effects.js'
 import * as selectors from '../selectors/selectors.js'
 import * as actions from '../actions/actions.js'
 
-export default function* page() {
+export default function* pageSaga() {
   yield takeEvery(actions.OBJECT_OPEN, objectOpen)
   yield takeEvery(actions.OBJECT_CLOSE, objectClose)
 }
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls
index d2ae7662654a57f6627a082aa8eb4dd34a0a638b..4f7df8b3e574065cf52a9206ab597a6e482b551f 100644
Binary files a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls and b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls differ
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls
index 1d69074cea8ec3a8fc903145491b0ab2902c2d44..9c50fc22e3a579c1c140b0fec647dff01636c211 100644
Binary files a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls and b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls differ
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js
index 6b335612f2cbaba8d21c781a14667f7fe2cdbb29..c916ea2ac26f01142334cbb22f64536a287204ab 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js
@@ -281,14 +281,18 @@ $.extend(DefaultProfile.prototype, {
 		
 		this.getStorageConfigCollectionForConfigSample = function(sample) {
 			var prefix = this.getSampleConfigSpacePrefix(sample);
-			return IdentifierUtil.getExperimentIdentifier(prefix + "ELN_SETTINGS", prefix + "STORAGES", prefix + "STORAGES_COLLECTION");
+			return IdentifierUtil.getExperimentIdentifier(prefix + "ELN_SETTINGS", "STORAGES", "STORAGES_COLLECTION");
 		}
 		
 		this.getStorageSpaceForSample = function(sample) {
+			return this.getStorageSpaceForSpace(sample.spaceCode);
+		}
+		
+		this.getStorageSpaceForSpace = function(spaceCode) {
 			var storageSpaceCode = null;
-			var prefixIndexOf = sample.spaceCode.indexOf("_"); // This is a euristic that only works if the prefixes can't contain "_"
+			var prefixIndexOf = spaceCode.indexOf("_"); // This is a euristic that only works if the prefixes can't contain "_"
 			if(prefixIndexOf !== -1) {
-				var prefix = sample.spaceCode.substring(0, prefixIndexOf);
+				var prefix = spaceCode.substring(0, prefixIndexOf);
 				for(var ssIdx = 0; ssIdx < this.storageSpaces.length; ssIdx++) {
 					if(this.storageSpaces[ssIdx].startsWith(prefix)) {
 						storageSpaceCode = this.storageSpaces[ssIdx];
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
index bd6a377e9d0a6ad004ad133e75c57b232bd3b8bd..8841a7bf04bc1c2f50a6cf32391e004d6d4ef8bb 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
@@ -1,744 +1,753 @@
 function FlowCytometryTechnology() {
-	this.init();
+    this.init();
 }
 
 $.extend(FlowCytometryTechnology.prototype, ELNLIMSPlugin.prototype, {
-	init: function () {
-
-		// Store a reference to the "retrieve FCS events" service
-		this.retrieveFCSEventsService = null;
-
-		// Data cache
-		this.dataCache = {};
-	},
-	forcedDisableRTF: [],
-	forceMonospaceFont: [],
-	sampleTypeDefinitionsExtension: {
-		"FACS_ARIA_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"INFLUX_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"LSR_FORTESSA_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"MOFLO_XDP_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"S3E_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"FACS_ARIA_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"FACS_ARIA_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"FACS_ARIA_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_PLATE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_WELL": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		}
-	},
-	dataSetTypeDefinitionsExtension: {
-		"FACS_ARIA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"INFLUX_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"LSR_FORTESSA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"MOFLO_XDP_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"S3E_ARIA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		}
-	},
-	sampleFormTop: function ($container, model) {
-
-	},
-	sampleFormBottom: function ($container, model) {
-
-	},
-	dataSetFormTop: function ($container, model) {
-
-		// Render the paremeter options
-		this.renderParameterSelectionWidget($container, model);
-
-		// Add a div for reporting status
-		$container.append($('<div>')
-			.css("margin-bottom", "5px")
-			.attr("id", "status_div"));
-
-		// Append the div where the data will be plotted
-		$container.append($('<div>')
-			.css("width", "580px")
-			.attr("id", "plot_canvas_div"));
-
-	},
-	dataSetFormBottom: function ($container, model) {
-
-	},
-
-	// Additional functionality
-	renderParameterSelectionWidget: function ($container, model) {
-
-		// Check that we ave the correct dataset type
-		if (!model.dataSetV3.type.code.endsWith("_FCSFILE")) {
-			return;
-		}
-
-		// Clear the container
-		$container.empty();
-
-		//
-		// Retrieve the parameter info
-		//
-		var parameterInfo = this.retrieveParameterInfo(model);
-
-		// Add legend
-		var legend = $("<legend>")
-			.text("Data viewer")
-		$container.append(legend);
-
-		// Create a div for all plotting options
-		var plot_params_div = $('<div>')
-			.css("text-align", "left")
-			.css("margin", "5px 0 15px 0")
-			.attr("id", "plot_params_div");
-
-		//
-		// Lay out the widget
-		//
-
-		// Create a form for the plot parameters
-		var form = $("<form>")
-			.attr("id", "parameter_form");
-		plot_params_div.append(form);
-
-		// Create divs to spatially organize the groups of parameters
-		var xAxisDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "xAxisDiv")
-		var yAxisDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "yAxisDiv")
-		var eventsDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "eventsDiv")
-		var plotDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("vertical-align", "top")
-			.css("padding-left", "10px")
-			.attr("id", "plotDiv")
-
-		// Add them to the form
-		form.append(xAxisDiv);
-		form.append(yAxisDiv);
-		form.append(eventsDiv);
-		form.append(plotDiv);
-
-		// X axis parameters
-		xAxisDiv.append($("<label>")
-			.attr("for", "parameter_form_select_X_axis")
-			.html("X axis"));
-		var selectXAxis = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_X_axis");
-		xAxisDiv.append(selectXAxis);
-
-		// Y axis parameters
-		yAxisDiv.append($("<label>")
-			.attr("for", "parameter_form_select_Y_axis")
-			.html("Y axis"));
-		var selectYAxis = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_Y_axis");
-		yAxisDiv.append(selectYAxis);
-
-		// Add all options
-		for (var i = 0; i < parameterInfo.numParameters; i++) {
-			var name = parameterInfo["names"][i];
-			var compositeName = parameterInfo["compositeNames"][i];
-			selectXAxis.append($("<option>")
-				.attr("value", name)
-				.text(compositeName));
-			selectYAxis.append($("<option>")
-				.attr("value", name)
-				.text(compositeName));
-		}
-
-		// // Pre-select some parameters
-		selectXAxis.val(parameterInfo["names"][0]);
-		selectYAxis.val(parameterInfo["names"][1]);
-
-		// Add a selector with the number of events to plot
-		eventsDiv.append($("<label>")
-			.attr("for", "parameter_form_select_num_events")
-			.html("Events to plot"));
-		var selectNumEvents = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_num_events");
-		eventsDiv.append(selectNumEvents);
-
-		// Add the options
-		var possibleOptions = [500, 1000, 2500, 5000, 10000, 20000, 50000, 100000];
-		var numEventsInFile = parseInt(parameterInfo.numEvents);
-		for (var i = 0; i < possibleOptions.length; i++) {
-			if (possibleOptions[i] < numEventsInFile) {
-				selectNumEvents.append($("<option>")
-					.attr("value", possibleOptions[i])
-					.text(possibleOptions[i].toString()));
-			}
-		}
-		selectNumEvents.append($("<option>")
-			.attr("value", parameterInfo.numEvents)
-			.text(parseInt(parameterInfo.numEvents)));
-
-		// Pre-select something reasonable
-		if (parameterInfo.numEvents > possibleOptions[4]) {
-			selectNumEvents.val(parseInt(possibleOptions[4]));
-		} else {
-			selectNumEvents.val(parseInt(parameterInfo.numEvents));
-		}
-
-		// Add "Plot" button
-		var thisObj = this;
-		var plotButton = $("<input>")
-			.attr("type", "button")
-			.attr("value", "Plot")
-			.click(function () {
-
-				// Get the selected parameters and their display scaling
-				var paramX = selectXAxis.find(":selected").val();
-				var paramY = selectYAxis.find(":selected").val();
-				var displayX = selectScaleX.find(":selected").val();
-				var displayY = selectScaleY.find(":selected").val();
-
-				// How many events to plot?
-				var numEventsToPlot = selectNumEvents.val();
-
-				// Sampling method
-				var samplingMethod = selectSamplingMethod.find(":selected").val();
-
-				// Call the retrieving and plotting method
-				thisObj.callServerSidePluginGenerateFCSPlot(
-					model,
-					paramX,
-					paramY,
-					displayX,
-					displayY,
-					numEventsToPlot,
-					parameterInfo.numEvents,
-					samplingMethod);
-			});
-		plotDiv.append(plotButton);
-
-		// Add a selector with the scaling for axis X
-		var xAxisScalingDiv = xAxisDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "xAxisScalingDiv"));
-		xAxisScalingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_scaleX")
-			.html("Scale for X axis"));
-		var selectScaleX = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_scaleX");
-		xAxisScalingDiv.append(selectScaleX);
-
-		// Add the options
-		possibleOptions = ["Linear", "Hyperlog"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectScaleX.append($("<option>")
-				.attr("name", possibleOptions[i])
-				.attr("value", possibleOptions[i])
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_scaleX").val(0);
-
-		// Add a selector with the scaling for axis Y
-		var yAxisScalingDiv = yAxisDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "yAxisScalingDiv"));
-		yAxisScalingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_scaleY")
-			.html("Scale for Y axis"));
-		var selectScaleY = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_scaleY");
-		yAxisScalingDiv.append(selectScaleY);
-
-		// Add the options
-		possibleOptions = ["Linear", "Hyperlog"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectScaleY.append($("<option>")
-				.attr("name", possibleOptions[i])
-				.attr("value", possibleOptions[i])
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_scaleY").val(0);
-
-		// Add a selector with the sampling method
-		var eventSamplingDiv = eventsDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "eventSamplingDiv"));
-		eventSamplingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_sampling_method")
-			.html("Sampling"));
-		var selectSamplingMethod = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_sampling_method");
-		eventSamplingDiv.append(selectSamplingMethod);
-
-		// Add the options
-		possibleOptions = ["Regular", "First rows"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectSamplingMethod.append($("<option>")
-				.attr("name", "" + (i + 1))
-				.attr("value", (i + 1))
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_sampling_method").val(0);
-
-		//
-		// End of widget
-		//
-
-		// Append the created div to the container
-		$container.append(plot_params_div);
-
-	},
-
-	retrieveParameterInfo: function (model) {
-
-		// Retrieve parameter information
-		var key = model.dataSetV3.type.code.substring(
-			0, model.dataSetV3.type.code.indexOf("_FCSFILE")) +
-			"_FCSFILE_PARAMETERS";
-
-		var parametersXML = $.parseXML(model.dataSetV3.properties[key]);
-		var parameters = parametersXML.childNodes[0];
-
-		var numParameters = parameters.getAttribute("numParameters");
-		var numEvents = parameters.getAttribute("numEvents");
-
-		var names = [];
-		var compositeNames = [];
-		var display = [];
-
-		// Parameter numbering starts at 1
-		var parametersToDisplay = 0;
-		for (var i = 1; i <= numParameters; i++) {
-
-			// If the parameter contains the PnCHANNELTYPE attribute (BD Influx Cell Sorter),
-			// we only add it if the channel type is 6.
-			var channelType = parameters.getAttribute("P" + i + "CHANNELTYPE");
-			if (channelType != null && channelType !== 6) {
-				continue;
-			}
-
-			// Store the parameter name
-			var name = parameters.getAttribute("P" + i + "N");
-			names.push(name);
-
-			// Store the composite name
-			var pStr = parameters.getAttribute("P" + i + "S");
-			var composite = name;
-			if (pStr !== "") {
-				composite = name + " (" + pStr + ")";
-			}
-			compositeNames.push(composite);
-
-			// Store the display scale
-			var displ = parameters.getAttribute("P" + i + "DISPLAY");
-			display.push(displ);
-
-			// Update the count of parameters to display
-			parametersToDisplay++;
-		}
-
-		// Store the parameter info
-		parameterInfo = {
-			"numParameters": parametersToDisplay,
-			"numEvents": numEvents,
-			"names": names,
-			"compositeNames": compositeNames,
-			"display": display
-		}
-
-		// Return it
-		return parameterInfo;
-	},
-
-	callServerSidePluginGenerateFCSPlot: function (model, paramX, paramY, displayX, displayY, numEventsToPlot, totalNumEvents, samplingMethod) {
-
-		// Check whether the data for the plot is already cached
-		var key = model.dataSetV3.code + "_" + paramX + "_" + paramY + "_" + numEventsToPlot.toString() +
-			"_" + displayX + "_" + displayY + "_" + samplingMethod.toString();
-
-		if (model.dataSetV3.code in this.dataCache &&
-			key in this.dataCache[model.dataSetV3.code]) {
-
-			// Plot the cached data
-			this.plotFCSData(
-				this.dataCache[model.dataSetV3.code][key],
-				paramX,
-				paramY,
-				displayX,
-				displayY);
-
-			// Return immediately
-			return;
-		}
-
-		// Inform the user that we are about to process the request
-		this.displayStatus("Please wait while processing your request. This might take a while...",
-			"info");
-	
-		var thisObj = this;
-		require(["openbis",
-			"as/dto/service/search/AggregationServiceSearchCriteria",
-			"as/dto/service/fetchoptions/AggregationServiceFetchOptions",
-			"as/dto/service/execute/AggregationServiceExecutionOptions"],
-			function (openbis,
-				AggregationServiceSearchCriteria,
-				AggregationServiceFetchOptions,
-				AggregationServiceExecutionOptions) {
-
-				// Parameters for the aggregation service
-				var options = new AggregationServiceExecutionOptions();
-				options.withParameter("code", model.dataSetV3.code);
-				options.withParameter("paramX", paramX);
-				options.withParameter("paramY", paramY);
-				options.withParameter("displayX", displayX);
-				options.withParameter("displayY", displayY);
-				options.withParameter("numEvents", totalNumEvents);
-				options.withParameter("maxNumEvents", numEventsToPlot);
-				options.withParameter("samplingMethod", samplingMethod);
-				options.withParameter("nodeKey", model.dataSetV3.code);
-
-				// Call service
-				if (null === thisObj.retrieveFCSEventsService) {
-					var criteria = new AggregationServiceSearchCriteria();
-					criteria.withName().thatEquals("retrieve_fcs_events");
-					var fetchOptions = new AggregationServiceFetchOptions();
-					mainController.openbisV3.searchAggregationServices(criteria, fetchOptions).then(function (result) {
-
-						// Check that we got our service
-						if (undefined === result.objects) {
-							console.log("Could not retrieve the server-side aggregation service!");
-							return;
-						}
-						thisObj.retrieveFCSEventsService = result.getObjects()[0];
-
-						// Now call the service
-						mainController.openbisV3.executeAggregationService(
-							thisObj.retrieveFCSEventsService.getPermId(),
-							options).then(function (result) {
-								thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-							});
-					});
-				} else {
-					// Call the service
-					mainController.openbisV3.executeAggregationService(
-						thisObj.retrieveFCSEventsService.getPermId(),
-						options).then(function (result) {
-							thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-						});
-				}
-			});
-	},
-
-	plotFCSData: function (data, xLabel, yLabel, xDisplay, yDisplay) {
-
-		// Make sure to have a proper array
-		var parsed_data = JSON.parse(data);
-
-		// Prepend data names to be compatible with C3.js
-		parsed_data[0].unshift("x_values");
-		parsed_data[1].unshift("y_values");
-
-		// Plot the data
-		c3.generate({
-			bindto: '#plot_canvas_div',
-			title: {
-				text: yLabel + " vs. " + xLabel
-			},
-			data: {
-				xs: {
-					y_values: "x_values"
-				},
-				columns: [
-					parsed_data[0],
-					parsed_data[1],
-				],
-				names: {
-					y_values: yLabel
-				},
-				type: 'scatter'
-			},
-			axis: {
-				x: {
-					label: xLabel,
-					tick: {
-						fit: false
-					}
-				},
-				y: {
-					label: yLabel,
-					tick: {
-						fit: false
-					}
-				}
-			},
-			legend: {
-				show: false
-			},
-			tooltip: {
-				format: {
-					title: function (d) {
-						const format = d3.format(',');
-						return xLabel + " | " + format(d);
-					},
-					value: function (value, ratio, id) {
-						const format = d3.format(',');
-						return format(value);
-					}
-				}
-			},
-			zoom: {
-				enabled: true,
-				rescale: true
-			},
-		});
-	},
-
-	processResultsFromRetrieveFCSEventsServerSidePlugin: function (table) {
-
-		// Did we get the expected result?
-		if (!table.rows || table.rows.length !== 1) {
-			DATAVIEWER.displayStatus(
-				"There was an error retrieving the data to plot!",
-				"danger");
-			return;
-		}
-
-		// Get the row of results
-		var row = table.rows[0];
-
-		// Retrieve the uid
-		var r_UID = row[0].value;
-
-		// Is the process completed?
-		var r_Completed = row[1].value;
-
-		var thisObj = this;
-		if (r_Completed === 0) {
-
-			require(["as/dto/service/execute/AggregationServiceExecutionOptions"],
-				function (AggregationServiceExecutionOptions) {
-
-					// Call the plug-in
-					setTimeout(function () {
-
-						// Now call the service again:
-						// we only need the UID of the job
-						var options = new AggregationServiceExecutionOptions();
-						options.withParameter("uid", r_UID);
-
-						mainController.openbisV3.executeAggregationService(
-							thisObj.retrieveFCSEventsService.getPermId(),
-							options).then(function (result) {
-								thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-							})
-					}, 2000);
-				});
-
-			// Return here
-			return;
-
-		}
-
-		// We completed the call and we can process the result
-
-		// Returned parameters
-		var r_Success = row[2].value;
-		var r_ErrorMessage = row[3].value;
-		var r_Data = row[4].value;
-		var r_Code = row[5].value;
-		var r_ParamX = row[6].value;
-		var r_ParamY = row[7].value;
-		var r_DisplayX = row[8].value;
-		var r_DisplayY = row[9].value;
-		var r_NumEvents = row[10].value;   // Currently not used
-		var r_MaxNumEvents = row[11].value;
-		var r_SamplingMethod = row[12].value;
-		var r_NodeKey = row[13].value;
-
-		var level;
-		if (r_Success === 1) {
-
-			// Error message and level
-			status = r_ErrorMessage;
-			level = "success";
-
-			// Plot the data
-			thisObj.plotFCSData(r_Data, r_ParamX, r_ParamY, r_DisplayX, r_DisplayY);
-
-			// Cache the plotted data
-			var dataKey = r_Code + "_" + r_ParamX + "_" + r_ParamY + "_" + r_MaxNumEvents.toString() +
-				"_" + r_DisplayX + "_" + r_DisplayY + "_" + r_SamplingMethod.toString();
-			thisObj.cacheFCSData(r_NodeKey, dataKey, r_Data);
-
-		} else {
-			status = "Sorry, there was an error: \"" + r_ErrorMessage + "\".";
-			level = "danger";
-		}
-
-		// We only display errors
-		if (r_Success === 0) {
-			thisObj.displayStatus(status, level);
-		} else {
-			thisObj.hideStatus();
-		}
-
-		return table;
-
-	},
-
-	cacheFCSData: function (nodeKey, dataKey, fcsData) {
-
-		// Cache the data
-		if (! (nodeKey in this.dataCache)) {
-			this.dataCache[nodeKey] = {};
-		}
-		this.dataCache[nodeKey][dataKey] = fcsData;
-	},
-
-	displayStatus: function(status, level) {
-		switch (level) {
-			case "info":
-				color = "black";
-				break;
-			case "success":
-				color = "cyan";
-				break;
-			case "danger":
-				color = "red";
-				break;
-			default:
-				color = "black";
-				break;
-		}
-		var status_div = $("#status_div");
-		status_div
-			.css("color", color)
-			.text(status);
-		status_div.show();
-	},
-
-	hideStatus: function() {
-		$("#status_div").hide();
-	}
+    init: function () {
+
+        // Store a reference to the "retrieve FCS events" service
+        this.retrieveFCSEventsService = null;
+
+        // Data cache
+        this.dataCache = {};
+    },
+    forcedDisableRTF: [],
+    forceMonospaceFont: [],
+    sampleTypeDefinitionsExtension: {
+        "FACS_ARIA_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_CHILDREN_DISABLED": true,
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "INFLUX_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_CHILDREN_DISABLED": true,
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "LSR_FORTESSA_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_CHILDREN_DISABLED": true,
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "MOFLO_XDP_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_CHILDREN_DISABLED": true,
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "S3E_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_CHILDREN_DISABLED": true,
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "FACS_ARIA_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "FACS_ARIA_TUBE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "FACS_ARIA_TUBESET": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_TUBE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_TUBESET": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_PLATE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_TUBE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_TUBESET": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_WELL": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_TUBE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_TUBESET": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_TUBE": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_TUBESET": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        }
+    },
+    dataSetTypeDefinitionsExtension: {
+        "FACS_ARIA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "INFLUX_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "LSR_FORTESSA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "MOFLO_XDP_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "S3E_ARIA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        }
+    },
+    sampleFormTop: function ($container, model) {
+
+    },
+    sampleFormBottom: function ($container, model) {
+
+    },
+    dataSetFormTop: function ($container, model) {
+
+        // Render the paremeter options
+        this.renderParameterSelectionWidget($container, model);
+
+        // Add a div for reporting status
+        $container.append($('<div>')
+            .css("margin-bottom", "5px")
+            .attr("id", "status_div"));
+
+        // Append the div where the data will be plotted
+        $container.append($('<div>')
+            .css("width", "580px")
+            .attr("id", "plot_canvas_div"));
+
+    },
+    dataSetFormBottom: function ($container, model) {
+
+    },
+
+    // Additional functionality
+    renderParameterSelectionWidget: function ($container, model) {
+
+        // Check that we ave the correct dataset type
+        if (!model.dataSetV3) {
+            return;
+        }
+
+        if (!model.dataSetV3.type.code.endsWith("_FCSFILE")) {
+            return;
+        }
+
+        // Clear the container
+        $container.empty();
+
+        //
+        // Retrieve the parameter info
+        //
+        var parameterInfo = this.retrieveParameterInfo(model);
+
+        // Add legend
+        var legend = $("<legend>")
+            .text("Data viewer");
+        $container.append(legend);
+
+        // Create a div for all plotting options
+        var plot_params_div = $('<div>')
+            .css("text-align", "left")
+            .css("margin", "5px 0 15px 0")
+            .attr("id", "plot_params_div");
+
+        //
+        // Lay out the widget
+        //
+
+        // Create a form for the plot parameters
+        var form = $("<form>")
+            .attr("id", "parameter_form");
+        plot_params_div.append(form);
+
+        // Create divs to spatially organize the groups of parameters
+        var xAxisDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "xAxisDiv");
+        var yAxisDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "yAxisDiv");
+        var eventsDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "eventsDiv");
+        var plotDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("vertical-align", "top")
+            .css("padding-left", "10px")
+            .attr("id", "plotDiv");
+
+        // Add them to the form
+        form.append(xAxisDiv);
+        form.append(yAxisDiv);
+        form.append(eventsDiv);
+        form.append(plotDiv);
+
+        // X axis parameters
+        xAxisDiv.append($("<label>")
+            .attr("for", "parameter_form_select_X_axis")
+            .html("X axis"));
+        var selectXAxis = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_X_axis");
+        xAxisDiv.append(selectXAxis);
+
+        // Y axis parameters
+        yAxisDiv.append($("<label>")
+            .attr("for", "parameter_form_select_Y_axis")
+            .html("Y axis"));
+        var selectYAxis = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_Y_axis");
+        yAxisDiv.append(selectYAxis);
+
+        // Add all options
+        for (var i = 0; i < parameterInfo.numParameters; i++) {
+            var name = parameterInfo["names"][i];
+            var compositeName = parameterInfo["compositeNames"][i];
+            selectXAxis.append($("<option>")
+                .attr("value", name)
+                .text(compositeName));
+            selectYAxis.append($("<option>")
+                .attr("value", name)
+                .text(compositeName));
+        }
+
+        // // Pre-select some parameters
+        selectXAxis.val(parameterInfo["names"][0]);
+        selectYAxis.val(parameterInfo["names"][1]);
+
+        // Add a selector with the number of events to plot
+        eventsDiv.append($("<label>")
+            .attr("for", "parameter_form_select_num_events")
+            .html("Events to plot"));
+        var selectNumEvents = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_num_events");
+        eventsDiv.append(selectNumEvents);
+
+        // Add the options
+        var possibleOptions = [500, 1000, 2500, 5000, 10000, 20000, 50000, 100000];
+        var numEventsInFile = parseInt(parameterInfo.numEvents);
+        for (i = 0; i < possibleOptions.length; i++) {
+            if (possibleOptions[i] < numEventsInFile) {
+                selectNumEvents.append($("<option>")
+                    .attr("value", possibleOptions[i])
+                    .text(possibleOptions[i].toString()));
+            }
+        }
+        selectNumEvents.append($("<option>")
+            .attr("value", parameterInfo.numEvents)
+            .text(parseInt(parameterInfo.numEvents)));
+
+        // Pre-select something reasonable
+        if (parameterInfo.numEvents > possibleOptions[4]) {
+            selectNumEvents.val(possibleOptions[4]);
+        } else {
+            selectNumEvents.val(parameterInfo.numEvents);
+        }
+
+        // Add "Plot" button
+        var thisObj = this;
+        var plotButton = $("<input>")
+            .attr("type", "button")
+            .attr("value", "Plot")
+            .click(function () {
+
+                // Get the selected parameters and their display scaling
+                var paramX = selectXAxis.find(":selected").val();
+                var paramY = selectYAxis.find(":selected").val();
+                var displayX = selectScaleX.find(":selected").val();
+                var displayY = selectScaleY.find(":selected").val();
+
+                // How many events to plot?
+                var numEventsToPlot = selectNumEvents.val();
+
+                // Sampling method
+                var samplingMethod = selectSamplingMethod.find(":selected").val();
+
+                // Call the retrieving and plotting method
+                thisObj.callServerSidePluginGenerateFCSPlot(
+                    model,
+                    paramX,
+                    paramY,
+                    displayX,
+                    displayY,
+                    numEventsToPlot,
+                    parameterInfo.numEvents,
+                    samplingMethod);
+            });
+        plotDiv.append(plotButton);
+
+        // Add a selector with the scaling for axis X
+        var xAxisScalingDiv = xAxisDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "xAxisScalingDiv"));
+        xAxisScalingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_scaleX")
+            .html("Scale for X axis"));
+        var selectScaleX = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_scaleX");
+        xAxisScalingDiv.append(selectScaleX);
+
+        // Add the options
+        possibleOptions = ["Linear", "Hyperlog"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectScaleX.append($("<option>")
+                .attr("name", possibleOptions[i])
+                .attr("value", possibleOptions[i])
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_scaleX").val(0);
+
+        // Add a selector with the scaling for axis Y
+        var yAxisScalingDiv = yAxisDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "yAxisScalingDiv"));
+        yAxisScalingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_scaleY")
+            .html("Scale for Y axis"));
+        var selectScaleY = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_scaleY");
+        yAxisScalingDiv.append(selectScaleY);
+
+        // Add the options
+        possibleOptions = ["Linear", "Hyperlog"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectScaleY.append($("<option>")
+                .attr("name", possibleOptions[i])
+                .attr("value", possibleOptions[i])
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_scaleY").val(0);
+
+        // Add a selector with the sampling method
+        var eventSamplingDiv = eventsDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "eventSamplingDiv"));
+        eventSamplingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_sampling_method")
+            .html("Sampling"));
+        var selectSamplingMethod = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_sampling_method");
+        eventSamplingDiv.append(selectSamplingMethod);
+
+        // Add the options
+        possibleOptions = ["Regular", "First rows"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectSamplingMethod.append($("<option>")
+                .attr("name", "" + (i + 1))
+                .attr("value", (i + 1))
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_sampling_method").val(0);
+
+        //
+        // End of widget
+        //
+
+        // Append the created div to the container
+        $container.append(plot_params_div);
+
+    },
+
+    retrieveParameterInfo: function (model) {
+
+        // Retrieve parameter information
+        var key = model.dataSetV3.type.code.substring(
+            0, model.dataSetV3.type.code.indexOf("_FCSFILE")) +
+            "_FCSFILE_PARAMETERS";
+
+        var parametersXML = $.parseXML(model.dataSetV3.properties[key]);
+        var parameters = parametersXML.childNodes[0];
+
+        var numParameters = parameters.getAttribute("numParameters");
+        var numEvents = parameters.getAttribute("numEvents");
+
+        var names = [];
+        var compositeNames = [];
+        var display = [];
+
+        // Parameter numbering starts at 1
+        var parametersToDisplay = 0;
+        for (var i = 1; i <= numParameters; i++) {
+
+            // If the parameter contains the PnCHANNELTYPE attribute (BD Influx Cell Sorter),
+            // we only add it if the channel type is 6.
+            var channelType = parameters.getAttribute("P" + i + "CHANNELTYPE");
+            if (channelType != null && channelType !== 6) {
+                continue;
+            }
+
+            // Store the parameter name
+            var name = parameters.getAttribute("P" + i + "N");
+            names.push(name);
+
+            // Store the composite name
+            var pStr = parameters.getAttribute("P" + i + "S");
+            var composite = name;
+            if (pStr !== "") {
+                composite = name + " (" + pStr + ")";
+            }
+            compositeNames.push(composite);
+
+            // Store the display scale
+            var displ = parameters.getAttribute("P" + i + "DISPLAY");
+            display.push(displ);
+
+            // Update the count of parameters to display
+            parametersToDisplay++;
+        }
+
+        // Store the parameter info
+        parameterInfo = {
+            "numParameters": parametersToDisplay,
+            "numEvents": numEvents,
+            "names": names,
+            "compositeNames": compositeNames,
+            "display": display
+        };
+
+        // Return it
+        return parameterInfo;
+    },
+
+    callServerSidePluginGenerateFCSPlot: function (model, paramX, paramY, displayX, displayY, numEventsToPlot, totalNumEvents, samplingMethod) {
+
+        // Check whether the data for the plot is already cached
+        var key = model.dataSetV3.code + "_" + paramX + "_" + paramY + "_" + numEventsToPlot.toString() +
+            "_" + displayX + "_" + displayY + "_" + samplingMethod.toString();
+
+        if (model.dataSetV3.code in this.dataCache &&
+            key in this.dataCache[model.dataSetV3.code]) {
+
+            // Plot the cached data
+            this.plotFCSData(
+                this.dataCache[model.dataSetV3.code][key],
+                paramX,
+                paramY,
+                displayX,
+                displayY);
+
+            // Return immediately
+            return;
+        }
+
+        // Inform the user that we are about to process the request
+        this.displayStatus("Please wait while processing your request. This might take a while...",
+            "info");
+
+        var thisObj = this;
+        require(["openbis",
+                "as/dto/service/search/AggregationServiceSearchCriteria",
+                "as/dto/service/fetchoptions/AggregationServiceFetchOptions",
+                "as/dto/service/execute/AggregationServiceExecutionOptions"],
+            function (openbis,
+                      AggregationServiceSearchCriteria,
+                      AggregationServiceFetchOptions,
+                      AggregationServiceExecutionOptions) {
+
+                // Parameters for the aggregation service
+                var options = new AggregationServiceExecutionOptions();
+                options.withParameter("code", model.dataSetV3.code);
+                options.withParameter("paramX", paramX);
+                options.withParameter("paramY", paramY);
+                options.withParameter("displayX", displayX);
+                options.withParameter("displayY", displayY);
+                options.withParameter("numEvents", totalNumEvents);
+                options.withParameter("maxNumEvents", numEventsToPlot);
+                options.withParameter("samplingMethod", samplingMethod);
+                options.withParameter("nodeKey", model.dataSetV3.code);
+
+                // Call service
+                if (null === thisObj.retrieveFCSEventsService) {
+                    var criteria = new AggregationServiceSearchCriteria();
+                    criteria.withName().thatEquals("retrieve_fcs_events");
+                    var fetchOptions = new AggregationServiceFetchOptions();
+                    mainController.openbisV3.searchAggregationServices(criteria, fetchOptions).then(function (result) {
+
+                        // Check that we got our service
+                        if (undefined === result.objects) {
+                            console.log("Could not retrieve the server-side aggregation service!");
+                            return;
+                        }
+                        thisObj.retrieveFCSEventsService = result.getObjects()[0];
+
+                        // Now call the service
+                        mainController.openbisV3.executeAggregationService(
+                            thisObj.retrieveFCSEventsService.getPermId(),
+                            options).then(function (result) {
+                            thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                        });
+                    });
+                } else {
+                    // Call the service
+                    mainController.openbisV3.executeAggregationService(
+                        thisObj.retrieveFCSEventsService.getPermId(),
+                        options).then(function (result) {
+                        thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                    });
+                }
+            });
+    },
+
+    plotFCSData: function (data, xLabel, yLabel, xDisplay, yDisplay) {
+
+        // Make sure to have a proper array
+        var parsed_data = JSON.parse(data);
+
+        // Prepend data names to be compatible with C3.js
+        parsed_data[0].unshift("x_values");
+        parsed_data[1].unshift("y_values");
+
+        // Plot the data
+        c3.generate({
+            bindto: '#plot_canvas_div',
+            title: {
+                text: yLabel + " vs. " + xLabel
+            },
+            data: {
+                xs: {
+                    y_values: "x_values"
+                },
+                columns: [
+                    parsed_data[0],
+                    parsed_data[1],
+                ],
+                names: {
+                    y_values: yLabel
+                },
+                type: 'scatter'
+            },
+            axis: {
+                x: {
+                    label: xLabel,
+                    tick: {
+                        fit: false
+                    }
+                },
+                y: {
+                    label: yLabel,
+                    tick: {
+                        fit: false
+                    }
+                }
+            },
+            legend: {
+                show: false
+            },
+            tooltip: {
+                format: {
+                    title: function (d) {
+                        const format = d3.format(',');
+                        return xLabel + " | " + format(d);
+                    },
+                    value: function (value, ratio, id) {
+                        const format = d3.format(',');
+                        return format(value);
+                    }
+                }
+            },
+            zoom: {
+                enabled: true,
+                rescale: true
+            },
+        });
+    },
+
+    processResultsFromRetrieveFCSEventsServerSidePlugin: function (table) {
+
+        // Did we get the expected result?
+        if (!table.rows || table.rows.length !== 1) {
+            DATAVIEWER.displayStatus(
+                "There was an error retrieving the data to plot!",
+                "danger");
+            return;
+        }
+
+        // Get the row of results
+        var row = table.rows[0];
+
+        // Retrieve the uid
+        var r_UID = row[0].value;
+
+        // Is the process completed?
+        var r_Completed = row[1].value;
+
+        var thisObj = this;
+        if (r_Completed === 0) {
+
+            require(["as/dto/service/execute/AggregationServiceExecutionOptions"],
+                function (AggregationServiceExecutionOptions) {
+
+                    // Call the plug-in
+                    setTimeout(function () {
+
+                        // Now call the service again:
+                        // we only need the UID of the job
+                        var options = new AggregationServiceExecutionOptions();
+                        options.withParameter("uid", r_UID);
+
+                        mainController.openbisV3.executeAggregationService(
+                            thisObj.retrieveFCSEventsService.getPermId(),
+                            options).then(function (result) {
+                            thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                        })
+                    }, 2000);
+                });
+
+            // Return here
+            return;
+
+        }
+
+        // We completed the call and we can process the result
+
+        // Returned parameters
+        var r_Success = row[2].value;
+        var r_ErrorMessage = row[3].value;
+        var r_Data = row[4].value;
+        var r_Code = row[5].value;
+        var r_ParamX = row[6].value;
+        var r_ParamY = row[7].value;
+        var r_DisplayX = row[8].value;
+        var r_DisplayY = row[9].value;
+        var r_NumEvents = row[10].value;   // Currently not used
+        var r_MaxNumEvents = row[11].value;
+        var r_SamplingMethod = row[12].value;
+        var r_NodeKey = row[13].value;
+
+        var level;
+        if (r_Success === 1) {
+
+            // Error message and level
+            status = r_ErrorMessage;
+            level = "success";
+
+            // Plot the data
+            thisObj.plotFCSData(r_Data, r_ParamX, r_ParamY, r_DisplayX, r_DisplayY);
+
+            // Cache the plotted data
+            var dataKey = r_Code + "_" + r_ParamX + "_" + r_ParamY + "_" + r_MaxNumEvents.toString() +
+                "_" + r_DisplayX + "_" + r_DisplayY + "_" + r_SamplingMethod.toString();
+            thisObj.cacheFCSData(r_NodeKey, dataKey, r_Data);
+
+        } else {
+            status = "Sorry, there was an error: \"" + r_ErrorMessage + "\".";
+            level = "danger";
+        }
+
+        // We only display errors
+        if (r_Success === 0) {
+            thisObj.displayStatus(status, level);
+        } else {
+            thisObj.hideStatus();
+        }
+
+        return table;
+
+    },
+
+    cacheFCSData: function (nodeKey, dataKey, fcsData) {
+
+        // Cache the data
+        if (! (nodeKey in this.dataCache)) {
+            this.dataCache[nodeKey] = {};
+        }
+        this.dataCache[nodeKey][dataKey] = fcsData;
+    },
+
+    displayStatus: function(status, level) {
+        switch (level) {
+            case "info":
+                color = "black";
+                break;
+            case "success":
+                color = "cyan";
+                break;
+            case "danger":
+                color = "red";
+                break;
+            default:
+                color = "black";
+                break;
+        }
+        var status_div = $("#status_div");
+        status_div
+            .css("color", color)
+            .text(status);
+        status_div.show();
+    },
+
+    hideStatus: function() {
+        $("#status_div").hide();
+    }
 
 });
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/MicroscopyTechnology.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/MicroscopyTechnology.js
index 5ee6177db2a6e8d3c46c8503a850f9518e1f9b57..4b07aee2df65149b57fda977646e35c66b870295 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/MicroscopyTechnology.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/MicroscopyTechnology.js
@@ -14,14 +14,14 @@ $.extend(MicroscopyTechnology.prototype, ELNLIMSPlugin.prototype, {
             "SHOW": false,
             "SAMPLE_CHILDREN_DISABLED": true,
             "SAMPLE_PARENTS_DISABLED": true,
-            "TOOLBAR": { CREATE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true }
         },
         "MICROSCOPY_EXPERIMENT": {
             "SHOW": false,
             "SAMPLE_CHILDREN_DISABLED": false,
             "SAMPLE_PARENTS_DISABLED": false,
             "SAMPLE_PARENTS_ANY_TYPE_DISABLED": true,
-            "TOOLBAR": { CREATE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "TOOLBAR": { CREATE: false, FREEZE: false, EDIT: true, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
             "SAMPLE_PARENTS_HINT": [{
                 "LABEL": "Organization Units",
                 "TYPE": "ORGANIZATION_UNIT",
@@ -32,23 +32,23 @@ $.extend(MicroscopyTechnology.prototype, ELNLIMSPlugin.prototype, {
     dataSetTypeDefinitionsExtension: {
         "MICROSCOPY_ACCESSORY_FILE": {
             "DATASET_PARENTS_DISABLED": true,
-            "TOOLBAR": { EDIT: true, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
         },
         "MICROSCOPY_IMG": {
             "DATASET_PARENTS_DISABLED": true,
-            "TOOLBAR": { EDIT: true, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
         },
         "MICROSCOPY_IMG_OVERVIEW": {
             "DATASET_PARENTS_DISABLED": true,
-            "TOOLBAR": { EDIT: true, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
         },
         "MICROSCOPY_IMG_THUMBNAIL": {
             "DATASET_PARENTS_DISABLED": true,
-            "TOOLBAR": { EDIT: true, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
         },
         "MICROSCOPY_IMG_CONTAINER": {
             "DATASET_PARENTS_DISABLED": true,
-            "TOOLBAR": { EDIT: true, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+            "TOOLBAR": { EDIT: false, FREEZE: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
         }
     },
     sampleFormTop: function ($container, model) {
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
index fe8f372a87e94a47f903dd9084eefddf56f6b8e0..f31dbf692b92a62b269c7e202040a410627b716e 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/widgets/JupyterNotebookView.js
@@ -23,9 +23,9 @@ function JupyterNotebookView(jupyterNotebookController, jupyterNotebookModel) {
 		$window.append($('<legend>').append("Create Jupyter Notebook"));
 		var $btns = $('<div>', {'id' : 'jnb_buttons'});
 		$window.append($btns);
-		var $btnOpen = $('<div>', { 'class' : 'btn btn-default', 'text' : 'For immediate use', 'id' : 'open_jnb' });
+		var $btnOpen = $('<div>', { 'class' : 'btn btn-default', 'text' : 'Create & connect', 'id' : 'open_jnb' });
 		$btnOpen.click(["open", $window, this], this._handle);
-		var $btnSave = $('<div>', { 'class' : 'btn btn-default', 'text' : 'For later use', 'id' : 'save_jnb' });
+		var $btnSave = $('<div>', { 'class' : 'btn btn-default', 'text' : 'Create & download', 'id' : 'save_jnb' });
 		$btnSave.click(["save", $window, this], this._handle);
 		$btns.append($btnOpen).append('&nbsp;').append($btnSave);
 		var css = {
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ExperimentForm/ExperimentFormView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ExperimentForm/ExperimentFormView.js
index 5c2958f79f05f741f8f035c2ad23d4dbfea8043a..0d9790a711feeaccfa9bd61648ad695740bc6eca 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ExperimentForm/ExperimentFormView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ExperimentForm/ExperimentFormView.js
@@ -428,7 +428,7 @@ function ExperimentFormView(experimentFormController, experimentFormModel) {
 				} else {
 					var $component = null;
 					if(propertyType.code === "$DEFAULT_OBJECT_TYPE") {
-						$component = FormUtil.getSampleTypeDropdown(propertyType.code, true);
+						$component = FormUtil.getSampleTypeDropdown(propertyType.code, false);
 					} else {
 						$component = FormUtil.getFieldForPropertyType(propertyType, value);
 					}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableView.js
index 545f609ec8a5137549834d6a27be8b3b0c4a948a..1980821bbdd7bfca701ad445c43e5ddb025c0269 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleTable/SampleTableView.js
@@ -215,11 +215,13 @@ function SampleTableView(sampleTableController, sampleTableModel) {
 	this.registerSamples = function(experimentIdentifier) {
 		var allowedSampleTypes = null;
 		var forcedSpace = null;
+		var spaceCodeFromIdentifier = null;
 		if(this._sampleTableModel.sampleTypeCodeToUse) {
 			allowedSampleTypes = [this._sampleTableModel.sampleTypeCodeToUse, "STORAGE_POSITION"];
 		}
 		if(experimentIdentifier) {
-			forcedSpace = IdentifierUtil.getForcedSpaceIdentifier(IdentifierUtil.getSpaceCodeFromIdentifier(experimentIdentifier));
+			spaceCodeFromIdentifier = IdentifierUtil.getSpaceCodeFromIdentifier(experimentIdentifier);
+			forcedSpace = IdentifierUtil.getForcedSpaceIdentifier(spaceCodeFromIdentifier);
 		}
 		
 		var typeAndFileController = new TypeAndFileController('Register ' + ELNDictionary.Samples + '', "REGISTRATION", function(type, file) {
@@ -245,7 +247,7 @@ function SampleTableView(sampleTableController, sampleTableModel) {
 					var experimentIdentifierOrDelete = experimentIdentifier;
 					if(experimentIdentifierOrDelete && typeAndFileController.getSampleTypeCode() === "STORAGE_POSITION") {
 						experimentIdentifierOrDelete = "__DELETE__";
-						forcedSpace = IdentifierUtil.getForcedSpaceIdentifier("STORAGE");
+						forcedSpace = profile.getStorageSpaceForSpace(spaceCodeFromIdentifier);
 					}
 					if(infoData.result.identifiersPressent) { //If identifiers are present they should match the space of the experiment
 						mainController.serverFacade.registerSamplesWithSilentOverrides(typeAndFileController.getSampleTypeCode(), forcedSpace, experimentIdentifierOrDelete, "sample-file-upload", null, finalCallback);
@@ -262,11 +264,13 @@ function SampleTableView(sampleTableController, sampleTableModel) {
 	this.updateSamples = function(experimentIdentifier) {
 		var allowedSampleTypes = null;
 		var forcedSpace = null;
+		var spaceCodeFromIdentifier = null;
 		if(this._sampleTableModel.sampleTypeCodeToUse) {
 			allowedSampleTypes = [this._sampleTableModel.sampleTypeCodeToUse, "STORAGE_POSITION"];
 		}
 		if(experimentIdentifier) {
-			forcedSpace = IdentifierUtil.getForcedSpaceIdentifier(IdentifierUtil.getSpaceCodeFromIdentifier(experimentIdentifier));
+			spaceCodeFromIdentifier = IdentifierUtil.getSpaceCodeFromIdentifier(experimentIdentifier);
+			forcedSpace = IdentifierUtil.getForcedSpaceIdentifier(spaceCodeFromIdentifier);
 		}
 		var typeAndFileController = new TypeAndFileController('Update ' + ELNDictionary.Samples + '', "UPDATE", function(type, file) {
 			Util.blockUI();
@@ -286,7 +290,7 @@ function SampleTableView(sampleTableController, sampleTableModel) {
 			var experimentIdentifierOrDelete = experimentIdentifier;
 			if(experimentIdentifierOrDelete && typeAndFileController.getSampleTypeCode() === "STORAGE_POSITION") {
 				experimentIdentifierOrDelete = "__DELETE__";
-				forcedSpace = IdentifierUtil.getForcedSpaceIdentifier("STORAGE");
+				forcedSpace = profile.getStorageSpaceForSpace(spaceCodeFromIdentifier);
 			}
 			
 			mainController.serverFacade.fileUpload(typeAndFileController.getFile(), function(result) {