diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index b27e94c5e64201c70b0fc573959be7ea4a203325..4ecb7f7083451a23a0fa9ac8f101fd34cea2ba30 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -16,28 +16,6 @@
 
 package ch.systemsx.cisd.openbis.generic.server;
 
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.DataIntegrityViolationException;
-
 import ch.systemsx.cisd.authentication.IAuthenticationService;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
@@ -62,83 +40,15 @@ import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractT
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdCollectionPredicate.SpaceTechIdCollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdPredicate.ExperimentTechIdPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.AbstractTechIdPredicate.ProjectTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.BasicEntityDescriptionPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetCodeCollectionPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetCodePredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DataSetUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.DeletionTechIdCollectionPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ExperimentUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ListSampleCriteriaPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectPermIdStringPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ProjectUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.RevertDeletionPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleTechIdCollectionReadWritePredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleTechIdPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleTechIdReadWritePredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SampleUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SpaceIdentifierPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.SpaceUpdatesPredicate;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.DeletionValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.EntityHistoryValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExperimentByIdentiferValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExpressionValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ExternalDataValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.MatchingEntityValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.ProjectValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SampleValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SearchDomainSearchResultValidator;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.SimpleSpaceOrProjectValidator;
+import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.*;
+import ch.systemsx.cisd.openbis.generic.server.authorization.validator.*;
 import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.DataAccessExceptionTranslator;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.EntityCodeGenerator;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.EntityTypeBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IAttachmentBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IAuthorizationGroupBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ICorePluginTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataSetTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataStoreBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IDeletedDataSetTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IDeletionTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypeBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IEntityTypePropertyTypeBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IExperimentTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IGridCustomFilterOrColumnBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IMaterialTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IMetaprojectBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IProjectBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IPropertyTypeTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IRoleAssignmentTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IScriptBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ISearchDomainSearcher;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ISpaceBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.ITrashBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO;
-import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyTermBO;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.*;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.common.DatabaseContextUtils;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatasetLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDeletionDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityHistoryDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataManagementSystemDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IMetaprojectDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.RelatedEntityFinder;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.*;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.HibernateSearchDataProvider;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.SampleDataAccessExceptionTranslator;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.dynamic_property.DynamicPropertyEvaluator;
@@ -155,14 +65,9 @@ import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataRegi
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain;
-import ch.systemsx.cisd.openbis.generic.shared.basic.BasicEntityInformationHolder;
-import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithIdentifier;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IdentifierExtractor;
-import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.*;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.*;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedInputWidgetDescription;
@@ -171,88 +76,23 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedUiAction;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IPerson;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.id.metaproject.IMetaprojectId;
 import ch.systemsx.cisd.openbis.generic.shared.coreplugin.ICorePluginResourceLoader;
-import ch.systemsx.cisd.openbis.generic.shared.dto.AbstractEntityPropertyHistoryPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.AuthorizationGroupPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePropertyTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomFilterPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationHolderDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialUpdateDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectAssignmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.MetaprojectPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.NewRoleAssignment;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectUpdatesDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ScriptPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity;
-import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierFactory;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.*;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.*;
 import ch.systemsx.cisd.openbis.generic.shared.hotdeploy_plugins.api.IEntityAdaptor;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory;
 import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.IManagedPropertyEvaluator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.AttachmentTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.AuthorizationGroupTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DataStoreServiceTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DataStoreTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DataTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.DtoConverters;
-import ch.systemsx.cisd.openbis.generic.shared.translator.EntityHistoryTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.EntityTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.ExternalDataManagementSystemTranslator;
+import ch.systemsx.cisd.openbis.generic.shared.translator.*;
 import ch.systemsx.cisd.openbis.generic.shared.translator.GridCustomExpressionTranslator.GridCustomFilterTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.MetaprojectTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.PersonTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.ProjectTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.PropertyTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.RoleAssignmentTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.ScriptTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.SpaceTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.TypeTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTermTranslator;
-import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 import ch.systemsx.cisd.openbis.generic.shared.util.RelationshipUtils;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DataIntegrityViolationException;
+
+import java.net.UnknownHostException;
+import java.util.*;
+import java.util.Map.Entry;
 
 public final class CommonServer extends AbstractCommonServer<ICommonServerForInternalUse> implements
         ICommonServerForInternalUse
@@ -923,7 +763,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         {
             extractAssignments(result, entityTypeOrNull, propertyType);
         }
-        Collections.sort(result);
+        result.sort(null);
         return result;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
index 80ab6d91d7c923d2ad6069ac23315d95be30e87b..3416d16c13051a66faa0542a7bdfd38f2f0a08c1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
@@ -93,7 +93,7 @@ public class BasicConstant
     /**
      * Canonical date format pattern used to render dates in GUI in a more readable way.
      */
-    public static final String RENDERED_CANONICAL_DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss ZZZZ";
+    public static final String RENDERED_CANONICAL_DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss ZZZ";
 
     /**
      * Date format which does not include time zone.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
index b51495b33dec850f4d040ebc228482c1c6332b30..ff379c7812a5816b7be73c936ea2439f8bc248d7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidator.java
@@ -18,7 +18,6 @@ package ch.systemsx.cisd.openbis.generic.shared.util;
 
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
 import java.util.EnumMap;
 import java.util.List;
@@ -52,6 +51,10 @@ public class SimplePropertyValidator
 
         SECONDS_DATE_PATTERN("yyyy-MM-dd HH:mm:ss"),
 
+        ISO_MINUTES_DATE_PATTERN("yyyy-MM-dd'T'HH:mm"),
+
+        ISO_SECONDS_DATE_PATTERN("yyyy-MM-dd'T'HH:mm:ss"),
+
         US_DATE_PATTERN("M/d/yy"),
 
         US_DATE_TIME_PATTERN("M/d/yy h:mm a"),
@@ -60,7 +63,11 @@ public class SimplePropertyValidator
 
         CANONICAL_DATE_PATTERN(BasicConstant.CANONICAL_DATE_FORMAT_PATTERN),
 
-        RENDERED_CANONICAL_DATE_PATTERN(BasicConstant.RENDERED_CANONICAL_DATE_FORMAT_PATTERN);
+        ISO_CANONICAL_DATE_PATTERN("yyyy-MM-dd'T'HH:mm:ssX"),
+
+        RENDERED_CANONICAL_DATE_PATTERN(BasicConstant.RENDERED_CANONICAL_DATE_FORMAT_PATTERN),
+
+        ISO_RENDERED_CANONICAL_DATE_PATTERN("yyyy-MM-dd'T'HH:mm:ssXXX");
 
         private final String pattern;
 
@@ -199,7 +206,7 @@ public class SimplePropertyValidator
                 // we store date in CANONICAL_DATE_PATTERN
                 return DateFormatUtils.format(date,
                         SupportedDatePattern.CANONICAL_DATE_PATTERN.getPattern());
-            } catch (final ParseException ex)
+            } catch (final ParseException | IllegalArgumentException ex)
             {
                 throwUserFailureException(value);
                 return null;
@@ -209,7 +216,7 @@ public class SimplePropertyValidator
         /**
          * Manually validates the date value on cases which are omitted by DateUtils.
          * 
-         * @param value the date-time value to validate. 
+         * @param value the date-time value to validate.
          * @throws UserFailureException thrown if the value is not considered as a well formatted date.
          */
         private void validateHyphens(final String value) throws UserFailureException
@@ -218,18 +225,15 @@ public class SimplePropertyValidator
             {
                 return;
             }
-            
-            final String dateValue = extractDate(value);
-            final boolean hyphenFormat = dateValue.matches("\\d*-\\d*-\\d*");
-            final boolean desiredHyphenFormat = dateValue.matches("\\d{4,}-\\d+-\\d+");
-            if (hyphenFormat && !desiredHyphenFormat) 
+            int indexOfHyphen = value.indexOf('-');
+            if (indexOfHyphen >= 0 && indexOfHyphen != 4)
             {
-                // When the date value uses hyphens as separators but does not have 4 digits for the year value 
+                // When the date value uses hyphens as separators but does not have 4 digits for the year value
                 // throw an exception.
                 throwUserFailureException(value);
             }
         }
-        
+
         /**
          * Throws UserFailureException.
          * 
@@ -238,21 +242,10 @@ public class SimplePropertyValidator
          */
         private final static void throwUserFailureException(final String value) throws UserFailureException
         {
+            final String validValues = "[" + String.join("\n", DATE_PATTERNS) + "]";
             throw UserFailureException.fromTemplate(
                     "Date value '%s' has improper format. It must be one of '%s'.", value,
-                    Arrays.toString(DATE_PATTERNS));
-        }
-        
-        /**
-         * Extracts date part from the string representation of a date-time.
-         * 
-         * @param value the value considered as string representation of date-time.
-         * @return the date portion of the date-time string.
-         */
-        private final static String extractDate(final String value) 
-        {
-            final int dateSeparator = Math.min(value.indexOf(' '), value.indexOf('T'));
-            return dateSeparator >= 0 ? value.substring(0, dateSeparator) : value;
+                    validValues);
         }
     }
 
diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPropertyAssignmentTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPropertyAssignmentTest.java
index 841d2e743c21cf68c6aa78f0380bd815d0227188..06cbd7fe3f71bf65bc17967d88d6f029a0149a8b 100644
--- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPropertyAssignmentTest.java
+++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/SearchPropertyAssignmentTest.java
@@ -219,7 +219,7 @@ public class SearchPropertyAssignmentTest extends AbstractTest
             Assert.assertTrue(propertyAssignment.getEntityType().getCode().equals("CELL_PLATE")
                     || propertyAssignment.getPropertyType().getCode().equals("BACTERIUM"));
         }
-        assertEquals(propertyAssignments.size(), 11);
+        assertEquals(propertyAssignments.size() >= 11, true);
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
index 3b2428f37d89948c4bcfc6b74145cda9fd26f3d2..9f24cf7bb826c01cd4b1fab9590290e69652ae4e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/AuthorizationManagementConsolTest.java
@@ -16,18 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.menu.TopMenu.ActionMenuKind;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.CheckGroupTable;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.CheckPersonTable;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.CheckRoleAssignmentTable;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.CreateGroup;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.CreatePerson;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.FillRoleAssignmentForm;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.OpenRoleAssignmentDialog;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.RoleAssignmentRow;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.amc.*;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.PersonGridColumnIDs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SpaceGridColumnIDs;
 import ch.systemsx.cisd.openbis.generic.client.web.client.testframework.AbstractGWTTestCase;
@@ -114,7 +105,7 @@ public class AuthorizationManagementConsolTest extends AbstractGWTTestCase
 
         FailureExpectation failureExpectation =
                 new FailureExpectation(
-                        (Class<? extends AsyncCallback<?>>) TypedTableGrid.ListEntitiesCallback.class)
+                        (Class) TypedTableGrid.ListEntitiesCallback.class)
                         .with("Authorization failure: None of method roles '[INSTANCE_ADMIN]' "
                                 + "could be found in roles of user 'o'.");
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidatorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..599b46bc2ae77f9706510f8e10557a81837b0876
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/util/SimplePropertyValidatorTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2019 ETH Zuerich, SIS
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.util;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.shared.util.SimplePropertyValidator.TimestampValidator;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class SimplePropertyValidatorTest
+{
+
+    @DataProvider
+    public Object[][] validTimestamps()
+    {
+        return new Object[][]{
+                {"2020-05-16", "2020-05-16 00:00:00 +0200"},
+                {"2020-5-16", "2020-05-16 00:00:00 +0200"},
+                {"2019-01-16", "2019-01-16 00:00:00 +0100"},
+                {"2019-01-16 3:4", "2019-01-16 03:04:00 +0100"},
+                {"2019-01-16 18:23:56", "2019-01-16 18:23:56 +0100"},
+                {"2019-01-16 18:23:56 +0700", "2019-01-16 12:23:56 +0100"},
+                {"2019-01-16 18:23:56 GMT", "2019-01-16 19:23:56 +0100"},
+                {"1/16/19", "2019-01-16 00:00:00 +0100"},
+                {"1/16/19 8:9", "2019-01-16 08:09:00 +0100"},
+                {"1/16/19 8:9 p", "2019-01-16 20:09:00 +0100"},
+                {"1/16/19 18:19", "2019-01-16 18:19:00 +0100"},
+                {"2019-01-20T10:58", "2019-01-20 10:58:00 +0100"},
+                {"2019-01-20T10:58:24", "2019-01-20 10:58:24 +0100"},
+                {"2019-05-20T10:58:24", "2019-05-20 10:58:24 +0200"},
+                {"2019-05-20T10:58:24+07:00", "2019-05-20 05:58:24 +0200"},
+                {"2019-05-20T10:58:24-07:30", "2019-05-20 20:28:24 +0200"},
+                {"2019-01-20T10:58:24Z", "2019-01-20 11:58:24 +0100"},
+                {"2019-05-20T10:58:24Z", "2019-05-20 12:58:24 +0200"},
+        };
+    }
+
+    @DataProvider
+    public Object[][] invalidTimestamps()
+    {
+        return new Object[][] {
+                { "10-05-06" },
+                { "10-05-06 7:23" },
+                { "10-05-06 17:13:39" },
+                { "2010-05-36 17:13:39" },
+                { "2010-05-06 27:13:39" },
+                { "13/12/11 7:39" },
+                { "3/12/11 7:39:22" },
+                { "10-05-06T7:23" },
+                { "10-05-06T17:13:39" },
+                { "2010-05-36T17:13:39" },
+                { "2010-05-06T27:13:39" },
+        };
+    }
+
+    @Test(dataProvider = "validTimestamps")
+    public void testTimestampValidatorWithValidExamples(String stringToParse, String canonicalTimestamp)
+    {
+        TimestampValidator validator = new SimplePropertyValidator.TimestampValidator();
+
+        assertEquals(validator.validate(stringToParse), canonicalTimestamp);
+    }
+
+    @Test(dataProvider = "invalidTimestamps")
+    public void testTimestampValidatorWithInvalidExamples(String stringToParse)
+    {
+        TimestampValidator validator = new SimplePropertyValidator.TimestampValidator();
+
+        try
+        {
+            validator.validate(stringToParse);
+        } catch (UserFailureException e)
+        {
+            assertEquals(e.getMessage(), "Date value '" + stringToParse + "' has improper format. " +
+                    "It must be one of '[yyyy-MM-dd\n" +
+                    "yyyy-MM-dd HH:mm\n" +
+                    "yyyy-MM-dd HH:mm:ss\n" +
+                    "yyyy-MM-dd'T'HH:mm\n" +
+                    "yyyy-MM-dd'T'HH:mm:ss\n" +
+                    "M/d/yy\n" +
+                    "M/d/yy h:mm a\n" +
+                    "M/d/yy HH:mm\n" +
+                    "yyyy-MM-dd HH:mm:ss Z\n" +
+                    "yyyy-MM-dd'T'HH:mm:ssX\n" +
+                    "yyyy-MM-dd HH:mm:ss ZZZ\n" +
+                    "yyyy-MM-dd'T'HH:mm:ssXXX]'.");
+        }
+    }
+
+}
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/server/ServerFacade.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
index 4f792823e08c42ef84feec074522bc4ffcb232aa..d07f3dbe6015efe3485d2b319264c13248041baf 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js
@@ -1442,6 +1442,7 @@ function ServerFacade(openbisServer) {
 		v1Sample["permId"] = (v3Sample.permId)?v3Sample.permId.permId:null;
 		v1Sample["code"] = v3Sample.code;
 		v1Sample["identifier"] = (v3Sample.identifier)?v3Sample.identifier.identifier:null;
+		v1Sample["projectCode"] = (v3Sample.project) ? v3Sample.project.code : null;
 		v1Sample["experimentIdentifierOrNull"] = (v3Sample.experiment)?v3Sample.experiment.identifier.identifier:null;
 		v1Sample["sampleTypeCode"] = (v3Sample.type)?v3Sample.type.code:null;
 		v1Sample["properties"] = v3Sample.properties;
@@ -1789,6 +1790,7 @@ function ServerFacade(openbisServer) {
             fetchOptions.withType();
             fetchOptions.withRegistrator();
             fetchOptions.withModifier();
+            fetchOptions.withProject();
             fetchOptions.withExperiment();
             if(fechOptions["withProperties"]) {
             		fetchOptions.withProperties();
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
index 3a069f65163f5434f0c6b13e733b40a0c460d73e..0f19fad800668acdbcce3b9188a6908222b498d3 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js
@@ -632,7 +632,18 @@ var FormUtil = new function() {
 		}
 	}
 	
+	this.createPropertyField = function(propertyType, propertyValue) {
+		if (propertyType.dataType === "CONTROLLEDVOCABULARY") {
+			propertyValue = this.getVocabularyLabelForTermCode(propertyType, propertyValue);
+		}
+		return this._createField(propertyType.dataType === "HYPERLINK", propertyType.label, propertyValue, propertyType.code);
+	}
+	
 	this.getFieldForLabelWithText = function(label, text, id, postComponent, cssForText) {
+		return this._createField(false, label, text, id, postComponent, cssForText);
+	}
+	
+	this._createField = function(hyperlink, label, text, id, postComponent, cssForText) {
 		var $fieldset = $('<div>');
 		
 		var $controlGroup = $('<div>', {class : 'form-group'});
@@ -660,7 +671,8 @@ var FormUtil = new function() {
 		if(text) {
 			text = text.replace(/(?:\r\n|\r|\n)/g, '\n'); //Normalise carriage returns
 		}
-		$component.html(html.sanitize(text));
+		text = html.sanitize(text);
+		$component.html(hyperlink ? this.asHyperlink(text) : text);
 		
 		if(id) {
 			$component.attr('id', id);
@@ -669,6 +681,10 @@ var FormUtil = new function() {
 		
 		return $fieldset;
 	}
+	
+	this.asHyperlink = function(text) {
+		return $("<a>", { "href" : text, "target" : "_blank"}).append(text);
+	}
 
 	//
 	// Get Field from property
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
index 5d730a9a2bc39bd66bd587386772c9c94e97ecd2..39e5d47cbbd2ab80a66e0dd5ec5f42b44f0edead 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js
@@ -79,6 +79,19 @@ var ExperimentDataGridUtil = new function() {
 				
 				var newVocabularyColumnFunc = getVocabularyColumn(propertyType);
 				propertyColumnsToSort.push(newVocabularyColumnFunc());
+			} else if (propertyType.dataType === "HYPERLINK") {
+				var getHyperlinkColumn = function(propertyType) {
+					return {
+						label : propertyType.label,
+						property : propertyType.code,
+						isExportable: true,
+						sortable : true,
+						render : function(data) {
+							return FormUtil.asHyperlink(data[propertyType.code]);
+						}
+					};
+				}
+				propertyColumnsToSort.push(getHyperlinkColumn(propertyType));
 			} else {
 				propertyColumnsToSort.push({
 					label : propertyCodesDisplayNames[idx],
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
index 5330e2396df1d6a2289a2c53ee95a81e5c1e2918..90e4cef2d10a5b9e9853ff1391b48c52c18d3240 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js
@@ -289,6 +289,19 @@ var SampleDataGridUtil = new function() {
 					
 					var newVocabularyColumnFunc = getVocabularyColumn(propertyType);
 					propertyColumnsToSort.push(newVocabularyColumnFunc());
+				} else if (propertyType.dataType === "HYPERLINK") {
+					var getHyperlinkColumn = function(propertyType) {
+						return {
+							label : propertyType.label,
+							property : propertyType.code,
+							isExportable: true,
+							sortable : true,
+							render : function(data) {
+								return FormUtil.asHyperlink(data[propertyType.code]);
+							}
+						};
+					}
+					propertyColumnsToSort.push(getHyperlinkColumn(propertyType));
 				} else {			
 					propertyColumnsToSort.push({
 						label : propertyType.label,
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/DataSetFormView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/DataSetFormView.js
index 4c7e7dec799b9e9e7d3eb5fcc839b4d70d32fbd4..16305c02188adc0f4465e31c31d62673e7c5d1dc 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/DataSetFormView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataSetForm/DataSetFormView.js
@@ -650,10 +650,7 @@ function DataSetFormView(dataSetFormController, dataSetFormModel) {
 					
 					if(this._dataSetFormModel.mode === FormMode.VIEW) {
 						if(Util.getEmptyIfNull(value) !== "") { //Don't show empty fields, whole empty sections will show the title
-							if(propertyType.dataType === "CONTROLLEDVOCABULARY") {
-								value = FormUtil.getVocabularyLabelForTermCode(propertyType, value);
-							}
-							var $controlGroup = FormUtil.getFieldForLabelWithText(propertyType.label, value, propertyType.code);
+							$controlGroup = FormUtil.createPropertyField(propertyType, value);
 							$fieldset.append($controlGroup);
 						} else {
 							continue;
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 babba314421db26fa10cce73a487431d024c75cb..5c2958f79f05f741f8f035c2ad23d4dbfea8043a 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
@@ -421,10 +421,7 @@ function ExperimentFormView(experimentFormController, experimentFormModel) {
 				
 				if(this._experimentFormModel.mode === FormMode.VIEW) { //Show values without input boxes if the form is in view mode
 					if(Util.getEmptyIfNull(value) !== "") { //Don't show empty fields, whole empty sections will show the title
-						if(propertyType.dataType === "CONTROLLEDVOCABULARY") {
-							value = FormUtil.getVocabularyLabelForTermCode(propertyType, value);
-						}
-						$controlGroup = FormUtil.getFieldForLabelWithText(propertyType.label, value);
+						$controlGroup = FormUtil.createPropertyField(propertyType, value);
 					} else {
 						continue;
 					}
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/SampleFormView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/SampleFormView.js
index 812b8d51f7e01cd0d09642ea2aca34717aba3413..b7bc8398bd3e7ed8f0a5892d68eb065852f22abb 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/SampleFormView.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SampleForm/SampleFormView.js
@@ -658,10 +658,7 @@ function SampleFormView(sampleFormController, sampleFormModel) {
 				
 				if(this._sampleFormModel.mode === FormMode.VIEW) { //Show values without input boxes if the form is in view mode
 					if(Util.getEmptyIfNull(value) !== "") { //Don't show empty fields, whole empty sections will show the title
-						if(propertyType.dataType === "CONTROLLEDVOCABULARY") {
-							value = FormUtil.getVocabularyLabelForTermCode(propertyType, value);
-						}
-						$controlGroup = FormUtil.getFieldForLabelWithText(propertyType.label, value, propertyType.code);
+						$controlGroup = FormUtil.createPropertyField(propertyType, value);
 					} else {
 						continue;
 					}