From 91899784405e64362c66d961ca5d9506f98e2a66 Mon Sep 17 00:00:00 2001
From: felmer <felmer>
Date: Wed, 17 Sep 2008 09:29:21 +0000
Subject: [PATCH] LMS-478 DTOs and related classes moved from 'lims_base' to
 'openbis'. Project dependencies changed: lims_base, etlserver,
 dataset_download depend on openbis.

SVN: 8344
---
 .../cisd/common/collections/ListSet.java      | 239 +++++++++++
 dataset_download/.classpath                   |  45 ++-
 .../datasetdownload/DataSetService.java       |   2 +-
 .../DatasetDownloadServlet.java               |   6 +-
 .../HTMLDirectoryRenderer.java                |  10 +-
 .../datasetdownload/IDirectoryRenderer.java   |   2 +-
 .../PlainTextRendererFactory.java             |   2 +-
 .../DatasetDownloadServletTest.java           |  18 +-
 openbis/.classpath                            |   5 +-
 .../web/server/GenericClientService.java      |   6 +-
 .../web/server/util/GroupTranslater.java      |   2 +-
 .../web/server/util/PersonTranslator.java     |   2 +-
 .../openbis/generic/server/GenericServer.java |   6 +-
 .../generic/server/GenericServerLogger.java   |   4 +-
 .../server/LogMessagePrefixGenerator.java     |   4 +-
 .../authorization/AuthorizationAdvisor.java   |   3 +-
 .../DefaultAccessController.java              |   4 +-
 .../DefaultReturnValueFilter.java             |   2 +-
 .../server/authorization/IAuthSession.java    |   2 +-
 .../authorization/PredicateExecutor.java      |   2 +-
 .../generic/server/authorization/Role.java    |   2 +-
 .../authorization/RoleWithIdentifier.java     |  10 +-
 .../authorization/annotation/RoleSet.java     |   2 +-
 .../AbstractDatabaseInstancePredicate.java    |   4 +-
 .../predicate/AbstractPredicate.java          |   2 +-
 .../predicate/ArrayPredicate.java             |   2 +-
 .../predicate/CollectionPredicate.java        |   2 +-
 .../DatabaseInstanceIdentifierPredicate.java  |   6 +-
 .../predicate/DelegatedPredicate.java         |   2 +-
 .../predicate/GroupIdentifierPredicate.java   |   8 +-
 .../authorization/predicate/IPredicate.java   |   2 +-
 .../predicate/NewExperimentPredicate.java     |   6 +-
 .../predicate/NewSamplePredicate.java         |   4 +-
 .../predicate/QueryRestrictionPredicate.java  |   4 +-
 .../predicate/SampleFilterPredicate.java      |  10 +-
 .../SampleOwnerIdentifierPredicate.java       |   4 +-
 .../validator/AbstractValidator.java          |   2 +-
 .../validator/BaseExperimentValidator.java    |   6 +-
 .../validator/DatabaseInstanceValidator.java  |   6 +-
 .../validator/ExternalDataValidator.java      |   6 +-
 .../validator/GroupValidator.java             |   6 +-
 .../authorization/validator/IValidator.java   |   2 +-
 .../dataaccess/IAuthorizationDAOFactory.java  |   2 +-
 .../dataaccess/IDatabaseInstanceDAO.java      |   2 +-
 .../generic/server/dataaccess/IGroupDAO.java  |   4 +-
 .../generic/server/dataaccess/IPersonDAO.java |   2 +-
 .../server/dataaccess/IRoleAssignmentDAO.java |   4 +-
 .../migration/MigrationStepFrom022To023.java  | 130 +++---
 .../migration/MigrationStepFrom023To024.java  | 376 +++++++++---------
 .../migration/MigrationStepFrom025To026.java  | 294 +++++++-------
 .../server/util/GroupIdentifierHelper.java    |  14 +-
 .../server/util/KeyExtractorFactory.java      |  31 +-
 .../openbis/generic/server/util/UuidUtil.java |   2 +-
 .../shared/GenericSharedConstants.java        |  31 ++
 .../generic/shared/IGenericServer.java        |   4 +-
 .../shared/dto/AbstractAttachmentPE.java      | 164 ++++++++
 .../generic/shared/dto/AbstractEntity.java    |  45 +++
 .../shared/dto/AbstractIdAndCodeHolder.java   | 125 ++++++
 .../dto/AbstractRegistratrationHolder.java    |  97 +++++
 .../generic/shared/dto/AbstractTypePE.java    |  86 ++++
 .../generic/shared/dto/AttachmentPE.java      |  47 +++
 .../generic/shared/dto/BaseExperiment.java    | 148 +++++++
 .../cisd/openbis/generic/shared/dto/Code.java | 112 ++++++
 .../generic/shared/dto/CodeConverter.java     | 103 +++++
 .../generic/shared/dto/ColumnNames.java       | 165 ++++++++
 .../openbis/generic/shared/dto/DataPE.java    | 275 +++++++++++++
 .../generic/shared/dto/DataSetType.java       |  39 ++
 .../generic/shared/dto/DataSetTypePE.java     |  70 ++++
 .../generic/shared/dto/DataStorePE.java       | 135 +++++++
 .../generic/shared/dto/DataTypePE.java        | 148 +++++++
 .../shared/dto/DatabaseInstancePE.java        | 183 +++++++++
 .../shared/dto/EntityPropertyFiller.java      |  74 ++++
 .../generic/shared/dto/EntityPropertyPE.java  | 164 ++++++++
 .../shared/dto/EntityPropertyTypeDTO.java     | 103 +++++
 .../generic/shared/dto/EntityType.java        |  55 +++
 .../dto/EntityTypeMandatorilyRelation.java    | 110 +++++
 .../generic/shared/dto/EntityTypePE.java      |  67 ++++
 .../shared/dto/EntityTypePropertyTypePE.java  | 128 ++++++
 .../generic/shared/dto/Experiment.java        | 234 +++++++++++
 .../generic/shared/dto/ExperimentPE.java      | 313 +++++++++++++++
 .../shared/dto/ExperimentPlatesFilter.java    |  70 ++++
 .../shared/dto/ExperimentPropertyPE.java      |  98 +++++
 .../generic/shared/dto/ExperimentType.java    |  29 ++
 .../generic/shared/dto/ExperimentTypePE.java  |  55 +++
 .../dto/ExperimentTypePropertyTypePE.java     |  71 ++++
 .../generic/shared/dto/ExternalData.java      | 223 +++++++++++
 .../generic/shared/dto/ExternalDataPE.java    | 162 ++++++++
 .../generic/shared/dto/ExtractableData.java   |  90 +++++
 .../generic/shared/dto/FileAttachmentPE.java  |  63 +++
 .../generic/shared/dto/FileFormatType.java    |  41 ++
 .../generic/shared/dto/FileFormatTypePE.java  |  75 ++++
 .../openbis/generic/shared/dto/GroupPE.java   | 226 +++++++++++
 ...ibernateAbstractRegistratrationHolder.java | 116 ++++++
 .../shared/dto/IEntityPropertiesHolder.java   |  38 ++
 .../generic/shared/dto/IEntityProperty.java   |  46 +++
 .../generic/shared/dto/IEntityType.java       |  39 ++
 .../shared/dto/IEntityTypePropertyType.java   |  36 ++
 .../generic/shared/dto/IIdAndCodeHolder.java  |  32 ++
 .../openbis/generic/shared/dto/IIdHolder.java |  33 ++
 .../shared/dto/IRegistratorHolder.java        |  48 +++
 .../dto/ISimpleEntityPropertiesHolder.java    |  36 ++
 .../shared/dto/IUntypedValueSetter.java       |  30 ++
 .../cisd/openbis/generic/shared/dto/Id.java   |  91 +++++
 .../generic/shared/dto/InvalidationPE.java    | 107 +++++
 .../generic/shared/dto/LimitFilter.java       | 102 +++++
 .../generic/shared/dto/LocatorType.java       |  41 ++
 .../generic/shared/dto/LocatorTypePE.java     |  50 +++
 .../generic/shared/dto/MaterialBatchPE.java   | 158 ++++++++
 .../generic/shared/dto/MaterialPE.java        | 232 +++++++++++
 .../shared/dto/MaterialPropertyPE.java        | 107 +++++
 .../generic/shared/dto/MaterialTypePE.java    |  54 +++
 .../dto/MaterialTypePropertyTypePE.java       |  75 ++++
 .../generic/shared/dto/NewExperiment.java     | 135 +++++++
 .../generic/shared/dto/NewMaterial.java       |  75 ++++
 .../shared/dto/NewProcessingInstruction.java  |  93 +++++
 .../generic/shared/dto/NewPropertyType.java   |  97 +++++
 .../generic/shared/dto/NewRoleAssignment.java | 112 ++++++
 .../openbis/generic/shared/dto/NewSample.java | 145 +++++++
 .../shared/dto/NewSampleComponent.java        |  49 +++
 ...wSampleComponentWithFixedMaterialType.java |  50 +++
 .../openbis/generic/shared/dto/PersonPE.java  | 261 ++++++++++++
 .../openbis/generic/shared/dto/Procedure.java | 193 +++++++++
 .../generic/shared/dto/ProcedurePE.java       | 210 ++++++++++
 .../generic/shared/dto/ProcedureType.java     |  64 +++
 .../generic/shared/dto/ProcedureTypePE.java   |  92 +++++
 .../shared/dto/ProcessingInstructionDTO.java  |  97 +++++
 .../shared/dto/ProcessingParameters.java      |  72 ++++
 .../openbis/generic/shared/dto/ProjectPE.java | 223 +++++++++++
 .../dto/PropertyTypeEntityTypeRelation.java   | 116 ++++++
 .../generic/shared/dto/PropertyTypePE.java    | 260 ++++++++++++
 .../generic/shared/dto/QueryRestriction.java  | 137 +++++++
 .../generic/shared/dto/RoleAssignmentPE.java  | 188 +++++++++
 .../openbis/generic/shared/dto/RoleCode.java  |  29 ++
 .../openbis/generic/shared/dto/Sample.java    | 262 ++++++++++++
 .../generic/shared/dto/SampleFilter.java      |  98 +++++
 .../shared/dto/SampleGenerationDTO.java       |  77 ++++
 .../openbis/generic/shared/dto/SamplePE.java  | 374 +++++++++++++++++
 .../generic/shared/dto/SamplePropertyPE.java  | 103 +++++
 .../generic/shared/dto/SampleType.java        |  56 +++
 .../generic/shared/dto/SampleTypePE.java      |  68 ++++
 .../shared/dto/SampleTypePropertyTypePE.java  |  76 ++++
 .../generic/shared/dto/SequenceNames.java     |  99 +++++
 .../openbis/generic/shared/dto/Session.java   |   2 -
 .../shared/dto/SimpleEntityProperty.java      | 111 ++++++
 .../generic/shared/dto/StorageFormat.java     |  75 ++++
 .../generic/shared/dto/TableNames.java        | 105 +++++
 .../generic/shared/dto/TimeInterval.java      | 151 +++++++
 .../shared/dto/ValidationMessages.java        | 147 +++++++
 .../generic/shared/dto/VocabularyPE.java      | 240 +++++++++++
 .../generic/shared/dto/VocabularyTermPE.java  | 162 ++++++++
 .../exception/UndefinedGroupException.java    |  36 ++
 .../shared/dto/hibernate/Location.java        |  48 +++
 .../dto/hibernate/LocationValidator.java      |  60 +++
 .../DatabaseInstanceIdentifier.java           | 139 +++++++
 .../dto/identifier/ExperimentIdentifier.java  | 124 ++++++
 .../dto/identifier/GroupIdentifier.java       | 140 +++++++
 .../dto/identifier/IdentifierHelper.java      | 105 +++++
 .../dto/identifier/MaterialIdentifier.java    |  69 ++++
 .../dto/identifier/ProjectIdentifier.java     | 102 +++++
 .../dto/identifier/SampleIdentifier.java      | 116 ++++++
 .../identifier/SampleIdentifierPattern.java   |  89 +++++
 .../dto/identifier/SampleOwnerIdentifier.java | 182 +++++++++
 .../shared/dto/properties/EntityDataType.java |  55 +++
 .../shared/dto/properties/EntityKind.java     |  90 +++++
 .../dto/properties/EntityProperties.java      | 122 ++++++
 .../EntityPropertyTypeDTOContainer.java       | 219 ++++++++++
 .../dto/properties/EntityPropertyValue.java   | 246 ++++++++++++
 .../dto/properties/PropertiesHelper.java      |  96 +++++
 .../shared/dto/types/DataSetTypeCode.java     |  59 +++
 .../shared/dto/types/ExperimentTypeCode.java  |  59 +++
 .../shared/dto/types/MaterialTypeCode.java    |  39 ++
 .../shared/dto/types/ProcedureTypeCode.java   |  58 +++
 .../shared/dto/types/SampleTypeCode.java      |  79 ++++
 .../authorization/AuthorizationTestUtil.java  |  12 +-
 .../DefaultAccessControllerTest.java          |   8 +-
 .../DefaultReturnValueFilterTest.java         |   2 +-
 .../authorization/PredicateExecutorTest.java  |   6 +-
 .../authorization/RoleWithIdentifierTest.java |  14 +-
 ...tabaseInstanceIdentifierPredicateTest.java |  10 +-
 .../GroupIdentifierPredicateTest.java         |   8 +-
 .../predicate/NewExperimentPredicateTest.java |   2 +-
 .../QueryRestrictionPredicateTest.java        |   2 +-
 .../validator/GroupValidatorTest.java         |  11 +-
 .../DatabaseInstanceIdentifierTest.java       |  57 +++
 .../identifier/ExperimentIdentifierTest.java  |  57 +++
 .../dto/identifier/GroupIdentifierTest.java   |  56 +++
 .../dto/identifier/ProjectIdentifierTest.java |  56 +++
 .../dto/identifier/SampleIdentifierTest.java  | 105 +++++
 188 files changed, 14275 insertions(+), 591 deletions(-)
 create mode 100644 common/source/java/ch/systemsx/cisd/common/collections/ListSet.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/GenericSharedConstants.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractAttachmentPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractEntity.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractIdAndCodeHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractRegistratrationHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AttachmentPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/BaseExperiment.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Code.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/CodeConverter.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataStorePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DatabaseInstancePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyFiller.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyTypeDTO.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypeMandatorilyRelation.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePropertyTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Experiment.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPlatesFilter.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPropertyPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePropertyTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalData.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExtractableData.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileAttachmentPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GroupPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/HibernateAbstractRegistratrationHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityPropertiesHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityProperty.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityTypePropertyType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdAndCodeHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IRegistratorHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ISimpleEntityPropertiesHolder.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IUntypedValueSetter.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Id.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/InvalidationPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LimitFilter.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialBatchPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPropertyPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePropertyTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewExperiment.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewMaterial.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewProcessingInstruction.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewPropertyType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewRoleAssignment.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSample.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponent.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponentWithFixedMaterialType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PersonPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Procedure.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedurePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingInstructionDTO.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingParameters.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProjectPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypeEntityTypeRelation.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/QueryRestriction.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleAssignmentPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleCode.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Sample.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleFilter.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGenerationDTO.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePropertyPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePropertyTypePE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SequenceNames.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SimpleEntityProperty.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/StorageFormat.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TableNames.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TimeInterval.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ValidationMessages.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyTermPE.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedGroupException.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/Location.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/LocationValidator.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/MaterialIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierPattern.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityDataType.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityKind.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityProperties.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyTypeDTOContainer.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyValue.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/PropertiesHelper.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/DataSetTypeCode.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ExperimentTypeCode.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/MaterialTypeCode.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ProcedureTypeCode.java
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/SampleTypeCode.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifierTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifierTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifierTest.java
 create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java

diff --git a/common/source/java/ch/systemsx/cisd/common/collections/ListSet.java b/common/source/java/ch/systemsx/cisd/common/collections/ListSet.java
new file mode 100644
index 00000000000..495592f43ef
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/collections/ListSet.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.collections;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+
+/**
+ * A set of named lists.
+ * <p>
+ * Naming: every list has an <i>unique</i> name but not necessarily an <i>unique</i> label.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+// TODO 2008-09-05, Christian Ribeaud: Write an Unit test for this class.
+public final class ListSet
+{
+    /**
+     * The lists.
+     * <p>
+     * Each list is identified by a {@link Column} which contains the name and the label of the
+     * corresponding list.<br />
+     * <code>values</code> of this map are &lt;row index&gt;=&lt;table value&gt; pairs.
+     * </p>
+     */
+    private final Map<Column, Map<Integer, String>> lists =
+            new HashMap<Column, Map<Integer, String>>();
+
+    /**
+     * A map containing <i>columns</i> keyed by <i>names</i>.
+     */
+    private final Map<String, Column> columnByName = new LinkedHashMap<String, Column>();
+
+    private final void addColumn(final Column newColumn)
+    {
+        final Column column = columnByName.get(newColumn.name);
+        if (column != null && column.label.equals(newColumn.label) == false)
+        {
+            throw new IllegalArgumentException(String.format(
+                    "Different labels detected for the same column name '%s'. "
+                            + "The new one is '%s', the previous one was '%s'.", column.name,
+                    newColumn.label, column.label));
+        }
+        columnByName.put(newColumn.name, newColumn);
+    }
+
+    private final Column getColumn(final String listName)
+    {
+        final Column column = columnByName.get(listName);
+        if (column == null)
+        {
+            throw new IllegalArgumentException(String.format("List name '%s' not found.", listName));
+        }
+        return column;
+    }
+
+    private final static Map<Integer, String> createIntMap()
+    {
+        return new HashMap<Integer, String>();
+    }
+
+    private final Map<Integer, String> getIntMap(final Column column)
+    {
+        final Map<Integer, String> list = lists.get(column);
+        if (list == null)
+        {
+            throw new IllegalArgumentException(String.format("No list found for column '%s'.",
+                    column));
+        }
+        return list;
+    }
+
+    /**
+     * Adds the specified value to the specified list at given <var>rowIndex</var>.
+     * 
+     * @param listName can not be <code>null</code>.
+     * @param value can not be <code>null</code>.
+     */
+    public final void addToList(final String listName, final String listLabel, final String value,
+            final int rowIndex)
+    {
+        assert listName != null : "Unspecified list name.";
+        assert value != null : "Unspecified value";
+        assert rowIndex > -1 : "Invalid row index";
+        final Column column = new Column(listName, listLabel);
+        addColumn(column);
+        Map<Integer, String> list = lists.get(column);
+        if (list == null)
+        {
+            list = createIntMap();
+            lists.put(column, list);
+        }
+        if (list.containsKey(rowIndex))
+        {
+            throw new IllegalArgumentException(String.format("List '%s' already contains a "
+                    + "value for row index %d", listName, rowIndex));
+        }
+        list.put(rowIndex, value);
+    }
+
+    /** Returns the value at given <var>rowIndex</var> from the list found with given <var>listName</var>. */
+    public final String tryGetValueAt(final String listName, final int rowIndex)
+    {
+        assert listName != null : "Unspecified list name";
+        assert rowIndex > -1 : "Invalid row index";
+        return getIntMap(getColumn(listName)).get(rowIndex);
+    }
+
+    /**
+     * For given <var>listName</var> returns corresponding label.
+     */
+    public final String getLabel(final String listName)
+    {
+        return getColumn(listName).label;
+    }
+
+    /**
+     * Returns a set of all list names.
+     */
+    public final Set<String> getListNames()
+    {
+        return Collections.unmodifiableSet(columnByName.keySet());
+    }
+
+    /**
+     * Merges this list set with given one.
+     */
+    public final void mergeList(final ListSet listSet)
+    {
+        final Set<String> listNames = listSet.getListNames();
+        for (final String listName : listNames)
+        {
+            final Column column = listSet.getColumn(listName);
+            final Map<Integer, String> list = listSet.getIntMap(column);
+            for (final Map.Entry<Integer, String> entry : list.entrySet())
+            {
+                addToList(listName, column.label, entry.getValue(), entry.getKey());
+            }
+        }
+    }
+
+    /**
+     * Returns the list of given name <var>listName</var> as {@link List}.
+     * 
+     * @return a list of size <var>rowCount</var>. If no value could be found for a given row
+     *         index, is filled with <code>null</code>.
+     */
+    public final List<String> getList(final String listName, final int rowCount)
+    {
+        final List<String> result =
+                new ArrayList<String>(Collections.<String> nCopies(rowCount, null));
+        final Map<Integer, String> list = getIntMap(getColumn(listName));
+        for (final Map.Entry<Integer, String> entry : list.entrySet())
+        {
+            result.set(entry.getKey(), entry.getValue());
+        }
+        return result;
+    }
+
+    //
+    // Helper classes
+    //
+
+    private final static class Column
+    {
+        final String name;
+
+        final String label;
+
+        Column(final String name, final String label)
+        {
+            assert name != null : "Unspecified name";
+            this.name = name;
+            this.label = label;
+        }
+
+        //
+        // Object
+        //
+
+        @Override
+        public final boolean equals(final Object obj)
+        {
+            if (obj == this)
+            {
+                return true;
+            }
+            if (obj instanceof Column == false)
+            {
+                return false;
+            }
+            final Column that = (Column) obj;
+            final EqualsBuilder builder = new EqualsBuilder();
+            builder.append(name, that.name);
+            return builder.isEquals();
+        }
+
+        @Override
+        public final int hashCode()
+        {
+            final HashCodeBuilder builder = new HashCodeBuilder();
+            builder.append(name);
+            return builder.toHashCode();
+        }
+
+        @Override
+        public final String toString()
+        {
+            return ToStringBuilder.reflectionToString(this,
+                    ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        }
+    }
+}
\ No newline at end of file
diff --git a/dataset_download/.classpath b/dataset_download/.classpath
index 6e36e7b8d0b..21346dc1b2c 100644
--- a/dataset_download/.classpath
+++ b/dataset_download/.classpath
@@ -1,22 +1,23 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="source/java"/>
-	<classpathentry kind="src" path="sourceTest/java"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/common"/>
-	<classpathentry kind="lib" path="/libraries/log4j/log4j.jar" sourcepath="/libraries/log4j/src.zip"/>
-	<classpathentry kind="lib" path="/libraries/jetty/servlet-api-2.5.jar" sourcepath="/libraries/jetty/src/servlet-api-2.5.zip"/>
-	<classpathentry kind="lib" path="/libraries/testng/testng-jdk15.jar" sourcepath="/libraries/testng/src.zip"/>
-	<classpathentry kind="lib" path="/libraries/jmock/jmock.jar"/>
-	<classpathentry kind="lib" path="/libraries/jetty/jetty.jar" sourcepath="/libraries/jetty/src/jetty.zip"/>
-	<classpathentry kind="lib" path="/libraries/jetty/jetty-util.jar" sourcepath="/libraries/jetty/src/jetty-util.zip"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/lims_base"/>
-	<classpathentry kind="lib" path="/libraries/commons-io/commons-io.jar" sourcepath="/libraries/commons-io/src.zip"/>
-	<classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/>
-	<classpathentry kind="lib" path="/libraries/restrictionchecker/restrictions.jar"/>
-	<classpathentry kind="lib" path="/libraries/cglib/cglib-nodep.jar"/>
-	<classpathentry kind="lib" path="/libraries/jmock/hamcrest/hamcrest-core.jar"/>
-	<classpathentry kind="lib" path="/libraries/jmock/hamcrest/hamcrest-library.jar"/>
-	<classpathentry kind="lib" path="/libraries/jmock/objenesis/objenesis-1.0.jar"/>
-	<classpathentry kind="output" path="targets/classes"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="source/java"/>
+	<classpathentry kind="src" path="sourceTest/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/common"/>
+	<classpathentry kind="lib" path="/libraries/log4j/log4j.jar" sourcepath="/libraries/log4j/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/jetty/servlet-api-2.5.jar" sourcepath="/libraries/jetty/src/servlet-api-2.5.zip"/>
+	<classpathentry kind="lib" path="/libraries/testng/testng-jdk15.jar" sourcepath="/libraries/testng/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/jmock/jmock.jar"/>
+	<classpathentry kind="lib" path="/libraries/jetty/jetty.jar" sourcepath="/libraries/jetty/src/jetty.zip"/>
+	<classpathentry kind="lib" path="/libraries/jetty/jetty-util.jar" sourcepath="/libraries/jetty/src/jetty-util.zip"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/lims_base"/>
+	<classpathentry kind="lib" path="/libraries/commons-io/commons-io.jar" sourcepath="/libraries/commons-io/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/restrictionchecker/restrictions.jar"/>
+	<classpathentry kind="lib" path="/libraries/cglib/cglib-nodep.jar"/>
+	<classpathentry kind="lib" path="/libraries/jmock/hamcrest/hamcrest-core.jar"/>
+	<classpathentry kind="lib" path="/libraries/jmock/hamcrest/hamcrest-library.jar"/>
+	<classpathentry kind="lib" path="/libraries/jmock/objenesis/objenesis-1.0.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/openbis"/>
+	<classpathentry kind="output" path="targets/classes"/>
+</classpath>
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DataSetService.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DataSetService.java
index 4c200cb691f..e3651efafe0 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DataSetService.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DataSetService.java
@@ -20,7 +20,7 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.lims.base.IDataSetService;
 import ch.systemsx.cisd.lims.base.ILIMSServiceFactory;
 import ch.systemsx.cisd.lims.base.ServiceRegistry;
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 
 /**
  * A <code>IDataSetService</code> implementation.
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
index 4ca18725b32..289cd8f9e10 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServlet.java
@@ -49,9 +49,9 @@ import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.lims.base.IDataSetService;
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
-import ch.systemsx.cisd.lims.base.dto.LocatorType;
-import ch.systemsx.cisd.lims.base.dto.LocatorTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 
 /**
  * @author Franz-Josef Elmer
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
index 6db5091627d..16b1955ac06 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/HTMLDirectoryRenderer.java
@@ -25,11 +25,11 @@ import org.apache.commons.lang.StringUtils;
 
 import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel;
 import ch.systemsx.cisd.common.utilities.Template;
-import ch.systemsx.cisd.lims.base.dto.ExperimentPE;
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.ProcedurePE;
-import ch.systemsx.cisd.lims.base.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProcedurePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 
 /**
  * An <code>IDirectoryRenderer</code> implementation which renders on HTML pages.
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java
index f460c934122..6e2673e0079 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/IDirectoryRenderer.java
@@ -17,7 +17,7 @@
 package ch.systemsx.cisd.openbis.datasetdownload;
 
 
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 
 /**
  * Interface of a renderer of a directory.
diff --git a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/PlainTextRendererFactory.java b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/PlainTextRendererFactory.java
index 99f2738f92d..6321f5bcbbc 100644
--- a/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/PlainTextRendererFactory.java
+++ b/dataset_download/source/java/ch/systemsx/cisd/openbis/datasetdownload/PlainTextRendererFactory.java
@@ -20,7 +20,7 @@ import java.io.PrintWriter;
 
 import org.apache.commons.io.FileUtils;
 
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 
 /**
  * Factory for rendering file system view in plain text.
diff --git a/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java b/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
index 93efd75924a..65cdb5f030d 100644
--- a/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
+++ b/dataset_download/sourceTest/java/ch/systemsx/cisd/openbis/datasetdownload/DatasetDownloadServletTest.java
@@ -46,15 +46,15 @@ import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.logging.BufferedAppender;
 import ch.systemsx.cisd.common.utilities.OSUtilities;
 import ch.systemsx.cisd.lims.base.IDataSetService;
-import ch.systemsx.cisd.lims.base.dto.ExperimentPE;
-import ch.systemsx.cisd.lims.base.dto.ExternalData;
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.LocatorType;
-import ch.systemsx.cisd.lims.base.dto.LocatorTypePE;
-import ch.systemsx.cisd.lims.base.dto.ProcedurePE;
-import ch.systemsx.cisd.lims.base.dto.ProjectPE;
-import ch.systemsx.cisd.lims.base.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProcedurePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 
 /**
  * @author Franz-Josef Elmer
diff --git a/openbis/.classpath b/openbis/.classpath
index 12db228308f..54f8ee2f089 100644
--- a/openbis/.classpath
+++ b/openbis/.classpath
@@ -16,7 +16,6 @@
 	<classpathentry kind="lib" path="/libraries/log4j/log4j.jar" sourcepath="/libraries/log4j/src.zip"/>
 	<classpathentry kind="lib" path="/libraries/spring/spring.jar" sourcepath="/libraries/spring/src.jar"/>
 	<classpathentry kind="lib" path="/libraries/spring/webmvc/spring-webmvc.jar" sourcepath="/libraries/spring/webmvc/src.jar"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/lims_base"/>
 	<classpathentry kind="lib" path="/libraries/commons-lang/commons-lang.jar" sourcepath="/libraries/commons-lang/src.zip"/>
 	<classpathentry kind="lib" path="/libraries/restrictionchecker/restrictions.jar"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/dbmigration"/>
@@ -24,5 +23,9 @@
 	<classpathentry kind="lib" path="/libraries/jmock/hamcrest/hamcrest-library.jar"/>
 	<classpathentry kind="lib" path="/libraries/jmock/objenesis/objenesis-1.0.jar"/>
 	<classpathentry kind="lib" path="/libraries/jmock/jmock.jar"/>
+	<classpathentry kind="lib" path="/libraries/hibernate-annotations/ejb3-persistence.jar"/>
+	<classpathentry kind="lib" path="/libraries/hibernate-annotations/hibernate-annotations.jar" sourcepath="/libraries/hibernate-annotations/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/hibernate-validator/hibernate-validator.jar" sourcepath="/libraries/hibernate-validator/src.zip"/>
+	<classpathentry kind="lib" path="/libraries/commons-io/commons-io.jar" sourcepath="/libraries/commons-io/src.zip"/>
 	<classpathentry kind="output" path="targets/classes"/>
 </classpath>
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
index ce5ee64b8fd..e797d721dc2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/GenericClientService.java
@@ -29,9 +29,6 @@ import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.servlet.IRequestContextProvider;
 import ch.systemsx.cisd.common.utilities.BuildAndEnvironmentInfo;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.client.web.client.IGenericClientService;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ApplicationInfo;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group;
@@ -40,7 +37,10 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.User;
 import ch.systemsx.cisd.openbis.generic.client.web.server.util.GroupTranslater;
 import ch.systemsx.cisd.openbis.generic.client.web.server.util.UserFailureExceptionTranslater;
 import ch.systemsx.cisd.openbis.generic.shared.IGenericServer;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/GroupTranslater.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/GroupTranslater.java
index c178ae63a66..86b047356ba 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/GroupTranslater.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/GroupTranslater.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.server.util;
 
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Group;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 
 /**
  * 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/PersonTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/PersonTranslator.java
index 3f1dd12c65d..f381b61cfd9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/PersonTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/PersonTranslator.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.server.util;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Person;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
index c449a550e5a..2d2b261ca86 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServer.java
@@ -27,11 +27,11 @@ import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.servlet.IRequestContextProvider;
 import ch.systemsx.cisd.common.servlet.RequestContextProviderAdapter;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.IGenericServer;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * Implementation of client-server interface.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
index 8b56cf94ca3..46c071009d6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/GenericServerLogger.java
@@ -23,10 +23,10 @@ import org.apache.log4j.Logger;
 import ch.systemsx.cisd.authentication.ISessionManager;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.IGenericServer;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * Logger class for {@link GenericServer} which creates readable logs of method invocations.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java
index 32fca099703..0ec02b38d00 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/LogMessagePrefixGenerator.java
@@ -17,8 +17,8 @@
 package ch.systemsx.cisd.openbis.generic.server;
 
 import ch.systemsx.cisd.authentication.ILogMessagePrefixGenerator;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 
 /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationAdvisor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationAdvisor.java
index 5a12b41e3c1..e2863e63140 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationAdvisor.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationAdvisor.java
@@ -39,7 +39,6 @@ import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.AnnotationUtils;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
 import ch.systemsx.cisd.common.utilities.AnnotationUtils.Parameter;
-import ch.systemsx.cisd.lims.base.LogMessageProvider;
 import ch.systemsx.cisd.openbis.generic.server.authorization.IAccessController.Argument;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.AuthorizationGuard;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
@@ -164,7 +163,7 @@ public final class AuthorizationAdvisor extends DefaultPointcutAdvisor
                 authorizationLog.info(String.format(
                         "[USER:'%s' GROUP:%s]: Authorization failure while "
                                 + "invoking method '%s': %s", session.getUserName(),
-                        groupCode == null ? LogMessageProvider.UNDEFINED : "'" + groupCode + "'",
+                        groupCode == null ? "<UNDEFINED>" : "'" + groupCode + "'",
                         ClassUtils.describeMethod(method), errorMessage));
                 throw new AuthorizationFailureException(errorMessage);
             }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java
index 8c8c4c6eeeb..ae0a7673ba6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessController.java
@@ -34,10 +34,10 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 
 /**
  * A default <code>IAccessController</code> implementation.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilter.java
index 59538e2e7ca..be30a3b1ba9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilter.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilter.java
@@ -29,9 +29,9 @@ import ch.systemsx.cisd.common.collections.FilteredList;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.ReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.IValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * A default <code>IReturnValueFilter</code> implementation
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/IAuthSession.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/IAuthSession.java
index a10b0cd33d1..2c1d5ce1294 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/IAuthSession.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/IAuthSession.java
@@ -16,7 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * Session interface used by authorization framework.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
index c2b7afc5474..6aea4115a2f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutor.java
@@ -20,12 +20,12 @@ import java.util.List;
 
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.IAccessController.Argument;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.ArrayPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.CollectionPredicate;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.IPredicate;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * A static class to execute {@link IPredicate}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/Role.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/Role.java
index 9d413e8f1bf..08a59487b81 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/Role.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/Role.java
@@ -19,7 +19,7 @@ package ch.systemsx.cisd.openbis.generic.server.authorization;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 
-import ch.systemsx.cisd.lims.base.role.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 
 /**
  * A well defined role, composed of a {@link RoleLevel} and a {@link RoleCode}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifier.java
index f6ce09bbba5..ef44010ebca 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifier.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifier.java
@@ -17,11 +17,11 @@
 package ch.systemsx.cisd.openbis.generic.server.authorization;
 
 import ch.rinn.restrictions.Private;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.lims.base.identifier.IdentifierHelper;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper;
 
 /**
  * Stores the {@link Role} and the "owner" to which this role is connected: database instance or a
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/annotation/RoleSet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/annotation/RoleSet.java
index 7e1b4e5fbb9..36e5274bcdd 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/annotation/RoleSet.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/annotation/RoleSet.java
@@ -21,9 +21,9 @@ import java.util.LinkedHashSet;
 import java.util.Set;
 
 import ch.systemsx.cisd.common.collections.CollectionUtils;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
 import ch.systemsx.cisd.openbis.generic.server.authorization.Role;
 import ch.systemsx.cisd.openbis.generic.server.authorization.Role.RoleLevel;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 
 /**
  * An enumeration which defines some role sets.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractDatabaseInstancePredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractDatabaseInstancePredicate.java
index 632b24b5f0b..d3367ee76f1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractDatabaseInstancePredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractDatabaseInstancePredicate.java
@@ -16,11 +16,11 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper;
 import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper.IDatabaseInstanceFinder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * An {@link AbstractPredicate} extension which works with database instances.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractPredicate.java
index 7d9508516db..326358a514b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/AbstractPredicate.java
@@ -20,8 +20,8 @@ import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * An <i>abstract</i> <code>IPredicate</code> implementation which mainly checks method
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ArrayPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ArrayPredicate.java
index 2dd7704381e..cb9142d3ae6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ArrayPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/ArrayPredicate.java
@@ -20,9 +20,9 @@ import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * An <code>IPredicate</code> implementation based on an array.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/CollectionPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/CollectionPredicate.java
index 1ddb4ccb85a..ef727012629 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/CollectionPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/CollectionPredicate.java
@@ -21,9 +21,9 @@ import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * An <code>IPredicate</code> implementation based on a {@link Collection}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicate.java
index 54831682351..8c7b2adc11b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicate.java
@@ -19,11 +19,11 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.Role.RoleLevel;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation for {@link DatabaseInstanceIdentifier}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DelegatedPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DelegatedPredicate.java
index 336b429057a..785498d163c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DelegatedPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DelegatedPredicate.java
@@ -19,9 +19,9 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * An <code>AbstractPredicate</code> extension which delegates its method calls to the
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicate.java
index 05abc413123..77819e943fb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicate.java
@@ -20,14 +20,14 @@ import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.Role.RoleLevel;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation based on {@link GroupIdentifier}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/IPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/IPredicate.java
index f49da1ac7c7..bb1893ce7da 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/IPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/IPredicate.java
@@ -19,10 +19,10 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.IPredicateFactory;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * Performs some predicate which returns a {@link Status} based on the input objects.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicate.java
index 4e2132aaa37..c30f3d98773 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicate.java
@@ -16,9 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 
-import ch.systemsx.cisd.lims.base.dto.NewExperiment;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
-import ch.systemsx.cisd.lims.base.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation for {@link NewExperiment}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewSamplePredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewSamplePredicate.java
index 144bb3c2ba2..dff1199f7d8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewSamplePredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewSamplePredicate.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 
-import ch.systemsx.cisd.lims.base.dto.NewSample;
-import ch.systemsx.cisd.lims.base.identifier.SampleOwnerIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewSample;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation for {@link NewSample}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicate.java
index 01529d392fa..e9ebc68bd66 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicate.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 
-import ch.systemsx.cisd.lims.base.dto.QueryRestriction;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.QueryRestriction;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation for {@link QueryRestriction}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleFilterPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleFilterPredicate.java
index a596ff8d15e..6be22cc4c31 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleFilterPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleFilterPredicate.java
@@ -19,13 +19,13 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.SampleFilter;
-import ch.systemsx.cisd.lims.base.identifier.SampleIdentifierPattern;
-import ch.systemsx.cisd.lims.base.identifier.SampleOwnerIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleFilter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierPattern;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation for {@link SampleFilter}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleOwnerIdentifierPredicate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleOwnerIdentifierPredicate.java
index 5e09085e20c..e3926798e3e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleOwnerIdentifierPredicate.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/SampleOwnerIdentifierPredicate.java
@@ -19,10 +19,10 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.predicate;
 import java.util.List;
 
 import ch.systemsx.cisd.common.exceptions.Status;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.SampleOwnerIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
 
 /**
  * An <code>IPredicate</code> implementation based on {@link SampleOwnerIdentifier}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/AbstractValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/AbstractValidator.java
index 256074f005b..d56a3c59076 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/AbstractValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/AbstractValidator.java
@@ -16,7 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * An <i>abstract</i> <code>IValidator</code> implementation which mainly checks method
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/BaseExperimentValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/BaseExperimentValidator.java
index 3752bd1fdcc..2676ae0dc26 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/BaseExperimentValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/BaseExperimentValidator.java
@@ -16,9 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
-import ch.systemsx.cisd.lims.base.dto.BaseExperiment;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.BaseExperiment;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * A {@link IValidator} implementation suitable for {@link BaseExperiment}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/DatabaseInstanceValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/DatabaseInstanceValidator.java
index 5cc4da05afd..7fe0f80d2de 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/DatabaseInstanceValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/DatabaseInstanceValidator.java
@@ -18,9 +18,9 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
 import java.util.List;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 
 /**
  * A {@link IValidator} implementation suitable for {@link DatabaseInstancePE}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidator.java
index 72b1276a612..841a1a7cffc 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/ExternalDataValidator.java
@@ -16,9 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
-import ch.systemsx.cisd.lims.base.dto.ExternalDataPE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * A {@link IValidator} implementation suitable for {@link ExternalDataPE}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidator.java
index 0200b356d63..5a654c282a4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidator.java
@@ -18,9 +18,9 @@ package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
 import java.util.List;
 
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 
 /**
  * A {@link IValidator} implementation suitable for {@link GroupPE}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/IValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/IValidator.java
index 3cc26fbd75c..963ddb18ceb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/IValidator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/IValidator.java
@@ -16,8 +16,8 @@
 
 package ch.systemsx.cisd.openbis.generic.server.authorization.validator;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.ValidatorStore;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * Performs some validation which returns <code>true</code> or <code>false</code> based on the
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IAuthorizationDAOFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IAuthorizationDAOFactory.java
index 6f01ed9cc51..8bd39353ff2 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IAuthorizationDAOFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IAuthorizationDAOFactory.java
@@ -16,7 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.server.dataaccess;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 
 /**
  * Factory definition for all Data Access Objects which are needed for managing authorization.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDatabaseInstanceDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDatabaseInstanceDAO.java
index ceedbbf3830..c71caf4495c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDatabaseInstanceDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDatabaseInstanceDAO.java
@@ -22,7 +22,7 @@ import org.springframework.dao.DataAccessException;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.dao.IncorrectResultSizeDataAccessException;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 
 /**
  * An interface that contains all data access operations on {@link DatabaseInstancePE}s.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IGroupDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IGroupDAO.java
index e1135b34e78..abee69648e6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IGroupDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IGroupDAO.java
@@ -21,8 +21,8 @@ import java.util.List;
 import org.springframework.dao.DataAccessException;
 import org.springframework.dao.EmptyResultDataAccessException;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 
 /**
  * <i>Data Access Object</i> for {@link GroupPE}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IPersonDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IPersonDAO.java
index 877ecf7237b..5b9340a4e33 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IPersonDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IPersonDAO.java
@@ -20,7 +20,7 @@ import java.util.List;
 
 import org.springframework.dao.DataAccessException;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * <i>Data Access Object</i> for persons.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
index 4b06ea00560..42ff809b3c9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IRoleAssignmentDAO.java
@@ -20,8 +20,8 @@ import java.util.List;
 
 import org.springframework.dao.DataAccessException;
 
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 
 /**
  * <i>Data Access Object</i> for {@link RoleAssignmentPE}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java
index 17ca7c69e65..0472709514a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom022To023.java
@@ -1,65 +1,65 @@
-/*
- * Copyright 2008 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
-
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.IncorrectResultSizeDataAccessException;
-import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
-
-import ch.systemsx.cisd.dbmigration.java.IMigrationStep;
-import ch.systemsx.cisd.lims.base.dto.TableNames;
-import ch.systemsx.cisd.openbis.generic.server.util.UuidUtil;
-
-/**
- * Finishes migration of the database version 22 to version 23 by setting the <i>UUID</i> code of
- * the database instance.
- * <p>
- * Note that, at that time, the <i>UUID</i> column label was <code>GLOBAL_CODE</code> and not
- * <code>UUID</code>.
- * </p>
- * 
- * @author Tomasz Pylak
- */
-public final class MigrationStepFrom022To023 implements IMigrationStep
-{
-    //
-    // IMigrationStep
-    //
-
-    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
-            throws DataAccessException
-    {
-        final String uuid = UuidUtil.generateUUID();
-        final int count =
-                simpleJdbcTemplate.queryForInt(String.format("select count(*) from %s",
-                        TableNames.DATABASE_INSTANCES_TABLE));
-        if (count == 1)
-        {
-            simpleJdbcTemplate.update(String.format("update %s set GLOBAL_CODE = ?",
-                    TableNames.DATABASE_INSTANCES_TABLE), uuid);
-        } else
-        {
-            throw new IncorrectResultSizeDataAccessException(1, count);
-        }
-    }
-
-    public final void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
-            throws DataAccessException
-    {
-    }
-
-}
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+
+import ch.systemsx.cisd.dbmigration.java.IMigrationStep;
+import ch.systemsx.cisd.openbis.generic.server.util.UuidUtil;
+import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
+
+/**
+ * Finishes migration of the database version 22 to version 23 by setting the <i>UUID</i> code of
+ * the database instance.
+ * <p>
+ * Note that, at that time, the <i>UUID</i> column label was <code>GLOBAL_CODE</code> and not
+ * <code>UUID</code>.
+ * </p>
+ * 
+ * @author Tomasz Pylak
+ */
+public final class MigrationStepFrom022To023 implements IMigrationStep
+{
+    //
+    // IMigrationStep
+    //
+
+    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
+            throws DataAccessException
+    {
+        final String uuid = UuidUtil.generateUUID();
+        final int count =
+                simpleJdbcTemplate.queryForInt(String.format("select count(*) from %s",
+                        TableNames.DATABASE_INSTANCES_TABLE));
+        if (count == 1)
+        {
+            simpleJdbcTemplate.update(String.format("update %s set GLOBAL_CODE = ?",
+                    TableNames.DATABASE_INSTANCES_TABLE), uuid);
+        } else
+        {
+            throw new IncorrectResultSizeDataAccessException(1, count);
+        }
+    }
+
+    public final void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
+            throws DataAccessException
+    {
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java
index d132a8d79a4..4da1aaee7f8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom023To024.java
@@ -1,188 +1,188 @@
-/*
- * Copyright 2008 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.log4j.Logger;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.dao.IncorrectResultSizeDataAccessException;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
-
-import ch.systemsx.cisd.common.collections.CollectionUtils;
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
-import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter;
-import ch.systemsx.cisd.lims.base.dto.TableNames;
-
-/**
- * A migration step from database version <code>v23</code> to version <code>v24</code>.
- * <p>
- * This migration step does the following: it migrate the dataset locations in the database (<code>Instance_&lt;instance code&gt;</code>
- * renamed Instance_&lt;UUID&gt; when &lt;instance code&gt; is the original source).
- * </p>
- * 
- * @author Christian Ribeaud
- */
-public final class MigrationStepFrom023To024 extends MigrationStepAdapter
-{
-    private static final String INSTANCE_PREFIX = "Instance_";
-
-    private static final Logger operationLog =
-            LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom023To024.class);
-
-    private final static ParameterizedRowMapper<DatabaseInstance> DATABASE_ROW_MAPPER =
-            new ParameterizedRowMapper<DatabaseInstance>()
-                {
-
-                    //
-                    // ParameterizedRowMapper
-                    //
-
-                    public final DatabaseInstance mapRow(final ResultSet rs, final int rowNum)
-                            throws SQLException
-                    {
-                        final String code = rs.getString("code");
-                        final String uuid = rs.getString("uuid");
-                        return new DatabaseInstance(code, uuid);
-                    }
-                };
-
-    private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER =
-            new ParameterizedRowMapper<ExternalData>()
-                {
-                    //
-                    // ParameterizedRowMapper
-                    //
-                    public final ExternalData mapRow(final ResultSet rs, final int rowNum)
-                            throws SQLException
-                    {
-                        final long id = rs.getLong("data_id");
-                        final String location = rs.getString("location");
-                        return new ExternalData(id, location);
-                    }
-                };
-
-    private final static DatabaseInstance getDatabaseInstance(
-            final SimpleJdbcTemplate simpleJdbcTemplate)
-    {
-        final DatabaseInstance databaseInstance =
-                simpleJdbcTemplate.queryForObject(String.format(
-                        "select uuid, code from %s where is_original_source = ?",
-                        TableNames.DATABASE_INSTANCES_TABLE), DATABASE_ROW_MAPPER, true);
-        return databaseInstance;
-    }
-
-    final static String getNewLocation(final ExternalData externalData,
-            final DatabaseInstance databaseInstance)
-    {
-        final String location = externalData.location;
-        final int index = location.indexOf('/');
-        if (index < 0)
-        {
-            throw new DataIntegrityViolationException(String.format(
-                    "No '/' found in location of externa data '%s'.", externalData));
-        }
-        final String afterInstance = location.substring(index);
-        return INSTANCE_PREFIX + databaseInstance.uuid + afterInstance;
-    }
-
-    //
-    // MigrationStepAdapter
-    //
-
-    @Override
-    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
-            throws DataAccessException
-    {
-        final DatabaseInstance databaseInstance = getDatabaseInstance(simpleJdbcTemplate);
-        final List<ExternalData> externalDatas =
-                simpleJdbcTemplate.query(String.format(
-                        "select data_id, location from %s where location like 'Instance_%s%%'",
-                        TableNames.EXTERNAL_DATA_TABLE, databaseInstance.code),
-                        EXTERNAL_DATA_ROW_MAPPER);
-        if (externalDatas.size() == 0)
-        {
-            operationLog.info("No data set location has been migrated.");
-        } else
-        {
-            for (final ExternalData externalData : externalDatas)
-            {
-                final int updated =
-                        simpleJdbcTemplate.update(String.format(
-                                "update %s set location = ? where data_id = ?",
-                                TableNames.EXTERNAL_DATA_TABLE), getNewLocation(externalData,
-                                databaseInstance), externalData.id);
-                if (updated != 1)
-                {
-                    throw new IncorrectResultSizeDataAccessException(1, updated);
-                }
-            }
-            operationLog.info(String.format(
-                    "Following data set locations '%s' have been migrated.", CollectionUtils
-                            .abbreviate(externalDatas, 10)));
-        }
-    }
-
-    //
-    // Helper classes
-    //
-
-    final static class DatabaseInstance
-    {
-
-        final String code;
-
-        final String uuid;
-
-        DatabaseInstance(final String code, final String uuid)
-        {
-            this.code = code;
-            this.uuid = uuid;
-        }
-    }
-
-    final static class ExternalData
-    {
-        final long id;
-
-        final String location;
-
-        ExternalData(final long id, final String location)
-        {
-            this.id = id;
-            this.location = location;
-        }
-
-        //
-        // ExternalData
-        //
-
-        @Override
-        public final String toString()
-        {
-            return ToStringBuilder.reflectionToString(this,
-                    ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
-        }
-    }
-}
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.log4j.Logger;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+
+import ch.systemsx.cisd.common.collections.CollectionUtils;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
+
+/**
+ * A migration step from database version <code>v23</code> to version <code>v24</code>.
+ * <p>
+ * This migration step does the following: it migrate the dataset locations in the database (<code>Instance_&lt;instance code&gt;</code>
+ * renamed Instance_&lt;UUID&gt; when &lt;instance code&gt; is the original source).
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class MigrationStepFrom023To024 extends MigrationStepAdapter
+{
+    private static final String INSTANCE_PREFIX = "Instance_";
+
+    private static final Logger operationLog =
+            LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom023To024.class);
+
+    private final static ParameterizedRowMapper<DatabaseInstance> DATABASE_ROW_MAPPER =
+            new ParameterizedRowMapper<DatabaseInstance>()
+                {
+
+                    //
+                    // ParameterizedRowMapper
+                    //
+
+                    public final DatabaseInstance mapRow(final ResultSet rs, final int rowNum)
+                            throws SQLException
+                    {
+                        final String code = rs.getString("code");
+                        final String uuid = rs.getString("uuid");
+                        return new DatabaseInstance(code, uuid);
+                    }
+                };
+
+    private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER =
+            new ParameterizedRowMapper<ExternalData>()
+                {
+                    //
+                    // ParameterizedRowMapper
+                    //
+                    public final ExternalData mapRow(final ResultSet rs, final int rowNum)
+                            throws SQLException
+                    {
+                        final long id = rs.getLong("data_id");
+                        final String location = rs.getString("location");
+                        return new ExternalData(id, location);
+                    }
+                };
+
+    private final static DatabaseInstance getDatabaseInstance(
+            final SimpleJdbcTemplate simpleJdbcTemplate)
+    {
+        final DatabaseInstance databaseInstance =
+                simpleJdbcTemplate.queryForObject(String.format(
+                        "select uuid, code from %s where is_original_source = ?",
+                        TableNames.DATABASE_INSTANCES_TABLE), DATABASE_ROW_MAPPER, true);
+        return databaseInstance;
+    }
+
+    final static String getNewLocation(final ExternalData externalData,
+            final DatabaseInstance databaseInstance)
+    {
+        final String location = externalData.location;
+        final int index = location.indexOf('/');
+        if (index < 0)
+        {
+            throw new DataIntegrityViolationException(String.format(
+                    "No '/' found in location of externa data '%s'.", externalData));
+        }
+        final String afterInstance = location.substring(index);
+        return INSTANCE_PREFIX + databaseInstance.uuid + afterInstance;
+    }
+
+    //
+    // MigrationStepAdapter
+    //
+
+    @Override
+    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
+            throws DataAccessException
+    {
+        final DatabaseInstance databaseInstance = getDatabaseInstance(simpleJdbcTemplate);
+        final List<ExternalData> externalDatas =
+                simpleJdbcTemplate.query(String.format(
+                        "select data_id, location from %s where location like 'Instance_%s%%'",
+                        TableNames.EXTERNAL_DATA_TABLE, databaseInstance.code),
+                        EXTERNAL_DATA_ROW_MAPPER);
+        if (externalDatas.size() == 0)
+        {
+            operationLog.info("No data set location has been migrated.");
+        } else
+        {
+            for (final ExternalData externalData : externalDatas)
+            {
+                final int updated =
+                        simpleJdbcTemplate.update(String.format(
+                                "update %s set location = ? where data_id = ?",
+                                TableNames.EXTERNAL_DATA_TABLE), getNewLocation(externalData,
+                                databaseInstance), externalData.id);
+                if (updated != 1)
+                {
+                    throw new IncorrectResultSizeDataAccessException(1, updated);
+                }
+            }
+            operationLog.info(String.format(
+                    "Following data set locations '%s' have been migrated.", CollectionUtils
+                            .abbreviate(externalDatas, 10)));
+        }
+    }
+
+    //
+    // Helper classes
+    //
+
+    final static class DatabaseInstance
+    {
+
+        final String code;
+
+        final String uuid;
+
+        DatabaseInstance(final String code, final String uuid)
+        {
+            this.code = code;
+            this.uuid = uuid;
+        }
+    }
+
+    final static class ExternalData
+    {
+        final long id;
+
+        final String location;
+
+        ExternalData(final long id, final String location)
+        {
+            this.id = id;
+            this.location = location;
+        }
+
+        //
+        // ExternalData
+        //
+
+        @Override
+        public final String toString()
+        {
+            return ToStringBuilder.reflectionToString(this,
+                    ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java
index 8a9b1390cbb..74d5a39e122 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/migration/MigrationStepFrom025To026.java
@@ -1,147 +1,147 @@
-/*
- * Copyright 2008 ETH Zuerich, CISD
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.log4j.Logger;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.IncorrectResultSizeDataAccessException;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
-
-import ch.systemsx.cisd.common.collections.CollectionUtils;
-import ch.systemsx.cisd.common.logging.LogCategory;
-import ch.systemsx.cisd.common.logging.LogFactory;
-import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
-import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter;
-import ch.systemsx.cisd.lims.base.dto.TableNames;
-
-/**
- * A migration step from database version <code>v25</code> to version <code>v26</code>.
- * <p>
- * Adapts the data set locations in database after OBSERVABLE_TYPE has been renamed to
- * DATA_SET_TYPE.
- * </p>
- * 
- * @author Izabela Adamczyk
- */
-public final class MigrationStepFrom025To026 extends MigrationStepAdapter
-{
-
-    private static final String OBSERVABLE_TYPE_PREFIX = "/ObservableType_";
-
-    private static final String DATA_SET_TYPE_PREFIX = "/DataSetType_";
-
-    private static final Logger operationLog =
-            LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom025To026.class);
-
-    private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER =
-            new ParameterizedRowMapper<ExternalData>()
-                {
-                    public final ExternalData mapRow(final ResultSet rs, final int rowNum)
-                            throws SQLException
-                    {
-                        final long id = rs.getLong("data_id");
-                        final String location = rs.getString("location");
-                        return new ExternalData(id, location);
-                    }
-                };
-
-    public final static String getNewLocation(final String oldLocation)
-    {
-        final int index = oldLocation.indexOf(OBSERVABLE_TYPE_PREFIX);
-        if (index < 0)
-        {
-            StringBuilder builder = new StringBuilder();
-            builder.append("WARNING: ");
-            builder.append("No ");
-            builder.append(OBSERVABLE_TYPE_PREFIX);
-            builder.append(" found in external data location '");
-            builder.append(oldLocation);
-            builder.append("'.");
-            operationLog.warn(builder.toString());
-            return oldLocation;
-        }
-        return oldLocation.replaceFirst(OBSERVABLE_TYPE_PREFIX, DATA_SET_TYPE_PREFIX);
-    }
-
-    //
-    // MigrationStepAdapter
-    //
-
-    @Override
-    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
-            throws DataAccessException
-    {
-
-        final List<ExternalData> externalDatas =
-                simpleJdbcTemplate.query(String.format("select data_id, location from %s",
-                        TableNames.EXTERNAL_DATA_TABLE), EXTERNAL_DATA_ROW_MAPPER);
-        if (externalDatas.size() == 0)
-        {
-            operationLog.info("No data set location has been migrated.");
-        } else
-        {
-            List<ExternalData> migrated = new ArrayList<ExternalData>();
-            for (final ExternalData externalData : externalDatas)
-            {
-                String oldLocation = externalData.location;
-                String newLocation = getNewLocation(externalData.location);
-                if (newLocation.equals(oldLocation) == false)
-                {
-                    final int updated =
-                            simpleJdbcTemplate.update(String.format(
-                                    "update %s set location = ? where data_id = ?",
-                                    TableNames.EXTERNAL_DATA_TABLE), newLocation, externalData.id);
-                    if (updated != 1)
-                    {
-                        throw new IncorrectResultSizeDataAccessException(1, updated);
-                    }
-                    migrated.add(externalData);
-                }
-            }
-            operationLog.info(String.format(
-                    "Following data set locations '%s' have been migrated.", CollectionUtils
-                            .abbreviate(migrated, 10)));
-        }
-    }
-
-    final static class ExternalData
-    {
-        final long id;
-
-        final String location;
-
-        ExternalData(final long id, final String location)
-        {
-            this.id = id;
-            this.location = location;
-        }
-
-        @Override
-        public final String toString()
-        {
-            return ToStringBuilder.reflectionToString(this,
-                    ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
-        }
-    }
-}
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.migration;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.log4j.Logger;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.IncorrectResultSizeDataAccessException;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+
+import ch.systemsx.cisd.common.collections.CollectionUtils;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.dbmigration.java.MigrationStepAdapter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.TableNames;
+
+/**
+ * A migration step from database version <code>v25</code> to version <code>v26</code>.
+ * <p>
+ * Adapts the data set locations in database after OBSERVABLE_TYPE has been renamed to
+ * DATA_SET_TYPE.
+ * </p>
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class MigrationStepFrom025To026 extends MigrationStepAdapter
+{
+
+    private static final String OBSERVABLE_TYPE_PREFIX = "/ObservableType_";
+
+    private static final String DATA_SET_TYPE_PREFIX = "/DataSetType_";
+
+    private static final Logger operationLog =
+            LogFactory.getLogger(LogCategory.OPERATION, MigrationStepFrom025To026.class);
+
+    private final static ParameterizedRowMapper<ExternalData> EXTERNAL_DATA_ROW_MAPPER =
+            new ParameterizedRowMapper<ExternalData>()
+                {
+                    public final ExternalData mapRow(final ResultSet rs, final int rowNum)
+                            throws SQLException
+                    {
+                        final long id = rs.getLong("data_id");
+                        final String location = rs.getString("location");
+                        return new ExternalData(id, location);
+                    }
+                };
+
+    public final static String getNewLocation(final String oldLocation)
+    {
+        final int index = oldLocation.indexOf(OBSERVABLE_TYPE_PREFIX);
+        if (index < 0)
+        {
+            StringBuilder builder = new StringBuilder();
+            builder.append("WARNING: ");
+            builder.append("No ");
+            builder.append(OBSERVABLE_TYPE_PREFIX);
+            builder.append(" found in external data location '");
+            builder.append(oldLocation);
+            builder.append("'.");
+            operationLog.warn(builder.toString());
+            return oldLocation;
+        }
+        return oldLocation.replaceFirst(OBSERVABLE_TYPE_PREFIX, DATA_SET_TYPE_PREFIX);
+    }
+
+    //
+    // MigrationStepAdapter
+    //
+
+    @Override
+    public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate)
+            throws DataAccessException
+    {
+
+        final List<ExternalData> externalDatas =
+                simpleJdbcTemplate.query(String.format("select data_id, location from %s",
+                        TableNames.EXTERNAL_DATA_TABLE), EXTERNAL_DATA_ROW_MAPPER);
+        if (externalDatas.size() == 0)
+        {
+            operationLog.info("No data set location has been migrated.");
+        } else
+        {
+            List<ExternalData> migrated = new ArrayList<ExternalData>();
+            for (final ExternalData externalData : externalDatas)
+            {
+                String oldLocation = externalData.location;
+                String newLocation = getNewLocation(externalData.location);
+                if (newLocation.equals(oldLocation) == false)
+                {
+                    final int updated =
+                            simpleJdbcTemplate.update(String.format(
+                                    "update %s set location = ? where data_id = ?",
+                                    TableNames.EXTERNAL_DATA_TABLE), newLocation, externalData.id);
+                    if (updated != 1)
+                    {
+                        throw new IncorrectResultSizeDataAccessException(1, updated);
+                    }
+                    migrated.add(externalData);
+                }
+            }
+            operationLog.info(String.format(
+                    "Following data set locations '%s' have been migrated.", CollectionUtils
+                            .abbreviate(migrated, 10)));
+        }
+    }
+
+    final static class ExternalData
+    {
+        final long id;
+
+        final String location;
+
+        ExternalData(final long id, final String location)
+        {
+            this.id = id;
+            this.location = location;
+        }
+
+        @Override
+        public final String toString()
+        {
+            return ToStringBuilder.reflectionToString(this,
+                    ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/GroupIdentifierHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/GroupIdentifierHelper.java
index 29f4c3bdc37..ffb0e512a07 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/GroupIdentifierHelper.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/GroupIdentifierHelper.java
@@ -21,15 +21,15 @@ import java.util.List;
 import ch.systemsx.cisd.common.collections.TableMap;
 import ch.systemsx.cisd.common.exceptions.InternalErr;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.exception.UndefinedGroupException;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
-import ch.systemsx.cisd.lims.base.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGroupDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.exception.UndefinedGroupException;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 
 /**
  * Some useful identifier methods on the <i>server</i> side.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/KeyExtractorFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/KeyExtractorFactory.java
index e8773699c8b..4aeb879fc0e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/KeyExtractorFactory.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/KeyExtractorFactory.java
@@ -17,16 +17,15 @@
 package ch.systemsx.cisd.openbis.generic.server.util;
 
 import ch.systemsx.cisd.common.collections.IKeyExtractor;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.ExperimentPE;
-import ch.systemsx.cisd.lims.base.dto.IIdAndCodeHolder;
-import ch.systemsx.cisd.lims.base.dto.IIdHolder;
-import ch.systemsx.cisd.lims.base.dto.MaterialPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.PropertyTypePE;
-import ch.systemsx.cisd.lims.base.dto.SampleComponentDTO;
-import ch.systemsx.cisd.lims.base.dto.SamplePE;
-import ch.systemsx.cisd.lims.base.dto.VocabularyTermPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IIdAndCodeHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IIdHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermPE;
 
 /**
  * A <code>IdKeyExtractor</code> factory.
@@ -41,9 +40,6 @@ public final class KeyExtractorFactory
     private final static IKeyExtractor<String, DatabaseInstancePE> DATABASE_INSTANCE_BY_UUID_KEY_EXTRACTOR =
             new UUIDKeyExtractor();
 
-    private final static IKeyExtractor<String, SampleComponentDTO> SAMPLE_COMPONENT_BY_CODE_KEY_EXTRACTOR =
-            createCodeKeyExtractor();
-
     private final static IKeyExtractor<Long, ExperimentPE> BASE_EXPERIMENT_BY_ID_KEY_EXTRACTOR =
             createIdKeyExtractor();
 
@@ -159,15 +155,6 @@ public final class KeyExtractorFactory
         return PERSON_BY_ID_KEY_EXTRACTOR;
     }
 
-    /**
-     * Returns an <code>IKeyExtractor</code> for <i>SampleComponentDTO</i> based on
-     * {@link SampleComponentDTO#getCode()}.
-     */
-    public final static IKeyExtractor<String, SampleComponentDTO> getSampleComponentByCode()
-    {
-        return SAMPLE_COMPONENT_BY_CODE_KEY_EXTRACTOR;
-    }
-
     //
     // Helper classes
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/UuidUtil.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/UuidUtil.java
index fce603852aa..dcd039a4ca8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/UuidUtil.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/util/UuidUtil.java
@@ -21,7 +21,7 @@ import java.util.regex.Pattern;
 
 import org.apache.commons.lang.StringUtils;
 
-import ch.systemsx.cisd.lims.base.util.CodeConverter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.CodeConverter;
 
 /**
  * Some utility methods based on {@link UUID}.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/GenericSharedConstants.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/GenericSharedConstants.java
new file mode 100644
index 00000000000..6de09a87ec1
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/GenericSharedConstants.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class GenericSharedConstants
+{
+    /**
+     * Everytime some public class in this package or subpackages are are changed, we should
+     * increment this.
+     */
+    public static final int VERSION = 28; // for release S40
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
index 05c003a652f..fa36932570a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IGenericServer.java
@@ -18,9 +18,9 @@ package ch.systemsx.cisd.openbis.generic.shared;
 
 import java.util.List;
 
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 
 /**
  * Definition of the client-server interface.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractAttachmentPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractAttachmentPE.java
new file mode 100644
index 00000000000..d6392da30c8
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractAttachmentPE.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.SequenceGenerator;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Superclass to store attachment. Does not contain attachment content.
+ * 
+ * @author Christian Ribeaud
+ * @author Tomasz Pylak
+ */
+@MappedSuperclass
+public class AbstractAttachmentPE extends HibernateAbstractRegistratrationHolder implements
+        Serializable, Comparable<AbstractAttachmentPE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String fileName;
+
+    private int version;
+
+    transient private Long id;
+
+    // TODO 2008-08-21, Christian Ribeaud: Put the experiment here instead of the id once it has
+    // been hibernated.
+    /**
+     * Id of the parent (e.g. an experiment) to which this attachment belongs.
+     */
+    transient private Long parentId;
+
+    /**
+     * Returns the file name of the property or <code>null</code>.
+     */
+    @Column(name = ColumnNames.FILE_NAME_COLUMN)
+    @NotNull(message = ValidationMessages.FILE_NAME_NOT_NULL_MESSAGE)
+    @Length(max = 100, message = ValidationMessages.FILE_NAME_LENGTH_MESSAGE)
+    public String getFileName()
+    {
+        return fileName;
+    }
+
+    public void setFileName(final String fileName)
+    {
+        this.fileName = fileName;
+    }
+
+    @Column(name = ColumnNames.VERSION_COLUMN)
+    @NotNull(message = ValidationMessages.VERSION_NOT_NULL_MESSAGE)
+    public int getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion(final int version)
+    {
+        this.version = version;
+    }
+
+    @SequenceGenerator(name = SequenceNames.EXPERIMENT_ATTACHMENT_SEQUENCE, sequenceName = SequenceNames.EXPERIMENT_ATTACHMENT_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.EXPERIMENT_ATTACHMENT_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @Column(name = ColumnNames.EXPERIMENT_COLUMN)
+    @NotNull(message = ValidationMessages.EXPERIMENT_NOT_NULL_MESSAGE)
+    public Long getParentId()
+    {
+        return parentId;
+    }
+
+    public void setParentId(final Long parentId)
+    {
+        this.parentId = parentId;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof AbstractAttachmentPE == false)
+        {
+            return false;
+        }
+        final AbstractAttachmentPE that = (AbstractAttachmentPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(fileName, that.fileName);
+        builder.append(version, that.version);
+        builder.append(parentId, that.parentId);
+        return builder.isEquals();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(fileName);
+        builder.append(version);
+        builder.append(parentId);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Comparable
+    //
+
+    public final int compareTo(final AbstractAttachmentPE o)
+    {
+        final int byFile = getFileName().compareTo(o.getFileName());
+        return byFile == 0 ? Integer.valueOf(getVersion()).compareTo(o.getVersion()) : byFile;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractEntity.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractEntity.java
new file mode 100644
index 00000000000..60b976967d7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractEntity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Abstract super class of all Data Transfer Objects having {@link SimpleEntityProperty}s.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractEntity<T extends AbstractEntity<T>> extends Code<T> implements
+        ISimpleEntityPropertiesHolder
+{
+    private static final long serialVersionUID = 1L;
+
+    private SimpleEntityProperty[] properties;
+
+    //
+    // IEntityPropertiesHolder
+    //
+
+    public final SimpleEntityProperty[] getProperties()
+    {
+        return properties;
+    }
+
+    public final void setProperties(final SimpleEntityProperty[] properties)
+    {
+        this.properties = properties;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractIdAndCodeHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractIdAndCodeHolder.java
new file mode 100644
index 00000000000..f28d33286e7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractIdAndCodeHolder.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * An <i>abstract</i> implementation of {@link IIdAndCodeHolder}
+ * 
+ * @author Christian Ribeaud
+ */
+public abstract class AbstractIdAndCodeHolder<T extends IIdAndCodeHolder> implements
+        IIdAndCodeHolder, Comparable<T>, Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static String CODE_PATTERN = "^[A-Z0-9_\\-]+$";
+
+    /**
+     * A static method for comparing two {@link IIdAndCodeHolder}s.
+     */
+    public final static int compare(final IIdAndCodeHolder o1, IIdAndCodeHolder o2)
+    {
+        return IdAndCodeHolderComparator.INSTANCE.compare(o1, o2);
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof IIdAndCodeHolder == false)
+        {
+            return false;
+        }
+        final IIdAndCodeHolder that = (IIdAndCodeHolder) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Compare
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(final T o)
+    {
+        return compare(this, o);
+    }
+
+    //
+    // Helper classes
+    //
+
+    private final static class IdAndCodeHolderComparator implements Comparator<IIdAndCodeHolder>
+    {
+
+        static final Comparator<IIdAndCodeHolder> INSTANCE = new IdAndCodeHolderComparator();
+
+        //
+        // Comparator
+        //
+
+        public final int compare(final IIdAndCodeHolder o1, final IIdAndCodeHolder o2)
+        {
+            final String thatCode = o2.getCode();
+            if (o1.getCode() == null)
+            {
+                return thatCode == null ? 0 : -1;
+            }
+            if (thatCode == null)
+            {
+                return 1;
+            }
+            return o1.getCode().compareTo(thatCode);
+
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractRegistratrationHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractRegistratrationHolder.java
new file mode 100644
index 00000000000..1963186759f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractRegistratrationHolder.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+
+/**
+ * Super class of DTOs which hold registration data.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractRegistratrationHolder extends Id implements IRegistratorHolder
+{
+    private static final long serialVersionUID = 1L;
+
+    /** Technical ID of the person who registered this entity. */
+    private final Long registratorID;
+
+    /**
+     * Person who registered this entity.
+     * <p>
+     * This is specified at insert time.
+     * </p>
+     */
+    private PersonPE registrator;
+
+    /**
+     * Registration date of this entity.
+     * <p>
+     * This is specified at insert time.
+     * </p>
+     */
+    private Date registrationDate;
+
+    protected AbstractRegistratrationHolder(final Long registratorID)
+    {
+        this.registratorID = registratorID;
+    }
+
+    public final Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    public final void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    //
+    // IRegistratorHolder
+    //
+
+    /**
+     * Returns registratorID.
+     */
+    public final Long getRegistratorID()
+    {
+        return registrator == null ? registratorID : registrator.getId();
+    }
+
+    /**
+     * Returns the registrator or <code>null</code> if not known.
+     */
+    public final PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    /**
+     * Sets the person who has registered the experiment.
+     * 
+     * @throws AssertionError if <code>registratorID</code> is defined but unequal
+     *             <code>registrator.getId()</code>.
+     */
+    public final void setRegistrator(final PersonPE registrator)
+    {
+        getAndCheckID(registrator, registratorID);
+        this.registrator = registrator;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractTypePE.java
new file mode 100644
index 00000000000..1d0dbf8843c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AbstractTypePE.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.MappedSuperclass;
+
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Abstract Persistence Entity representing a type.
+ * 
+ * @author Izabela Adamczyk
+ */
+@MappedSuperclass
+public abstract class AbstractTypePE extends AbstractIdAndCodeHolder<AbstractTypePE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    transient protected Long id;
+
+    private String code;
+
+    private String description;
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    public AbstractTypePE(final long id, final String code, final String description)
+    {
+        setId(id);
+        setCode(code);
+        setDescription(description);
+    }
+
+    public AbstractTypePE()
+    {
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 80, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AttachmentPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AttachmentPE.java
new file mode 100644
index 00000000000..14a26d15442
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/AttachmentPE.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Contains information about an attachment. Does not contain attachment content.<br>
+ * NOTE: this class does not add anything to the superclass. It exists only because superclasses
+ * cannot be mapped to tables in Hibernate.
+ * 
+ * @author Tomasz Pylak
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENT_ATTACHMENTS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.EXPERIMENT_COLUMN, ColumnNames.FILE_NAME_COLUMN, ColumnNames.VERSION_COLUMN }) })
+public class AttachmentPE extends AbstractAttachmentPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final List<AttachmentPE> EMPTY_LIST = new ArrayList<AttachmentPE>();
+
+    public static final AttachmentPE[] EMPTY_ARRAY = new AttachmentPE[0];
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/BaseExperiment.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/BaseExperiment.java
new file mode 100644
index 00000000000..74741fef1a3
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/BaseExperiment.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A basic <code>Experiment</code> object without procedures, samples, and data.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class BaseExperiment extends AbstractEntity<BaseExperiment>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private ExperimentType experimentType;
+
+    private Date registrationDate;
+
+    private PersonPE registrator;
+
+    private ProjectPE project;
+
+    private NewMaterial studyObject;
+
+    private ProcessingInstructionDTO[] processingInstructions;
+
+    private boolean invalidated;
+
+    private Date lastDataSetDate;
+
+    public final boolean isInvalidated()
+    {
+        return invalidated;
+    }
+
+    public final void setInvalidated(final boolean invalidated)
+    {
+        this.invalidated = invalidated;
+    }
+
+    public final ProcessingInstructionDTO[] getProcessingInstructions()
+    {
+        return processingInstructions;
+    }
+
+    public final void setProcessingInstructions(
+            final ProcessingInstructionDTO[] processingInstructions)
+    {
+        this.processingInstructions = processingInstructions;
+    }
+
+    public final NewMaterial getStudyObject()
+    {
+        return studyObject;
+    }
+
+    public final void setStudyObject(final NewMaterial material)
+    {
+        this.studyObject = material;
+    }
+
+    public final Date getLastDataSetDate()
+    {
+        return lastDataSetDate;
+    }
+
+    public final void setLastDataSetDate(final Date lastDataSetDate)
+    {
+        this.lastDataSetDate = lastDataSetDate;
+    }
+
+    public Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    public PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    public void setRegistrator(final PersonPE registrator)
+    {
+        this.registrator = registrator;
+    }
+
+    public final ProjectPE getProject()
+    {
+        return project;
+    }
+
+    public final void setProject(final ProjectPE project)
+    {
+        this.project = project;
+    }
+
+    public final ExperimentType getExperimentType()
+    {
+        return experimentType;
+    }
+
+    public final void setExperimentType(final ExperimentType experimentType)
+    {
+        this.experimentType = experimentType;
+    }
+
+    //
+    // AbstractEntity
+    //
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    public final EntityType getEntityType()
+    {
+        return getExperimentType();
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Code.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Code.java
new file mode 100644
index 00000000000..5f9f6f8e62d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Code.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A class that overrides {@link #equals(Object)}, {@link #hashCode()}, {@link #toString()} for a
+ * given <code>code</code>.
+ * <p>
+ * This class also implements {@link Comparable} interface.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public abstract class Code<T extends Code<T>> implements Serializable, Comparable<T>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String code;
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    @BeanProperty(label = "code")
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof Code == false)
+        {
+            return false;
+        }
+        final Code<?> that = (Code<?>) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.code, code);
+        return builder.isEquals();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(code);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public int compareTo(final T o)
+    {
+        final String thatCode = o.code;
+        if (code == null)
+        {
+            return thatCode == null ? 0 : -1;
+        }
+        if (thatCode == null)
+        {
+            return 1;
+        }
+        return code.compareTo(thatCode);
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/CodeConverter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/CodeConverter.java
new file mode 100644
index 00000000000..8c68cf1052d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/CodeConverter.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Methods for converter codes from business layer to database and from database to business layer.
+ * 
+ * @author Bernd Rinn
+ */
+public final class CodeConverter
+{
+    public static final String USER_PROPERTY_PREFIX = "USER.";
+
+    private CodeConverter()
+    {
+        // Cannot be instantiated.
+    }
+
+    /**
+     * Converts a code from database form to business layer form.
+     * 
+     * @return The code appropriate for the business layer.
+     */
+    public static String tryToBusinessLayer(final String codeFromDatabaseOrNull)
+    {
+        return tryToBusinessLayer(codeFromDatabaseOrNull, false);
+    }
+
+    /**
+     * Converts a code from database form to business layer form.
+     * <p>
+     * If <var>userNamespace</var> is <code>true</code>, the prefix 'USER.' will be used,
+     * because user properties will be represented as 'NAME' in the database and as USER.NAME in the
+     * business layer.
+     * 
+     * @return The code appropriate for the business layer.
+     */
+    public static String tryToBusinessLayer(final String codeFromDatabaseOrNull,
+            final boolean userNamespace)
+    {
+        if (userNamespace && codeFromDatabaseOrNull != null)
+        {
+            return USER_PROPERTY_PREFIX + codeFromDatabaseOrNull;
+        } else
+        {
+            return codeFromDatabaseOrNull;
+        }
+    }
+
+    /**
+     * Converts a property type code from business layer form to database form.
+     * <p>
+     * The code will be translated to upper case. User properties will be represented as 'NAME' in
+     * the database and as USER.NAME in the business layer.
+     * 
+     * @return The code appropriate for the database.
+     */
+    public static String tryToDatabase(final String codeFromBusinessLayerOrNull)
+    {
+        if (codeFromBusinessLayerOrNull == null)
+        {
+            return null;
+        }
+        final String upperCaseCode = codeFromBusinessLayerOrNull.toUpperCase();
+        if (upperCaseCode.startsWith(USER_PROPERTY_PREFIX))
+        {
+            return upperCaseCode.substring(USER_PROPERTY_PREFIX.length());
+        } else
+        {
+            return upperCaseCode;
+        }
+    }
+
+    /**
+     * Returns <code>true</code>, if the <var>codeFromBusinessLayerOrNull</var> represents a
+     * user property code.
+     */
+    public static boolean isInternalNamespace(final String codeFromBusinessLayerOrNull)
+    {
+        if (codeFromBusinessLayerOrNull == null)
+        {
+            return false;
+        } else
+        {
+            return codeFromBusinessLayerOrNull.toUpperCase().startsWith(USER_PROPERTY_PREFIX) == false;
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java
new file mode 100644
index 00000000000..1c19152b444
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ColumnNames.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * This class lists database field names commonly used.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ColumnNames
+{
+
+    public static final String CODE_COLUMN = "code";
+
+    public static final String CONTROL_LAYOUT_SAMPLE_COLUMN = "samp_id_control_layout";
+
+    public static final String CONTROLLED_VOCABULARY_COLUMN = "covo_id";
+
+    public static final String DATA_CHILD_COLUMN = "data_id_child";
+
+    public static final String DATA_ID_COLUMN = "data_id";
+
+    public static final String DATA_PARENT_COLUMN = "data_id_parent";
+
+    public static final String DATA_PRODUCER_CODE_COLUMN = "data_producer_code";
+
+    public static final String DATA_STORE_COLUMN = "dast_id";
+
+    public static final String DATA_TYPE_COLUMN = "daty_id";
+
+    public final static String DATABASE_INSTANCE_COLUMN = "dbin_id";
+
+    public static final String DESCRIPTION_COLUMN = "description";
+
+    public static final String DOWNLOAD_URL_COLUMN = "download_url";
+
+    public static final String EXPERIMENT_COLUMN = "expe_id";
+
+    public static final String EXPERIMENT_TYPE_COLUMN = "exty_id";
+
+    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_COLUMN = "etpt_id";
+
+    public static final String FILE_FORMAT_TYPE = "ffty_id";
+
+    public static final String FILE_NAME_COLUMN = "file_name";
+
+    public final static String FIRST_NAME_COLUMN = "first_name";
+
+    public static final String GENERATED_FROM_SAMPLE_COLUMN = "samp_id_generated_from";
+
+    public static final String GROUP_COLUMN = "grou_id";
+
+    public static final String GROUP_PARENT_COLUMN = "grou_id_parent";
+
+    public static final String ID_COLUMN = "id";
+
+    public static final String INHIBITOR_OF_COLUMN = "mate_id_inhibitor_of";
+
+    public static final String INVALIDATION_COLUMN = "inva_id";
+
+    public static final String IS_COMPLETE_COLUMN = "is_complete";
+
+    public static final String IS_DATA_CQUSITION = "is_data_acquisition";
+
+    public static final String IS_INTERNAL_NAMESPACE = "is_internal_namespace";
+
+    public static final String IS_MANAGED_INTERNALLY = "is_managed_internally";
+
+    public static final String IS_MANDATORY = "is_mandatory";
+
+    public static final String IS_ORIGINAL_SOURCE_COLUMN = "is_original_source";
+
+    public static final String IS_PLACEHOLDER_COLUMN = "is_placeholder";
+
+    public static final String LABEL_COLUMN = "label";
+
+    public final static String LAST_NAME_COLUMN = "last_name";
+
+    public static final String LOCATION_COLUMN = "location";
+
+    public static final String LOCATOR_TYPE_COLUMN = "loty_id";
+
+    public static final String MATERIAL_COLUMN = "mate_id";
+
+    public static final String MATERIAL_BATCH_COLUMN = "maba_id";
+
+    public static final String MATERIAL_TYPE_COLUMN = "maty_id";
+
+    public static final String MATERIAL_TYPE_PROPERTY_TYPE_COLUMN = "mtpt_id";
+
+    public static final String DATA_SET_TYPE_COLUMN = "dsty_id";
+
+    public static final String PARENT_DATA_SET_CODE_COLUMN = "data_producer_code";
+
+    public static final String PART_OF_SAMPLE_COLUMN = "samp_id_part_of";
+
+    public static final String PERSON_GRANTEE_COLUMN = "pers_id_grantee";
+
+    public static final String PERSON_LEADER_COLUMN = "pers_id_leader";
+
+    public static final String PERSON_REGISTERER_COLUMN = "pers_id_registerer";
+
+    public static final String PROCEDURE_COLUMN = "proc_id";
+
+    public static final String PROCEDURE_PRODUCED_BY_COLUMN = "proc_id_produced_by";
+
+    public static final String PROCEDURE_TYPE_COLUMN = "pcty_id";
+
+    public static final String PRODUCTION_TIMESTAMP_COLUMN = "production_timestamp";
+
+    public static final String PROJECT_COLUMN = "proj_id";
+
+    public static final String PROPERTY_TYPE_COLUMN = "prty_id";
+
+    public static final String REGISTRATION_TIMESTAMP_COLUMN = "registration_timestamp";
+
+    public final static String ROLE_COLUMN = "role_code";
+
+    public static final String SAMPLE_ACQUIRED_FROM = "samp_id_acquired_from";
+
+    public static final String SAMPLE_COLUMN = "samp_id";
+
+    public static final String SAMPLE_DERIVED_FROM = "samp_id_derived_from";
+
+    public static final String SAMPLE_TYPE_COLUMN = "saty_id";
+
+    public static final String SAMPLE_TYPE_PROPERTY_TYPE_COLUMN = "stpt_id";
+
+    public static final String STORAGE_FORMAT_COLUMN = "cvte_id_stor_fmt";
+
+    public static final String STUDY_OBJECT_COLUMN = "mate_id_study_object";
+
+    public static final String TOP_SAMPLE_COLUMN = "samp_id_top";
+
+    public final static String USER_COLUMN = "user_id";
+
+    public static final String UUID_COLUMN = "uuid";
+
+    public static final String VALUE = "value";
+
+    public static final String VERSION_COLUMN = "version";
+
+    public static final String VOCABULARY_TERM_COLUMN = "cvte_id";
+
+    public static final String AMOUNT_COLUMN = "amount";
+
+    private ColumnNames()
+    {
+        // Can not be instantiated.
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
new file mode 100644
index 00000000000..aef8a2f97d7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataPE.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.annotations.Check;
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which contains any information we would like to
+ * know about one DATA.
+ * <p>
+ * This class is the <i>Java Object</i> representation of the corresponding data in the database.
+ * </p>
+ * 
+ * @author Bernd Rinn
+ */
+@Entity
+@Table(name = TableNames.DATA_TABLE, uniqueConstraints = @UniqueConstraint(columnNames = ColumnNames.CODE_COLUMN))
+@Check(constraints = "(" + ColumnNames.SAMPLE_ACQUIRED_FROM + " IS NOT NULL AND "
+        + ColumnNames.SAMPLE_DERIVED_FROM + " IS NULL) OR (" + ColumnNames.SAMPLE_ACQUIRED_FROM
+        + " IS NULL AND " + ColumnNames.SAMPLE_DERIVED_FROM + " IS NOT NULL)")
+@Inheritance(strategy = InheritanceType.JOINED)
+public class DataPE extends AbstractIdAndCodeHolder<DataPE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final DataPE[] EMPTY_ARRAY = new DataPE[0];
+
+    public static final List<DataPE> EMPTY_LIST = Collections.emptyList();
+
+    private transient Long id;
+
+    private String code;
+
+    private boolean placeholder;
+
+    /** Registration date of the database instance. */
+    private Date registrationDate;
+
+    private DataSetTypePE dataSetType;
+
+    private ProcedurePE procedure;
+
+    private Date productionDate;
+
+    private String dataProducerCode;
+
+    private SamplePE sampleAcquiredFrom;
+
+    private SamplePE sampleDerivedFrom;
+
+    private List<DataPE> parents = EMPTY_LIST;
+
+    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false, updatable = false)
+    @Generated(GenerationTime.INSERT)
+    public Date getRegistrationDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(registrationDate);
+    }
+
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATA_SET_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATA_SET_TYPE_COLUMN, updatable = false)
+    /** Returns <code>dataSetType</code>. */
+    public DataSetTypePE getDataSetType()
+    {
+        return dataSetType;
+    }
+
+    /** Sets <code>dataSetType</code>. */
+    public void setDataSetType(final DataSetTypePE dataSetType)
+    {
+        this.dataSetType = dataSetType;
+    }
+
+    /**
+     * Returns <code>true</code> if this data set is a placeholder for a data set yet to arrive.
+     */
+    @Column(name = ColumnNames.IS_PLACEHOLDER_COLUMN)
+    public boolean isPlaceholder()
+    {
+        return placeholder;
+    }
+
+    /**
+     * Set to <code>true</code> if this data set is a placeholder for a data set yet to arrive.
+     */
+    public void setPlaceholder(final boolean placeholder)
+    {
+        this.placeholder = placeholder;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.SAMPLE_ACQUIRED_FROM, updatable = false)
+    public SamplePE getSampleAcquiredFrom()
+    {
+        return sampleAcquiredFrom;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.SAMPLE_DERIVED_FROM, updatable = false)
+    public SamplePE getSampleDerivedFrom()
+    {
+        return sampleDerivedFrom;
+    }
+
+    public void setSampleAcquiredFrom(final SamplePE sampleAcquiredFrom)
+    {
+        this.sampleAcquiredFrom = sampleAcquiredFrom;
+    }
+
+    public void setSampleDerivedFrom(final SamplePE sampleDerivedFrom)
+    {
+        this.sampleDerivedFrom = sampleDerivedFrom;
+    }
+
+    @Transient
+    public String getAssociatedSampleCode()
+    {
+        final SamplePE sample = sampleAcquiredFrom != null ? sampleAcquiredFrom : sampleDerivedFrom;
+        return sample != null ? sample.getCode() : null;
+    }
+
+    /**
+     * Returns the date when the measurement / calculation that produced this external data set has
+     * been performed.
+     * <p>
+     * This may not be known in which case this method will return <code>null</code>.
+     */
+    @Column(name = ColumnNames.PRODUCTION_TIMESTAMP_COLUMN, updatable = false)
+    public Date getProductionDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(productionDate);
+    }
+
+    /**
+     * Sets the date when the measurement / calculation that produced this external data set has
+     * been performed.
+     */
+    public void setProductionDate(final Date measurementDate)
+    {
+        this.productionDate = measurementDate;
+    }
+
+    /**
+     * Returns the code identifying the data source (i.e. measurement device or software pipeline)
+     * that produced this external data set.
+     * <p>
+     * This may not be known in which case this method will return <code>null</code>.
+     * </p>
+     */
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Column(name = ColumnNames.DATA_PRODUCER_CODE_COLUMN, updatable = false)
+    public String getDataProducerCode()
+    {
+        return dataProducerCode;
+    }
+
+    /**
+     * Sets the code identifying the data source (i.e. measurement device or software pipeline) that
+     * produced this external data set.
+     */
+    public void setDataProducerCode(final String dataProducerCode)
+    {
+        this.dataProducerCode = dataProducerCode;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    /**
+     * Sets the code (i.e. the externally used unique identifier) of this external data.
+     */
+    public void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+    @JoinTable(name = TableNames.DATA_SET_RELATIONSHIPS_TABLE, joinColumns = @JoinColumn(name = ColumnNames.DATA_CHILD_COLUMN), inverseJoinColumns = @JoinColumn(name = ColumnNames.DATA_PARENT_COLUMN))
+    public List<DataPE> getParents()
+    {
+        return parents;
+    }
+
+    public void setParents(final List<DataPE> parents)
+    {
+        this.parents = parents;
+    }
+
+    //
+    // AbstractIdAndCodeHolder
+    //
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.DATA_SEQUENCE, sequenceName = SequenceNames.DATA_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    @Column(unique = true)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    /** Returns <code>procedure</code>. */
+    @ManyToOne(fetch = FetchType.LAZY)
+    @NotNull(message = ValidationMessages.PROCEDURE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.PROCEDURE_PRODUCED_BY_COLUMN, updatable = false)
+    public ProcedurePE getProcedure()
+    {
+        return procedure;
+    }
+
+    /** Sets <code>procedure</code>. */
+    public void setProcedure(final ProcedurePE procedure)
+    {
+        this.procedure = procedure;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetType.java
new file mode 100644
index 00000000000..074c0f40c62
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetType.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about an data set type.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class DataSetType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public DataSetType()
+    {
+    }
+
+    public DataSetType(final String code)
+    {
+        setCode(code);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePE.java
new file mode 100644
index 00000000000..f0821591c8c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePE.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence Entity representing data set type.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.DATA_SET_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public class DataSetTypePE extends AbstractTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private DatabaseInstancePE databaseInstance;
+
+    @SequenceGenerator(name = SequenceNames.DATA_SET_TYPE_SEQUENCE, sequenceName = SequenceNames.DATA_SET_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_SET_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataStorePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataStorePE.java
new file mode 100644
index 00000000000..dc938c7ef41
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataStorePE.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistence Entity</i> which represents an entry in {@link TableNames#DATA_STORES_TABLE}.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.DATA_STORES_TABLE, uniqueConstraints = @UniqueConstraint(columnNames =
+    { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }))
+public final class DataStorePE extends AbstractIdAndCodeHolder<DataStorePE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    /**
+     * The code of this data store.
+     */
+    private String code;
+
+    /** Registration date of this data store. */
+    private Date registrationDate;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private String downloadUrl;
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @Column(name = ColumnNames.DOWNLOAD_URL_COLUMN, updatable = false)
+    @NotNull(message = ValidationMessages.DOWNLOAD_URL_NOT_NULL_MESSAGE)
+    public final String getDownloadUrl()
+    {
+        return downloadUrl;
+    }
+
+    public final void setDownloadUrl(final String downloadUrl)
+    {
+        this.downloadUrl = downloadUrl;
+    }
+
+    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false, updatable = false)
+    @Generated(GenerationTime.INSERT)
+    public final Date getRegistrationDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(registrationDate);
+    }
+
+    public final void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    //
+    // AbstractIdAndCodeHolder
+    //
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public final String getCode()
+    {
+        return code;
+    }
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.DATA_STORE_SEQUENCE, sequenceName = SequenceNames.DATA_STORE_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_STORE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataTypePE.java
new file mode 100644
index 00000000000..4833ea820af
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataTypePE.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityDataType;
+
+/**
+ * Persistence Entity representing 'data type'.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.DATA_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN }) })
+public final class DataTypePE implements IIdHolder, Serializable, Comparable<DataTypePE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    private EntityDataType code;
+
+    private String description;
+
+    @SequenceGenerator(name = SequenceNames.DATA_TYPE_SEQUENCE, sequenceName = SequenceNames.DATA_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    @Enumerated(EnumType.STRING)
+    public final EntityDataType getCode()
+    {
+        return code;
+    }
+
+    public final void setCode(final EntityDataType code)
+    {
+        this.code = code;
+    }
+
+    @NotNull(message = ValidationMessages.DESCRIPTION_NOT_NULL_MESSAGE)
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 80, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof DataTypePE == false)
+        {
+            return false;
+        }
+        final DataTypePE that = (DataTypePE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Comparable
+    //
+
+    public final int compareTo(final DataTypePE o)
+    {
+        return getCode().name().compareTo(o.getCode().name());
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DatabaseInstancePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DatabaseInstancePE.java
new file mode 100644
index 00000000000..bb45998f4ab
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DatabaseInstancePE.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistence Entity</i> which represents a database instance.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.DATABASE_INSTANCES_TABLE)
+public final class DatabaseInstancePE extends AbstractIdAndCodeHolder<DatabaseInstancePE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static String SYSTEM_DEFAULT = "SYSTEM_DEFAULT";
+
+    public final static DatabaseInstancePE[] EMPTY_ARRAY = new DatabaseInstancePE[0];
+
+    private transient Long id;
+
+    /** Registration date of the database instance. */
+    private Date registrationDate;
+
+    /**
+     * The local code of this database instance.
+     * <p>
+     * If <code>SYSTEM_DEFAULT</code>, then {@link #isSystemDefault()} will return
+     * <code>true</code>.
+     * </p>
+     */
+    private String code;
+
+    /**
+     * The global unique code of this database instance (UUID).
+     */
+    private String uuid;
+
+    private boolean isHomeDatabase;
+
+    /** Whether this database instance should get a <i>brand</i>. */
+    private boolean systemDefault;
+
+    private DataStorePE dataStore;
+
+    @OneToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATA_STORE_COLUMN, updatable = false)
+    public final DataStorePE getDataStore()
+    {
+        return dataStore;
+    }
+
+    public final void setDataStore(final DataStorePE dataStorePE)
+    {
+        this.dataStore = dataStorePE;
+    }
+
+    private final void setSystemDefault(final boolean systemDefault)
+    {
+        this.systemDefault = systemDefault;
+    }
+
+    /**
+     * Whether given <var>code</var> is <code>SYSTEM_DEFAULT</code> code.
+     */
+    public final static boolean isSystemDefault(final String code)
+    {
+        return SYSTEM_DEFAULT.equals(code);
+    }
+
+    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false, updatable = false)
+    @Generated(GenerationTime.INSERT)
+    public final Date getRegistrationDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(registrationDate);
+    }
+
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+        setSystemDefault(isSystemDefault(code));
+    }
+
+    @Column(name = ColumnNames.UUID_COLUMN)
+    @NotNull(message = ValidationMessages.UUID_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    // Do not call this method 'getUUID' or Hibernate will complain!
+    public String getUuid()
+    {
+        return uuid;
+    }
+
+    // Do not call this method 'setUUID' or Hibernate will complain!
+    public void setUuid(final String uuid)
+    {
+        this.uuid = uuid;
+    }
+
+    @Transient
+    public final boolean isSystemDefault()
+    {
+        return systemDefault;
+    }
+
+    @Column(name = ColumnNames.IS_ORIGINAL_SOURCE_COLUMN, nullable = false)
+    public final boolean isOriginalSource()
+    {
+        return isHomeDatabase;
+    }
+
+    public final void setOriginalSource(final boolean isHomeDatabase)
+    {
+        this.isHomeDatabase = isHomeDatabase;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    //
+    // AbstractIdAndCodeHolder
+    //
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.DATABASE_INSTANCE_SEQUENCE, sequenceName = SequenceNames.DATABASE_INSTANCE_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATABASE_INSTANCE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @Column(unique = true)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public final String getCode()
+    {
+        return code;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyFiller.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyFiller.java
new file mode 100644
index 00000000000..e9b245ce8db
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyFiller.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Used when assigning mandatory property to an entity, which has some instances or when mandatory
+ * flag is change from optional and properties for some entities are unset.
+ * 
+ * @author Tomasz Pylak
+ */
+public class EntityPropertyFiller extends AbstractHashable implements Serializable
+{
+    public static final EntityPropertyFiller[] EMPTY_ARRAY = new EntityPropertyFiller[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String entityCode;
+
+    private String untypedPropertyValue;
+
+    public EntityPropertyFiller()
+    {
+    }
+
+    public EntityPropertyFiller(final String entityCode, final String untypedPropertyValue)
+    {
+        setEntityCode(entityCode);
+        setPropertyValue(untypedPropertyValue);
+    }
+
+    public final String getEntityCode()
+    {
+        return entityCode;
+    }
+
+    public final String getPropertyValue()
+    {
+        return untypedPropertyValue;
+    }
+
+    @BeanProperty(label = "code")
+    public void setEntityCode(final String entityCode)
+    {
+        assert entityCode != null : "Unspecified entity code.";
+        this.entityCode = entityCode;
+    }
+
+    @BeanProperty(label = "value")
+    public final void setPropertyValue(final String untypedPropertyValue)
+    {
+        assert untypedPropertyValue != null : "Unspecified property value.";
+        this.untypedPropertyValue = untypedPropertyValue;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyPE.java
new file mode 100644
index 00000000000..f4bdaeef23f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyPE.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+
+import ch.systemsx.cisd.common.utilities.ClassUtils;
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * Persistence entity representing entity property.
+ * 
+ * @author Tomasz Pylak
+ * @author Izabela Adamczyk
+ */
+@MappedSuperclass
+public abstract class EntityPropertyPE extends HibernateAbstractRegistratrationHolder implements
+        IRegistratorHolder, IUntypedValueSetter, IEntityProperty
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /**
+     * The value of this entity property.
+     * <p>
+     * Like in the database, no value is set if <code>value</code> is from controlled vocabulary.
+     * </p>
+     */
+    private String value;
+
+    /**
+     * The vocabulary term.
+     * <p>
+     * Not <code>null</code> if <code>value</code> is from controlled vocabulary.
+     * </p>
+     */
+    private VocabularyTermPE vocabularyTerm;
+
+    protected transient Long id;
+
+    protected transient Long entityId;
+
+    protected EntityTypePropertyTypePE entityTypePropertyType;
+
+    public <T extends EntityTypePropertyTypePE> void setEntityTypePropertyType(
+            final T entityTypePropertyType)
+    {
+        this.entityTypePropertyType = entityTypePropertyType;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    public void setValue(final String value)
+    {
+        this.value = value;
+    }
+
+    @Column(name = ColumnNames.VALUE)
+    @Length(max = 1024, message = ValidationMessages.VALUE_LENGTH_MESSAGE)
+    public String getValue()
+    {
+        return value;
+    }
+
+    // TODO 2008-09-02, Franz-Josef Elmer: Remove this method when
+    // EntityPropertyTypeDAO.createPropertyValue() is no longer used.
+    public void setEntityId(final Long entityId)
+    {
+        this.entityId = entityId;
+    }
+
+    public void setVocabularyTerm(final VocabularyTermPE vt)
+    {
+        this.vocabularyTerm = vt;
+
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.VOCABULARY_TERM_COLUMN, updatable = false)
+    public VocabularyTermPE getVocabularyTerm()
+    {
+        return vocabularyTerm;
+    }
+
+    //
+    // IUntypedValueSetter
+    //
+
+    // TODO 2008-08-29, Christian Ribeaud: How to validate this? A custom validator? It must be a
+    // 'VocabularyTermPE' and not just an id.
+    public final void setUntypedValue(final String value, final Long vocabularyTerm)
+    {
+        assert value != null || vocabularyTerm == null : "Value from controlled vocabulary set cannot be null!";
+        if (vocabularyTerm != null)
+        {
+            if (getVocabularyTerm() == null)
+            {
+                final VocabularyTermPE vt = new VocabularyTermPE();
+                setVocabularyTerm(vt);
+            }
+            getVocabularyTerm().setId(vocabularyTerm);
+            getVocabularyTerm().setCode(value);
+        } else
+        {
+            setValue(value);
+        }
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("entityTypePropertyType", getEntityTypePropertyType());
+        builder.append("value", getValue());
+        builder.append("vocabularyTerm", getVocabularyTerm());
+        return builder.toString();
+    }
+
+    public final String tryGetUntypedValue()
+    {
+        return getVocabularyTerm() == null ? getValue() : getVocabularyTerm().getCode();
+    }
+
+    /**
+     * Creates an {@link EntityPropertyPE} from given <var>entityKind</var>.
+     */
+    public final static <T extends EntityPropertyPE> T createEntityProperty(
+            final EntityKind entityKind)
+    {
+        assert entityKind != null : "Unspecified entity kind";
+        return ClassUtils.createInstance(entityKind.<T> getEntityPropertyClass());
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyTypeDTO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyTypeDTO.java
new file mode 100644
index 00000000000..e9abbfe9698
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityPropertyTypeDTO.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityDataType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.PropertiesHelper;
+
+/**
+ * Specification of one entity property (name, type, is mandatory).
+ * 
+ * @author Tomasz Pylak
+ */
+public final class EntityPropertyTypeDTO extends Id implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private boolean mandatory;
+
+    private Date registrationDate;
+
+    private PersonPE registrator;
+
+    private PropertyTypePE propertyType;
+
+    public EntityPropertyTypeDTO()
+    {
+    }
+
+    public EntityPropertyTypeDTO(final long id, final boolean mandatory,
+            final Date registrationDate, final PersonPE registrator,
+            final PropertyTypePE propertyType)
+    {
+        setId(id);
+        this.mandatory = mandatory;
+        this.registrationDate = registrationDate;
+        this.registrator = registrator;
+        this.propertyType = propertyType;
+    }
+
+    public final EntityDataType getDataTypeCode()
+    {
+        return EntityDataType.valueOf(PropertiesHelper.getSimpleType(propertyType));
+    }
+
+    public final boolean isMandatory()
+    {
+        return mandatory;
+    }
+
+    public final void setMandatory(final boolean mandatory)
+    {
+        this.mandatory = mandatory;
+    }
+
+    public final Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    public final void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    public final PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    public final void setRegistrator(final PersonPE registrator)
+    {
+        this.registrator = registrator;
+    }
+
+    public final PropertyTypePE getPropertyType()
+    {
+        return propertyType;
+    }
+
+    public final void setPropertyType(final PropertyTypePE propertyType)
+    {
+        this.propertyType = propertyType;
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityType.java
new file mode 100644
index 00000000000..59583e32612
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityType.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * An <i>abstract</i> <code>Code</code> extension for types.
+ * 
+ * @author Christian Ribeaud
+ */
+public class EntityType extends Code<EntityType> implements IEntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String description;
+
+    public EntityType()
+    {
+    }
+
+    public EntityType(final String code, final String description)
+    {
+        setCode(code);
+        setDescription(description);
+    }
+
+    //
+    // IEntityType
+    //
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypeMandatorilyRelation.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypeMandatorilyRelation.java
new file mode 100644
index 00000000000..147431f0fad
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypeMandatorilyRelation.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * @author Franz-Josef Elmer
+ */
+public class EntityTypeMandatorilyRelation implements Serializable,
+        Comparable<EntityTypeMandatorilyRelation>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final EntityTypeMandatorilyRelation[] EMPTY_ARRAY =
+            new EntityTypeMandatorilyRelation[0];
+
+    private EntityType type;
+
+    private boolean mandatory;
+
+    public final boolean isMandatory()
+    {
+        return mandatory;
+    }
+
+    public final void setMandatory(final boolean mandatory)
+    {
+        this.mandatory = mandatory;
+    }
+
+    public final EntityType getEntityType()
+    {
+        return type;
+    }
+
+    public final void setEntityType(final EntityType materialType)
+    {
+        this.type = materialType;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof EntityTypeMandatorilyRelation == false)
+        {
+            return false;
+        }
+        final EntityTypeMandatorilyRelation that = (EntityTypeMandatorilyRelation) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.type, type);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(type);
+        return builder.toHashCode();
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>type</code>, then they come first.
+     */
+    public final int compareTo(final EntityTypeMandatorilyRelation o)
+    {
+        final EntityType thatType = o.type;
+        if (type == null)
+        {
+            return thatType == null ? 0 : -1;
+        }
+        if (thatType == null)
+        {
+            return 1;
+        }
+        return type.compareTo(thatType);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePE.java
new file mode 100644
index 00000000000..9e581c0a0e4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePE.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ClassUtils;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * Persistence Entity representing entity type.
+ * <p>
+ * Entity is one of: material, sample, experiment
+ * </p>
+ * 
+ * @author Franz-Josef Elmer
+ * @author Izabela Adamczyk
+ */
+@MappedSuperclass
+public abstract class EntityTypePE extends AbstractTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private DatabaseInstancePE databaseInstance;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    /**
+     * Creates an {@link EntityPropertyPE} from given <var>entityKind</var>.
+     */
+    public final static <T extends EntityTypePE> T createEntityTypePE(final EntityKind entityKind)
+    {
+        assert entityKind != null : "Unspecified entity kind.";
+        return ClassUtils.createInstance(entityKind.<T> getTypeClass());
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePropertyTypePE.java
new file mode 100644
index 00000000000..9172f12f692
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/EntityTypePropertyTypePE.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ClassUtils;
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
+
+/**
+ * Relation between a {@link EntityTypePE} of something and a {@link PropertyTypePE}.
+ * <p>
+ * This represents an entry in <code>{entity}_type_property_types</code> table.
+ * </p>
+ * 
+ * @author Franz-Josef Elmer
+ * @author Tomasz Pylak
+ * @author Izabela Adamczyk
+ */
+@MappedSuperclass
+public abstract class EntityTypePropertyTypePE extends HibernateAbstractRegistratrationHolder
+        implements IEntityTypePropertyType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private boolean mandatory;
+
+    private boolean managedInternally;
+
+    protected transient Long id;
+
+    protected EntityTypePE entityType;
+
+    private PropertyTypePE propertyType;
+
+    final public static <T extends EntityTypePropertyTypePE> T createEntityTypePropertyType(
+            final EntityKind entityKind)
+    {
+        return ClassUtils.createInstance(entityKind.<T> getEntityTypePropertyTypeAssignmentClass());
+    }
+
+    @NotNull(message = ValidationMessages.PROPERTY_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.PROPERTY_TYPE_COLUMN, updatable = false)
+    public PropertyTypePE getPropertyType()
+    {
+        return propertyType;
+    }
+
+    public void setPropertyType(final PropertyTypePE propertyType)
+    {
+        this.propertyType = propertyType;
+    }
+
+    @NotNull
+    @Column(name = ColumnNames.IS_MANDATORY)
+    public boolean isMandatory()
+    {
+        return mandatory;
+    }
+
+    public void setMandatory(final boolean mandatory)
+    {
+        this.mandatory = mandatory;
+    }
+
+    @NotNull
+    @Column(name = ColumnNames.IS_MANAGED_INTERNALLY)
+    public boolean isManagedInternally()
+    {
+        return managedInternally;
+    }
+
+    public void setManagedInternally(final boolean managedInternally)
+    {
+        this.managedInternally = managedInternally;
+    }
+
+    public void setEntityType(final EntityTypePE entityType)
+    {
+        this.entityType = entityType;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("managedInternally", isManagedInternally());
+        builder.append("mandatory", isMandatory());
+        builder.append("propertyType", getPropertyType());
+        builder.append("entityType", getEntityType());
+        return builder.toString();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Experiment.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Experiment.java
new file mode 100644
index 00000000000..69cfc371ad9
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Experiment.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * The full description of a experiment.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class Experiment extends AbstractEntity<Experiment>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private NewMaterial studyObject;
+
+    private PersonPE registrator;
+
+    private Date registrationDate;
+
+    private ExperimentType experimentType;
+
+    private AttachmentPE[] attachments = new AttachmentPE[0];
+
+    private Procedure[] procedures = new Procedure[0];
+
+    private ProjectPE project;
+
+    private ProcessingInstructionDTO[] processingInstructions = ProcessingInstructionDTO.EMPTY_ARRAY;
+
+    private InvalidationPE invalidation;
+
+    public final NewMaterial getStudyObject()
+    {
+        return studyObject;
+    }
+
+    public final void setStudyObject(final NewMaterial studyObject)
+    {
+        this.studyObject = studyObject;
+    }
+
+    public final PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    public final void setRegistrator(final PersonPE person)
+    {
+        this.registrator = person;
+    }
+
+    public final Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    public final void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    public final ExperimentType getExperimentType()
+    {
+        return experimentType;
+    }
+
+    public final void setExperimentType(final ExperimentType experimentType)
+    {
+        this.experimentType = experimentType;
+    }
+
+    /**
+     * Returns the descriptions of all {@link FileAttachmentPE}s that are stored for this
+     * experiment. If there are no such properties, the array will be empty (have length 0).
+     */
+    public final AttachmentPE[] getAttachments()
+    {
+        if (attachments == null)
+        {
+            return new AttachmentPE[0];
+        }
+        return attachments;
+    }
+
+    /**
+     * Sets the descriptions of all {@link FileAttachmentPE}s.
+     */
+    public final void setAttachments(final AttachmentPE[] attachments)
+    {
+        this.attachments = attachments;
+    }
+
+    /**
+     * Sets procedures.
+     */
+    public final void setProcedures(final Procedure[] procedures)
+    {
+        this.procedures = procedures;
+    }
+
+    /**
+     * Returns procedures. Never returns <code>null</code> but could return an empty array.
+     */
+    public final Procedure[] getProcedures()
+    {
+        if (procedures == null)
+        {
+            return new Procedure[0];
+        }
+        return procedures;
+    }
+
+    public final ProjectPE getProject()
+    {
+        return project;
+    }
+
+    public final void setProject(final ProjectPE project)
+    {
+        this.project = project;
+    }
+
+    public final ProcessingInstructionDTO[] getProcessingInstructions()
+    {
+        if (processingInstructions == null)
+        {
+            return ProcessingInstructionDTO.EMPTY_ARRAY;
+        }
+        return processingInstructions;
+    }
+
+    public final void setProcessingInstructions(final ProcessingInstructionDTO[] processingInstructions)
+    {
+        this.processingInstructions = processingInstructions;
+    }
+
+    public final InvalidationPE getInvalidation()
+    {
+        return invalidation;
+    }
+
+    public final void setInvalidation(final InvalidationPE invalidation)
+    {
+        this.invalidation = invalidation;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof Experiment == false)
+        {
+            return false;
+        }
+        final Experiment that = (Experiment) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.project, project);
+        builder.append(that.getCode(), getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(project);
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    @Override
+    public final int compareTo(final Experiment o)
+    {
+        final String thatCode = o.getCode();
+        if (getCode() == null)
+        {
+            return thatCode == null ? 0 : -1;
+        }
+        if (thatCode == null)
+        {
+            return 1;
+        }
+        return getCode().compareTo(thatCode);
+    }
+
+    public final EntityType getEntityType()
+    {
+        return getExperimentType();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPE.java
new file mode 100644
index 00000000000..c50099e4a04
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPE.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence Entity representing experiment.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENTS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.PROJECT_COLUMN }) })
+public class ExperimentPE extends HibernateAbstractRegistratrationHolder implements
+        IEntityPropertiesHolder<ExperimentPropertyPE>, IIdAndCodeHolder, Comparable<ExperimentPE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final Object EMPTY_ARRAY = new ExperimentPE[0];
+
+    private transient Long id;
+
+    private String code;
+
+    private ProjectPE project;
+
+    private MaterialPE studyObject;
+
+    private ExperimentTypePE experimentType;
+
+    private InvalidationPE invalidation;
+
+    private List<ExperimentPropertyPE> properties = ExperimentPropertyPE.EMPTY_LIST;
+
+    private DataStorePE dataStore;
+
+    private List<AttachmentPE> attachments = AttachmentPE.EMPTY_LIST;
+
+    private List<ProcedurePE> procedures = ProcedurePE.EMPTY_LIST;
+
+    private ProcessingInstructionDTO[] processingInstructions =
+            ProcessingInstructionDTO.EMPTY_ARRAY;
+
+    private Date lastDataSetDate;
+
+    public ExperimentPE()
+    {
+        super();
+    }
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.EXPERIMENT_SEQUENCE, sequenceName = SequenceNames.EXPERIMENT_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.EXPERIMENT_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.PROJECT_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.PROJECT_COLUMN, updatable = false)
+    public ProjectPE getProject()
+    {
+        return project;
+    }
+
+    public void setProject(final ProjectPE project)
+    {
+        this.project = project;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.STUDY_OBJECT_COLUMN, updatable = false)
+    public MaterialPE getStudyObject()
+    {
+        return studyObject;
+    }
+
+    public void setStudyObject(final MaterialPE studyObject)
+    {
+        this.studyObject = studyObject;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.EXPERIMENT_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_TYPE_COLUMN, updatable = false)
+    public ExperimentTypePE getExperimentType()
+    {
+        return experimentType;
+    }
+
+    public void setExperimentType(final ExperimentTypePE experimentType)
+    {
+
+        this.experimentType = experimentType;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.INVALIDATION_COLUMN)
+    public InvalidationPE getInvalidation()
+    {
+        return invalidation;
+    }
+
+    public void setInvalidation(final InvalidationPE invalidation)
+    {
+
+        this.invalidation = invalidation;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "experiment")
+    private List<ExperimentPropertyPE> getExperimentProperties()
+    {
+        return properties;
+    }
+
+    private void setExperimentProperties(final List<ExperimentPropertyPE> properties)
+    {
+        this.properties = properties;
+    }
+
+    @Transient
+    public List<ExperimentPropertyPE> getProperties()
+    {
+        return getExperimentProperties();
+    }
+
+    public void setProperties(final List<ExperimentPropertyPE> properties)
+    {
+        for (final ExperimentPropertyPE experimentProperty : properties)
+        {
+            final ExperimentPE parent = experimentProperty.getExperiment();
+            if (parent != null)
+            {
+                parent.getProperties().remove(experimentProperty);
+            }
+            experimentProperty.setExperiment(this);
+        }
+        setExperimentProperties(properties);
+    }
+
+    @OneToMany(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_COLUMN, updatable = false)
+    public List<AttachmentPE> getAttachments()
+    {
+        return attachments;
+    }
+
+    public void setAttachments(final List<AttachmentPE> attachments)
+    {
+        this.attachments = attachments;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_COLUMN, updatable = false)
+    public List<ProcedurePE> getProcedures()
+    {
+        return procedures;
+    }
+
+    public void setProcedures(final List<ProcedurePE> procedures)
+    {
+        this.procedures = procedures;
+    }
+
+    @Transient
+    public ProcessingInstructionDTO[] getProcessingInstructions()
+    {
+        return processingInstructions;
+    }
+
+    public void setProcessingInstructions(final ProcessingInstructionDTO[] processingInstructions)
+    {
+        this.processingInstructions = processingInstructions;
+    }
+
+    @Transient
+    public Date getLastDataSetDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(lastDataSetDate);
+    }
+
+    public void setLastDataSetDate(final Date lastDataSetDate)
+    {
+        this.lastDataSetDate = lastDataSetDate;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATA_STORE_COLUMN)
+    public DataStorePE getDataStore()
+    {
+        return dataStore;
+    }
+
+    public void setDataStore(final DataStorePE dataStore)
+    {
+        this.dataStore = dataStore;
+    }
+
+    //
+    // Comparable
+    //
+
+    public int compareTo(final ExperimentPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ExperimentPE == false)
+        {
+            return false;
+        }
+        final ExperimentPE that = (ExperimentPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        builder.append(getProject(), that.getProject());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        builder.append(getProject());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("code", getCode());
+        builder.append("project", getProject());
+        builder.append("experimentType", getExperimentType());
+        builder.append("invalidation", getInvalidation());
+        return builder.toString();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPlatesFilter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPlatesFilter.java
new file mode 100644
index 00000000000..bd9734830d4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPlatesFilter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A filter for all Plates which are assigned to a experiment.
+ * 
+ * @author Basil Neff
+ */
+public final class ExperimentPlatesFilter implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /** If <code>true</code> only experiment with valid samples are returned. */
+    private boolean hideInvalidated;
+
+    public ExperimentPlatesFilter(final boolean hideInvalidated)
+    {
+        setHideInvalidated(hideInvalidated);
+    }
+
+    /**
+     * Returns, if the invalidated plates should filtered out. If <code>true</code> only
+     * experiment with valid samples are returned.
+     */
+    public final boolean isHideInvalidated()
+    {
+        return hideInvalidated;
+    }
+
+    public final void setHideInvalidated(final boolean hideInvalidated)
+    {
+        this.hideInvalidated = hideInvalidated;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("hideInvalidated", isHideInvalidated());
+        return builder.toString();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPropertyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPropertyPE.java
new file mode 100644
index 00000000000..186cd5a8e05
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentPropertyPE.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing experiment property.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENT_PROPERTIES_TABLE)
+public class ExperimentPropertyPE extends EntityPropertyPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static ExperimentPropertyPE[] EMPTY_ARRAY = new ExperimentPropertyPE[0];
+
+    public static final List<ExperimentPropertyPE> EMPTY_LIST = Collections.emptyList();
+
+    private ExperimentPE experiment;
+
+    //
+    // EntityPropertyPE
+    //
+
+    @NotNull(message = ValidationMessages.EXPERIMENT_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = ExperimentTypePropertyTypePE.class)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_TYPE_PROPERTY_TYPE_COLUMN, updatable = false)
+    public EntityTypePropertyTypePE getEntityTypePropertyType()
+    {
+        return entityTypePropertyType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.EXPERIMENT_PROPERTY_SEQUENCE, sequenceName = SequenceNames.EXPERIMENT_PROPERTY_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.EXPERIMENT_PROPERTY_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    @Transient
+    public Long getEntityId()
+    {
+        return experiment.getId();
+    }
+
+    @Override
+    public void setEntityId(final Long entityId)
+    {
+        experiment = new ExperimentPE();
+        experiment.setId(entityId);
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_COLUMN, updatable = false)
+    public ExperimentPE getExperiment()
+    {
+        return experiment;
+    }
+
+    void setExperiment(final ExperimentPE experiment)
+    {
+        this.experiment = experiment;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentType.java
new file mode 100644
index 00000000000..8e5eff2b454
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentType.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * The type of an experiment.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ExperimentType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePE.java
new file mode 100644
index 00000000000..9feb7103bdd
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePE.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing type of experiment.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENT_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class ExperimentTypePE extends EntityTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    //
+    // EntityTypePE
+    //
+
+    @SequenceGenerator(name = SequenceNames.EXPERIMENT_TYPE_SEQUENCE, sequenceName = SequenceNames.EXPERIMENT_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.EXPERIMENT_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePropertyTypePE.java
new file mode 100644
index 00000000000..0e19fcae1ab
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExperimentTypePropertyTypePE.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing experiment type - property type relation.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENT_TYPE_PROPERTY_TYPE_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.ID_COLUMN }) })
+public class ExperimentTypePropertyTypePE extends EntityTypePropertyTypePE
+{
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final ExperimentTypePropertyTypePE[] EMPTY_ARRAY =
+            new ExperimentTypePropertyTypePE[0];
+
+    //
+    // EntityTypePropertyTypePE
+    //
+
+    @NotNull(message = ValidationMessages.EXPERIMENT_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = ExperimentTypePE.class)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_TYPE_COLUMN)
+    public EntityTypePE getEntityType()
+    {
+        return entityType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE, sequenceName = SequenceNames.EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalData.java
new file mode 100644
index 00000000000..b1e22b67f22
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalData.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.common.types.BooleanOrUnknown;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about external data.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ExternalData extends ExtractableData
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String location;
+
+    private StorageFormat storageFormat;
+
+    private Date registrationDate;
+
+    private FileFormatType fileFormatType;
+
+    private DataSetType dataSetType;
+
+    private LocatorType locatorType;
+
+    private Procedure procedure;
+
+    private BooleanOrUnknown complete = BooleanOrUnknown.U;
+
+    private String associatedSampleCode;
+
+    /** Returns <code>dataSetType</code>. */
+    public final DataSetType getDataSetType()
+    {
+        return dataSetType;
+    }
+
+    /** Sets <code>dataSetType</code>. */
+    public final void setDataSetType(final DataSetType dataSetType)
+    {
+        this.dataSetType = dataSetType;
+    }
+
+    /** Returns <code>locator</code>. */
+    public final String getLocation()
+    {
+        return location;
+    }
+
+    /** Sets <code>locator</code>. */
+    public final void setLocation(final String locator)
+    {
+        this.location = locator;
+    }
+
+    /**
+     * Returns the storage format (proprietary or BDS) of this external data set.
+     */
+    public StorageFormat getStorageFormat()
+    {
+        return storageFormat;
+    }
+
+    /**
+     * Sets the storage format (proprietary or BDS) of this external data set.
+     */
+    public void setStorageFormat(final StorageFormat storageFormat)
+    {
+        this.storageFormat = storageFormat;
+    }
+
+    /** Returns the date when the data set has been registered to the database. */
+    public Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    /** Sets the date when the data set has been registered to the database. */
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    /** Returns <code>fileFormatType</code>. */
+    public final FileFormatType getFileFormatType()
+    {
+        return fileFormatType;
+    }
+
+    /** Sets <code>fileFormatType</code>. */
+    public final void setFileFormatType(final FileFormatType fileFormatType)
+    {
+        this.fileFormatType = fileFormatType;
+    }
+
+    /** Returns <code>locatorType</code>. */
+    public final LocatorType getLocatorType()
+    {
+        return locatorType;
+    }
+
+    /** Sets <code>locatorType</code>. */
+    public final void setLocatorType(final LocatorType locatorType)
+    {
+        this.locatorType = locatorType;
+    }
+
+    public Procedure getProcedure()
+    {
+        return procedure;
+    }
+
+    public final void setProcedure(final Procedure procedure)
+    {
+        this.procedure = procedure;
+    }
+
+    /**
+     * Returns {@link BooleanOrUnknown#T}, if the data set is complete in the data store and
+     * {@link BooleanOrUnknown#F}, if some parts of the data are missing. If the completeness is
+     * not known (e.g. because the data set is stored in a format that does not allow to assess the
+     * completeness, {@link BooleanOrUnknown#U} is returned.
+     */
+    public final BooleanOrUnknown getComplete()
+    {
+        return complete;
+    }
+
+    /**
+     * Sets whether this data set is complete in the data store or not. The default is
+     * {@link BooleanOrUnknown#U}, which corresponds to the case where the data are stored in a
+     * format that does not allow to assess completeness.
+     */
+    public final void setComplete(final BooleanOrUnknown complete)
+    {
+        this.complete = complete;
+    }
+
+    public String getAssociatedSampleCode()
+    {
+        return associatedSampleCode;
+    }
+
+    public void setAssociatedSampleCode(final String sampleCode)
+    {
+        this.associatedSampleCode = sampleCode;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ExternalData == false)
+        {
+            return false;
+        }
+        final ExternalData that = (ExternalData) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.location, location);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(location);
+        return builder.toHashCode();
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    @Override
+    public final int compareTo(final ExtractableData o)
+    {
+        final String thatLocation = ((ExternalData) o).location;
+        if (location == null)
+        {
+            return thatLocation == null ? 0 : -1;
+        }
+        if (thatLocation == null)
+        {
+            return 1;
+        }
+        return location.compareTo(thatLocation);
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java
new file mode 100644
index 00000000000..5996c342726
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExternalDataPE.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.PrimaryKeyJoinColumn;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.types.BooleanOrUnknown;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.hibernate.Location;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which contains any information we would like to
+ * know about one EXTERNAL DATA.
+ * <p>
+ * This class is the <i>Java Object</i> representation of the corresponding data in the database.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.EXTERNAL_DATA_TABLE, uniqueConstraints = @UniqueConstraint(columnNames =
+    { ColumnNames.LOCATION_COLUMN, ColumnNames.LOCATOR_TYPE_COLUMN }))
+@PrimaryKeyJoinColumn(name = ColumnNames.DATA_ID_COLUMN)
+public final class ExternalDataPE extends DataPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /** An empty array of <code>ExternalData</code>. */
+    @SuppressWarnings("hiding")
+    public final static ExternalDataPE[] EMPTY_ARRAY = new ExternalDataPE[0];
+
+    private String location;
+
+    private VocabularyTermPE storageFormatVocabularyTerm;
+
+    private FileFormatTypePE fileFormatType;
+
+    private LocatorTypePE locatorType;
+
+    private BooleanOrUnknown complete = BooleanOrUnknown.U;
+
+    /**
+     * Returns the id of the locator type of the location of this external data, or
+     * <code>null</code> if not yet set.
+     */
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.LOCATOR_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.LOCATOR_TYPE_COLUMN, updatable = false)
+    public final LocatorTypePE getLocatorType()
+    {
+        return locatorType;
+    }
+
+    public void setLocatorType(final LocatorTypePE locatorType)
+    {
+        this.locatorType = locatorType;
+    }
+
+    /** Returns <code>locator</code>. */
+    @Column(name = ColumnNames.LOCATION_COLUMN)
+    @Length(max = 1024, message = ValidationMessages.LOCATION_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.LOCATION_NOT_NULL_MESSAGE)
+    @Location(relative = true, message = ValidationMessages.LOCATION_NOT_RELATIVE)
+    public String getLocation()
+    {
+        return location;
+    }
+
+    /** Sets <code>locator</code>. */
+    public void setLocation(final String location)
+    {
+        this.location = location;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.STORAGE_FORMAT_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.STORAGE_FORMAT_COLUMN, updatable = false)
+    public VocabularyTermPE getStorageFormatVocabularyTerm()
+    {
+        return storageFormatVocabularyTerm;
+    }
+
+    public void setStorageFormatVocabularyTerm(final VocabularyTermPE storageFormatVocabularyTerm)
+    {
+        this.storageFormatVocabularyTerm = storageFormatVocabularyTerm;
+    }
+
+    /**
+     * Returns the storage format (proprietary or BDS) of this external data set.
+     */
+    @Transient
+    public StorageFormat getStorageFormat()
+    {
+        return StorageFormat.tryGetFromCode(storageFormatVocabularyTerm.getCode());
+    }
+
+    /** Returns <code>fileFormatType</code>. */
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.FILE_FORMAT_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.FILE_FORMAT_TYPE, updatable = false)
+    public FileFormatTypePE getFileFormatType()
+    {
+        return fileFormatType;
+    }
+
+    /** Sets <code>fileFormatType</code>. */
+    public void setFileFormatType(final FileFormatTypePE fileFormatType)
+    {
+        this.fileFormatType = fileFormatType;
+    }
+
+    @NotNull(message = ValidationMessages.IS_COMPLETE_NOT_NULL_MESSAGE)
+    @Column(name = ColumnNames.IS_COMPLETE_COLUMN)
+    @Enumerated(EnumType.STRING)
+    /**
+     * Returns {@link BooleanOrUnknown#T}, if the data set is complete in the data store and
+     * {@link BooleanOrUnknown#F}, if some parts of the data are missing. If the completeness is
+     * not known (e.g. because the data set is stored in a format that does not allow to assess the
+     * completeness, {@link BooleanOrUnknown#U} is returned.
+     */
+    public BooleanOrUnknown getComplete()
+    {
+        return complete;
+    }
+
+    /**
+     * Sets whether this data set is complete in the data store or not. The default is
+     * {@link BooleanOrUnknown#U}, which corresponds to the case where the data are stored in a
+     * format that does not allow to assess completeness.
+     */
+    public void setComplete(final BooleanOrUnknown complete)
+    {
+        this.complete = complete;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExtractableData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExtractableData.java
new file mode 100644
index 00000000000..e7cf5d9721d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ExtractableData.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Date;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A basic {@link ExternalData} object.
+ * <p>
+ * {@link ExternalData} extends this class and completes it with additional fields.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public class ExtractableData extends Code<ExtractableData>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private Date productionDate;
+
+    private String dataProducerCode;
+
+    private String parentDataSetCode;
+
+    /**
+     * Returns the date when the measurement / calculation that produced this external data set has
+     * been performed.
+     * <p>
+     * This may not be known in which case this method will return <code>null</code>.
+     */
+    public Date getProductionDate()
+    {
+        return productionDate;
+    }
+
+    /**
+     * Sets the date when the measurement / calculation that produced this external data set has
+     * been performed.
+     */
+    public void setProductionDate(final Date productionDate)
+    {
+        this.productionDate = productionDate;
+    }
+
+    /**
+     * Returns the code identifying the data source (i.e. measurement device or software pipeline)
+     * that produced this external data set.
+     * <p>
+     * This may not be known in which case this method will return <code>null</code>.
+     */
+    public String getDataProducerCode()
+    {
+        return dataProducerCode;
+    }
+
+    /**
+     * Sets the code identifying the data source (i.e. measurement device or software pipeline) that
+     * produced this external data set.
+     */
+    public void setDataProducerCode(final String dataProducerCode)
+    {
+        this.dataProducerCode = dataProducerCode;
+    }
+
+    public final String getParentDataSetCode()
+    {
+        return parentDataSetCode;
+    }
+
+    public final void setParentDataSetCode(String parentDataSetCode)
+    {
+        this.parentDataSetCode = parentDataSetCode;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileAttachmentPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileAttachmentPE.java
new file mode 100644
index 00000000000..0d194c4a53a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileAttachmentPE.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Contains information about an attachment together with its content.
+ * 
+ * @author Bernd Rinn
+ */
+@Entity
+@Table(name = TableNames.EXPERIMENT_ATTACHMENTS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.EXPERIMENT_COLUMN, ColumnNames.FILE_NAME_COLUMN, ColumnNames.VERSION_COLUMN }) })
+public class FileAttachmentPE extends AbstractAttachmentPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private byte[] value;
+
+    /**
+     * Returns bytes blob stored in the attachment.
+     */
+    @NotNull(message = ValidationMessages.ATTACHMENT_CONTENT_NOT_NULL_MESSAGE)
+    public byte[] getValue()
+    {
+        return value;
+    }
+
+    public void setValue(byte[] value)
+    {
+        this.value = value;
+    }
+
+    @Override
+    public final String toString()
+    {
+        return getClass().getSimpleName() + "{len(value)="
+                + (value != null ? value.length : "<null>") + ",attachment=" + super.toString()
+                + "}";
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatType.java
new file mode 100644
index 00000000000..facdd283e7c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about a file format type.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class FileFormatType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final String DEFAULT_FILE_FORMAT_TYPE_CODE = "TIFF";
+
+    public FileFormatType()
+    {
+    }
+
+    public FileFormatType(final String code)
+    {
+        setCode(code);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatTypePE.java
new file mode 100644
index 00000000000..0beec72892a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/FileFormatTypePE.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence Entity representing the type of file format.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.FILE_FORMAT_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class FileFormatTypePE extends AbstractTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private DatabaseInstancePE databaseInstance;
+
+    @SequenceGenerator(name = SequenceNames.FILE_FORMAT_TYPE_SEQUENCE, sequenceName = SequenceNames.FILE_FORMAT_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.FILE_FORMAT_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    public FileFormatTypePE()
+    {
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GroupPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GroupPE.java
new file mode 100644
index 00000000000..611244ac741
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/GroupPE.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistence Entity</i> which represents a group.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.GROUPS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class GroupPE extends HibernateAbstractRegistratrationHolder implements
+        IIdAndCodeHolder, Comparable<GroupPE>, Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final GroupPE[] EMPTY_ARRAY = new GroupPE[0];
+
+    private transient Long id;
+
+    private String code;
+
+    private String description;
+
+    private PersonPE groupLeader;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private GroupPE parent;
+
+    // null if unknown
+    private Boolean home;
+
+    private DataStorePE dataStore;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATA_STORE_COLUMN, updatable = false)
+    public final DataStorePE getDataStore()
+    {
+        return dataStore;
+    }
+
+    public final void setDataStore(final DataStorePE dataStorePE)
+    {
+        this.dataStore = dataStorePE;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 250, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.PERSON_LEADER_COLUMN, updatable = false)
+    public final PersonPE getGroupLeader()
+    {
+        return groupLeader;
+    }
+
+    public final void setGroupLeader(final PersonPE groupLeader)
+    {
+        this.groupLeader = groupLeader;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.GROUP_PARENT_COLUMN, updatable = false)
+    public final GroupPE getParent()
+    {
+        return parent;
+    }
+
+    public final void setParent(final GroupPE parent)
+    {
+        this.parent = parent;
+    }
+
+    @Transient
+    public final Boolean isHome()
+    {
+        return home;
+    }
+
+    public final void setHome(final Boolean home)
+    {
+        this.home = home;
+    }
+
+    //
+    // IIdAndCodeHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.GROUP_SEQUENCE, sequenceName = SequenceNames.GROUP_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.GROUP_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public final String getCode()
+    {
+        return code;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof GroupPE == false)
+        {
+            return false;
+        }
+        final GroupPE that = (GroupPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(code, that.code);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(code);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Compare
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(final GroupPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/HibernateAbstractRegistratrationHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/HibernateAbstractRegistratrationHolder.java
new file mode 100644
index 00000000000..f27d283f57b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/HibernateAbstractRegistratrationHolder.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Transient;
+
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+
+
+/**
+ * Super class of <i>Persistent Entities</i> which hold registration data.
+ * <p>
+ * <b>Note:</b> there is no <i>NOT-NULL</i> constraint applied to registrator (by comparison with
+ * the database where there almost one).
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+@MappedSuperclass
+public abstract class HibernateAbstractRegistratrationHolder implements IRegistratorHolder,
+        Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Person who registered this entity.
+     * <p>
+     * This is specified at insert time.
+     * </p>
+     */
+    private PersonPE registrator;
+
+    /**
+     * Registration date of this entity.
+     * <p>
+     * This is specified at insert time.
+     * </p>
+     */
+    private Date registrationDate;
+
+    /**
+     * Ensures that given <var>date</var> is a real one (<code>java.util.Date</code>) and not a
+     * <i>SQL</i> one.
+     */
+    public final static Date getDate(final Date date)
+    {
+        if (date == null)
+        {
+            return null;
+        }
+        final String packageName = date.getClass().getPackage().getName();
+        if (packageName.equals("java.sql"))
+        {
+            return new Date(date.getTime());
+        }
+        return date;
+    }
+
+    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false, updatable = false)
+    @Generated(GenerationTime.INSERT)
+    public Date getRegistrationDate()
+    {
+        return getDate(registrationDate);
+    }
+
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    //
+    // IRegistratorHolder
+    //
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.PERSON_REGISTERER_COLUMN, updatable = false)
+    public PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    public void setRegistrator(final PersonPE registrator)
+    {
+        this.registrator = registrator;
+    }
+
+    @Transient
+    public Long getRegistratorID()
+    {
+        return registrator.getId();
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityPropertiesHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityPropertiesHolder.java
new file mode 100644
index 00000000000..60d9d7e4929
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityPropertiesHolder.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.List;
+
+/**
+ * Interface of classes having entity properties.
+ * 
+ * @author Christian Ribeaud
+ */
+public interface IEntityPropertiesHolder<T extends EntityPropertyPE>
+{
+    /**
+     * Gets the entity properties.
+     */
+    public List<T> getProperties();
+
+    /**
+     * Sets the entity properties.
+     */
+    public void setProperties(final List<T> properties);
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityProperty.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityProperty.java
new file mode 100644
index 00000000000..4b8325d087f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityProperty.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+
+/**
+ * An entity property is composed of:
+ * <ol>
+ * <li>{@link IIdHolder#getId()}</li>
+ * <li>{@link #getEntityId()}</li>
+ * <li>{@link #getEntityTypePropertyType()}</li>
+ * </ol>
+ * 
+ * @author Christian Ribeaud
+ */
+public interface IEntityProperty extends IIdHolder
+{
+    /**
+     * Returns the entity type property type for this entity property.
+     */
+    public EntityTypePropertyTypePE getEntityTypePropertyType();
+
+    /**
+     * Returns the entity id for this entity property.
+     */
+    public Long getEntityId();
+
+    /**
+     * Return untyped value or <code>null</code>. 
+     */
+    public String tryGetUntypedValue();
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityType.java
new file mode 100644
index 00000000000..d133c1a8383
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityType.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Getters and Setters of all DTOs which are Entity Types (e.g. Material Type, Experiment Type).
+ * 
+ * @author Franz-Josef Elmer
+ */
+public interface IEntityType
+{
+
+    /** Returns the code of this type. */
+    public String getCode();
+
+    /** Sets the code of this type. */
+    public void setCode(final String code);
+
+    /** Returns a description of this type. */
+    public String getDescription();
+
+    /** Sets the description of this type. */
+    public void setDescription(final String description);
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityTypePropertyType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityTypePropertyType.java
new file mode 100644
index 00000000000..9e9c4ba17a7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IEntityTypePropertyType.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+
+/**
+ * An entity property is composed of:
+ * <ol>
+ * <li>{@link IIdHolder#getId()}</li>
+ * <li>{@link #getEntityType()}</li>
+ * </ol>
+ * 
+ * @author Christian Ribeaud
+ */
+public interface IEntityTypePropertyType extends IIdHolder
+{
+
+    /**
+     * Returns the entity type for this entity type property type.
+     */
+    public EntityTypePE getEntityType();
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdAndCodeHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdAndCodeHolder.java
new file mode 100644
index 00000000000..723d198abb8
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdAndCodeHolder.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+
+/**
+ * Read-only interface for beans with a (unique) business code as a string and a unique technical
+ * ID.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public interface IIdAndCodeHolder extends IIdHolder
+{
+    /**
+     * Returns the business code of this instance.
+     */
+    public String getCode();
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdHolder.java
new file mode 100644
index 00000000000..61cf20cbfc3
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IIdHolder.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Read-only interface for beans with a unique technical Id.
+ * 
+ * @author Christian Ribeaud
+ */
+public interface IIdHolder
+{
+
+    /**
+     * Returns the technical ID of this instance.
+     * 
+     * @return <code>null</code> if there is no Id.
+     */
+    public Long getId();
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IRegistratorHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IRegistratorHolder.java
new file mode 100644
index 00000000000..7d569c24347
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IRegistratorHolder.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+
+/**
+ * Implementations are aware of the registrator.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public interface IRegistratorHolder
+{
+
+    /**
+     * Returns registratorID.
+     */
+    public Long getRegistratorID();
+
+    /**
+     * Returns the registrator.
+     * 
+     * @return <code>null</code> if undefined.
+     */
+    public PersonPE getRegistrator();
+
+    /**
+     * Sets the person who has registered something.
+     * 
+     * @throws AssertionError if {@link #getRegistratorID()} is not <code>null</code> but unequal
+     *             <code>registrator.getId()</code>.
+     */
+    public void setRegistrator(final PersonPE registrator);
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ISimpleEntityPropertiesHolder.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ISimpleEntityPropertiesHolder.java
new file mode 100644
index 00000000000..76fee88d1fe
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ISimpleEntityPropertiesHolder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Interface of classes having entity properties.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public interface ISimpleEntityPropertiesHolder
+{
+    /**
+     * Gets the entity properties.
+     */
+    public SimpleEntityProperty[] getProperties();
+
+    /**
+     * Sets the entity properties.
+     */
+    public void setProperties(final SimpleEntityProperty[] properties);
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IUntypedValueSetter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IUntypedValueSetter.java
new file mode 100644
index 00000000000..d07ea6eec9c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/IUntypedValueSetter.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * Holds the untyped property value.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public interface IUntypedValueSetter
+{
+
+    /** Internally sets the untyped property value. */
+    public void setUntypedValue(final String valueOrNull, final Long vocabularyTermIdOrNull);
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Id.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Id.java
new file mode 100644
index 00000000000..cf25ee05305
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Id.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * An abstract class which based equality and comparability on in its unique field <code>id</code>.
+ * 
+ * @author Christian Ribeaud
+ */
+public class Id implements Serializable, IIdHolder
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static Long getAndCheckID(final IIdHolder objectWithID, final Long id)
+    {
+        if (objectWithID == null)
+        {
+            return id;
+        }
+        assert id == null || id.equals(objectWithID.getId());
+        return objectWithID.getId();
+    }
+
+    transient private Long id;
+
+    /**
+     * Sets id.
+     * 
+     * @param id New value. Can be <code>null</code>.
+     */
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    //
+    // IIdHolder
+    //
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/InvalidationPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/InvalidationPE.java
new file mode 100644
index 00000000000..24acb05d946
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/InvalidationPE.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Class representing invalidation.
+ * 
+ * @author Franz-Josef Elmer
+ */
+@Entity
+@Table(name = TableNames.INVALIDATION_TABLE)
+public class InvalidationPE extends HibernateAbstractRegistratrationHolder implements IIdHolder,
+        Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    private String reason;
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.INVALIDATION_SEQUENCE, sequenceName = SequenceNames.INVALIDATION_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.INVALIDATION_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @Length(max = 250, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public String getReason()
+    {
+        return reason;
+    }
+
+    public void setReason(final String description)
+    {
+        this.reason = description;
+    }
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof InvalidationPE == false)
+        {
+            return false;
+        }
+        final InvalidationPE that = (InvalidationPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(id, that.id);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(id);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LimitFilter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LimitFilter.java
new file mode 100644
index 00000000000..8dc0224153f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LimitFilter.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Java Bean</i> that filters a list of results.
+ * <p>
+ * Typically this filter is applied to results returned by the database before sending them to the
+ * client.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class LimitFilter extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private final static int NO_LIMIT = -1;
+
+    public LimitFilter(int limit)
+    {
+        this.limit = limit;
+    }
+
+    /**
+     * Creates the empty filter.
+     */
+    public LimitFilter()
+    {
+        this(NO_LIMIT);
+    }
+
+    public final static LimitFilter createEmpty()
+    {
+        return new LimitFilter();
+    }
+
+    /**
+     * The maximum number of items the returned list should be composed of.
+     */
+    private int limit;
+
+    /** At which index to apply {@link #limit}. */
+    private int start;
+
+    /**
+     * Returns <code>limit</code>.
+     * <p>
+     * Never returns a value smaller than <code>NO_LIMIT</code>.
+     * </p>
+     */
+    public final int getLimit()
+    {
+        return Math.max(limit, NO_LIMIT);
+    }
+
+    public final void setLimit(int limit)
+    {
+        this.limit = limit;
+    }
+
+    /**
+     * Returns <code>limit</code>.
+     * <p>
+     * Never returns a negative value.
+     * </p>
+     */
+    public final int getStart()
+    {
+        return Math.max(start, 0);
+    }
+
+    public final void setStart(int start)
+    {
+        this.start = start;
+    }
+
+    /** @return true if the filter has no effect */
+    public final boolean isEmpty()
+    {
+        return this.equals(createEmpty());
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorType.java
new file mode 100644
index 00000000000..a5a6f593624
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorType.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which contains any information we would like to
+ * know about a locator type.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class LocatorType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final String DEFAULT_LOCATOR_TYPE_CODE = "RELATIVE_LOCATION";
+
+    public LocatorType()
+    {
+    }
+
+    public LocatorType(final String code)
+    {
+        setCode(code);
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorTypePE.java
new file mode 100644
index 00000000000..98d7dd89800
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/LocatorTypePE.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence Entity representing type of locator.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.LOCATOR_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN }) })
+public final class LocatorTypePE extends AbstractTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    @SequenceGenerator(name = SequenceNames.LOCATOR_TYPE_SEQUENCE, sequenceName = SequenceNames.LOCATOR_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.LOCATOR_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialBatchPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialBatchPE.java
new file mode 100644
index 00000000000..530c9b80a7e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialBatchPE.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which contains any information we would like to
+ * know about one material batch.
+ * <p>
+ * This class is the <i>Java Object</i> representation of the corresponding data in the database.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.MATERIAL_BATCHES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.MATERIAL_COLUMN }) })
+public final class MaterialBatchPE extends HibernateAbstractRegistratrationHolder implements
+        IIdAndCodeHolder, Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    private transient Long id;
+
+    private String code;
+
+    private Double amount;
+
+    private transient List<SamplePE> samples;
+
+    private MaterialPE material;
+
+    /**
+     * Creates an instance for specified technical ID of the person who has registered the material
+     * batch.
+     */
+    public MaterialBatchPE(final Long registratorID)
+    {
+        PersonPE registrator = new PersonPE();
+        registrator.setId(registratorID);
+        setRegistrator(registrator);
+    }
+
+    public MaterialBatchPE()
+    {
+    }
+
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    /** Returns <code>code</code>. */
+    public final String getCode()
+    {
+        return code;
+    }
+
+    /** Sets <code>code</code>. */
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @Column(name = ColumnNames.AMOUNT_COLUMN)
+    public final Double getAmount()
+    {
+        return amount;
+    }
+
+    public final void setAmount(final Double ammount)
+    {
+        this.amount = ammount;
+    }
+
+    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+    @JoinTable(name = TableNames.SAMPLE_MATERIAL_BATCHES_TABLE, joinColumns = @JoinColumn(name = ColumnNames.MATERIAL_BATCH_COLUMN), inverseJoinColumns = @JoinColumn(name = ColumnNames.SAMPLE_COLUMN))
+    public List<SamplePE> getSamples()
+    {
+        return samples;
+    }
+
+    public void setSamples(List<SamplePE> samples)
+    {
+        this.samples = samples;
+    }
+
+    /**
+     * @return <code>null</code> when undefined.
+     */
+    @Transient
+    public final Long getMaterialID()
+    {
+        return material == null ? null : material.getId();
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @NotNull(message = ValidationMessages.MATERIAL_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.MATERIAL_COLUMN, updatable = false)
+    public final MaterialPE getMaterial()
+    {
+        return material;
+    }
+
+    public final void setMaterial(final MaterialPE material)
+    {
+        this.material = material;
+    }
+
+    @SequenceGenerator(name = SequenceNames.MATERIAL_BATCH_SEQUENCE, sequenceName = SequenceNames.MATERIAL_BATCH_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.MATERIAL_BATCH_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPE.java
new file mode 100644
index 00000000000..ea92bea498a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPE.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistent Entity</i> which is a material.
+ * 
+ * @author Franz-Josef Elmer
+ */
+@Entity
+@Table(name = TableNames.MATERIALS_TABLE, uniqueConstraints = @UniqueConstraint(columnNames =
+    { ColumnNames.CODE_COLUMN, ColumnNames.MATERIAL_TYPE_COLUMN,
+            ColumnNames.DATABASE_INSTANCE_COLUMN }))
+public class MaterialPE extends HibernateAbstractRegistratrationHolder implements IIdAndCodeHolder,
+        Comparable<MaterialPE>, IEntityPropertiesHolder<MaterialPropertyPE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    private MaterialTypePE materialType;
+
+    private String code;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private List<MaterialPropertyPE> properties = MaterialPropertyPE.EMPTY_LIST;
+
+    public static final MaterialPE[] EMPTY_ARRAY = new MaterialPE[0];
+
+    private MaterialPE inhibitorOf;
+
+    public MaterialPE()
+    {
+    }
+
+    @Id
+    @SequenceGenerator(name = SequenceNames.MATERIAL_SEQUENCE, sequenceName = SequenceNames.MATERIAL_SEQUENCE, allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.MATERIAL_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.MATERIAL_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.MATERIAL_TYPE_COLUMN, updatable = false)
+    public MaterialTypePE getMaterialType()
+    {
+        return materialType;
+    }
+
+    public void setMaterialType(final MaterialTypePE materialType)
+    {
+        this.materialType = materialType;
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.INHIBITOR_OF_COLUMN)
+    public MaterialPE getInhibitorOf()
+    {
+        return inhibitorOf;
+    }
+
+    public void setInhibitorOf(final MaterialPE inhibitorOf)
+    {
+        this.inhibitorOf = inhibitorOf;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "material")
+    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+    private List<MaterialPropertyPE> getMaterialProperties()
+    {
+        return properties;
+    }
+
+    private void setMaterialProperties(final List<MaterialPropertyPE> properties)
+    {
+        this.properties = properties;
+    }
+
+    //
+    // IEntityPropertiesHolder
+    //
+
+    @Transient
+    public List<MaterialPropertyPE> getProperties()
+    {
+        return getMaterialProperties();
+    }
+
+    public void setProperties(final List<MaterialPropertyPE> properties)
+    {
+        for (MaterialPropertyPE materialProperty : properties)
+        {
+            MaterialPE parent = materialProperty.getMaterial();
+            if (parent != null)
+            {
+                parent.getProperties().remove(materialProperty);
+            }
+            materialProperty.setMaterial(this);
+        }
+        setMaterialProperties(properties);
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof MaterialPE == false)
+        {
+            return false;
+        }
+        final MaterialPE that = (MaterialPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        builder.append(getMaterialType(), that.getMaterialType());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        builder.append(getMaterialType());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("code", getCode());
+        builder.append("materialType", getMaterialType());
+        return builder.toString();
+    }
+
+    //
+    // Comparable
+    //
+
+    public final int compareTo(final MaterialPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPropertyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPropertyPE.java
new file mode 100644
index 00000000000..6abd75a346e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialPropertyPE.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing material property.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.MATERIAL_PROPERTIES_TABLE)
+@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+public class MaterialPropertyPE extends EntityPropertyPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static MaterialPropertyPE[] EMPTY_ARRAY = new MaterialPropertyPE[0];
+
+    public static final List<MaterialPropertyPE> EMPTY_LIST =
+            Collections.<MaterialPropertyPE> emptyList();
+
+    private MaterialPE material;
+
+    //
+    // EntityPropertyPE
+    //
+
+    @NotNull(message = ValidationMessages.MATERIAL_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = MaterialTypePropertyTypePE.class)
+    @JoinColumn(name = ColumnNames.MATERIAL_TYPE_PROPERTY_TYPE_COLUMN, updatable = false)
+    public EntityTypePropertyTypePE getEntityTypePropertyType()
+    {
+        return entityTypePropertyType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.MATERIAL_PROPERTY_SEQUENCE, sequenceName = SequenceNames.MATERIAL_PROPERTY_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.MATERIAL_PROPERTY_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    // TODO 2008-09-02, Franz-Josef Elmer: Remove this method when
+    // EntityPropertyTypeDAO.createPropertyValue() is no longer used.
+    @Transient
+    public Long getEntityId()
+    {
+        return material.getId();
+    }
+
+    // TODO 2008-09-02, Franz-Josef Elmer: Remove this method when
+    // EntityPropertyTypeDAO.createPropertyValue() is no longer used.
+    @Override
+    public void setEntityId(final Long entityId)
+    {
+        material = new MaterialPE();
+        material.setId(entityId);
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.MATERIAL_COLUMN, updatable = false)
+    public MaterialPE getMaterial()
+    {
+        return material;
+    }
+
+    void setMaterial(final MaterialPE materialID)
+    {
+        this.material = materialID;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
new file mode 100644
index 00000000000..a3f387ac580
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePE.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing type of material.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.MATERIAL_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class MaterialTypePE extends EntityTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    //
+    // EntityTypePE
+    //
+
+    @SequenceGenerator(name = SequenceNames.MATERIAL_TYPE_SEQUENCE, sequenceName = SequenceNames.MATERIAL_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.MATERIAL_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePropertyTypePE.java
new file mode 100644
index 00000000000..9541a6f2568
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/MaterialTypePropertyTypePE.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing material type - property type relation.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.MATERIAL_TYPE_PROPERTY_TYPE_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.ID_COLUMN }) })
+public class MaterialTypePropertyTypePE extends EntityTypePropertyTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final MaterialTypePropertyTypePE[] EMPTY_ARRAY =
+            new MaterialTypePropertyTypePE[0];
+
+    public MaterialTypePropertyTypePE()
+    {
+    }
+
+    //
+    // EntityTypePropertyTypePE
+    //
+
+    @NotNull(message = ValidationMessages.MATERIAL_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = MaterialTypePE.class)
+    @JoinColumn(name = ColumnNames.MATERIAL_TYPE_COLUMN)
+    public EntityTypePE getEntityType()
+    {
+        return entityType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE, sequenceName = SequenceNames.MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE)
+    @Column(insertable = false, updatable = false)
+    public Long getId()
+    {
+        return id;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewExperiment.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewExperiment.java
new file mode 100644
index 00000000000..15162ac0234
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewExperiment.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+
+/**
+ * The full description of a new experiment. Used when registering an experiment to the LIMS.
+ * 
+ * @author Bernd Rinn
+ */
+public final class NewExperiment extends AbstractEntity<NewExperiment>
+{
+
+    public final static NewExperiment[] EMPTY_ARRAY = new NewExperiment[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private ProjectIdentifier projectIdentifier;
+
+    private String studyObjectCode;
+
+    private String studyObjectTypeCode;
+
+    private String experimentTypeCode;
+
+    private String description;
+
+    /**
+     * Processing instructions related to this experiment.
+     * <p>
+     * Processing instructions are procedure type specific.
+     * </p>
+     */
+    private NewProcessingInstruction[] processingInstructions = new NewProcessingInstruction[0];
+
+    /** List of cell plates that are related to this experiment. */
+    private SampleIdentifier[] cellPlates = SampleIdentifier.EMPTY_ARRAY;
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    public EntityType getEntityType()
+    {
+        return new EntityType(experimentTypeCode, "Experiment of type " + experimentTypeCode);
+    }
+
+    public final String getExperimentTypeCode()
+    {
+        return experimentTypeCode;
+    }
+
+    public final void setExperimentTypeCode(final String experimentTypeCode)
+    {
+        this.experimentTypeCode = experimentTypeCode;
+    }
+
+    public final String getStudyObjectCode()
+    {
+        return studyObjectCode;
+    }
+
+    public final void setStudyObjectCode(final String studyObjectCode)
+    {
+        this.studyObjectCode = studyObjectCode;
+    }
+
+    public ProjectIdentifier getProjectIdentifier()
+    {
+        return projectIdentifier;
+    }
+
+    public final void setProjectIdentifier(final ProjectIdentifier projectIdentifier)
+    {
+        this.projectIdentifier = projectIdentifier;
+    }
+
+    /** Never returns <code>null</code> but could return an empty array. */
+    public final SampleIdentifier[] getCellPlates()
+    {
+        return cellPlates == null ? SampleIdentifier.EMPTY_ARRAY : cellPlates;
+    }
+
+    public final void setCellPlates(final SampleIdentifier[] cellPlateCodes)
+    {
+        this.cellPlates = cellPlateCodes;
+    }
+
+    public final void setProcessingInstructions(
+            final NewProcessingInstruction[] processingInstructions)
+    {
+        this.processingInstructions = processingInstructions;
+    }
+
+    /** Never returns <code>null</code> but could return an empty array. */
+    public final NewProcessingInstruction[] getProcessingInstructions()
+    {
+        return processingInstructions == null ? new NewProcessingInstruction[0]
+                : processingInstructions;
+    }
+
+    public final String getStudyObjectTypeCode()
+    {
+        return studyObjectTypeCode;
+    }
+
+    public final void setStudyObjectTypeCode(final String studyObjectTypeCode)
+    {
+        this.studyObjectTypeCode = studyObjectTypeCode;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewMaterial.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewMaterial.java
new file mode 100644
index 00000000000..d580dd6d3c6
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewMaterial.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Class representing a new material.
+ * 
+ * @author Franz-Josef Elmer
+ * @author Tomasz Pylak
+ */
+public final class NewMaterial extends AbstractEntity<NewMaterial>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private EntityType materialType;
+
+    private NewMaterial inhibitorOfOrNull;
+
+    public NewMaterial(final String code, final EntityType materialType)
+    {
+        setCode(code);
+        this.materialType = materialType;
+        this.inhibitorOfOrNull = null;
+        setProperties(new SimpleEntityProperty[0]);
+    }
+
+    public NewMaterial()
+    {
+    }
+
+    public NewMaterial getInhibitorOf()
+    {
+        return inhibitorOfOrNull;
+    }
+
+    public void setInhibitorOf(final NewMaterial inhibitorOfOrNull)
+    {
+        this.inhibitorOfOrNull = inhibitorOfOrNull;
+    }
+
+    public final EntityType getMaterialType()
+    {
+        return materialType;
+    }
+
+    public final void setMaterialType(final EntityType materialType)
+    {
+        this.materialType = materialType;
+    }
+
+    //
+    // AbstractEntity
+    //
+
+    public final EntityType getEntityType()
+    {
+        return getMaterialType();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewProcessingInstruction.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewProcessingInstruction.java
new file mode 100644
index 00000000000..05ec1d2e401
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewProcessingInstruction.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Processing instruction is a specific experiment attachment.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public final class NewProcessingInstruction extends AbstractHashable implements Serializable
+{
+    public final static NewProcessingInstruction[] EMPTY_ARRAY = new NewProcessingInstruction[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String procedureTypeCode;
+
+    private String path;
+
+    private String description;
+
+    private ProcessingParameters parameters;
+
+    public final String getPath()
+    {
+        return path;
+    }
+
+    @BeanProperty(label = "path")
+    public final void setPath(final String path)
+    {
+        this.path = path;
+    }
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    @BeanProperty(optional = true, label = "description")
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    /** can be null */
+    public final byte[] getParameters()
+    {
+        return parameters == null ? null : parameters.getProcessingParameters();
+    }
+
+    public String getParametersFileDescription()
+    {
+        return parameters == null ? null : parameters.getFileDescription();
+    }
+
+    @BeanProperty(optional = true, label = "parameters")
+    public final void setProcessingParameters(final ProcessingParameters parameters)
+    {
+        this.parameters = parameters;
+    }
+
+    public final String getProcedureTypeCode()
+    {
+        return procedureTypeCode;
+    }
+
+    @BeanProperty(label = "procedure_type")
+    public final void setProcedureTypeCode(final String procedureTypeCode)
+    {
+        this.procedureTypeCode = procedureTypeCode;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewPropertyType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewPropertyType.java
new file mode 100644
index 00000000000..5ff794a292f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewPropertyType.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * <i>Bean</i> for registering new property type.
+ * <p>
+ * It is used by the parser. This explains the {@link BeanProperty} annotations.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class NewPropertyType extends Code<NewPropertyType>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final NewPropertyType[] EMPTY_ARRAY = new NewPropertyType[0];
+
+    private String type;
+
+    private String description;
+
+    private String label;
+
+    private String vocabularyCode;
+
+    @BeanProperty(label = "data_type")
+    public final void setType(final String type)
+    {
+        this.type = type;
+    }
+
+    @BeanProperty(label = "description")
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    @BeanProperty(label = "label")
+    public final void setLabel(final String label)
+    {
+        this.label = label;
+    }
+
+    @BeanProperty(optional = true, label = "vocabulary")
+    public void setVocabularyCode(final String vocabularyCode)
+    {
+        this.vocabularyCode = vocabularyCode;
+    }
+
+    public final String getType()
+    {
+        return type;
+    }
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final String getLabel()
+    {
+        return label;
+    }
+
+    public final String getVocabularyCode()
+    {
+        return vocabularyCode;
+    }
+
+    //
+    // Code
+    //
+
+    @Override
+    public final String toString()
+    {
+        return getCode();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewRoleAssignment.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewRoleAssignment.java
new file mode 100644
index 00000000000..c1cbf11c72d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewRoleAssignment.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+
+/**
+ * <i>Bean</i> for registering new role assignments.
+ * <p>
+ * It is used by the parser. This explains the {@link BeanProperty} annotations.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class NewRoleAssignment extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final NewRoleAssignment[] EMPTY_ARRAY = new NewRoleAssignment[0];
+
+    private DatabaseInstanceIdentifier databaseInstanceIdentifier;
+
+    private GroupIdentifier groupIdentifier;
+
+    private String userId;
+
+    private RoleCode role;
+
+    public final RoleCode getRole()
+    {
+        return role;
+    }
+
+    @BeanProperty(label = "role")
+    public final void setRole(final RoleCode role)
+    {
+        this.role = role;
+    }
+
+    public final DatabaseInstanceIdentifier getDatabaseInstanceIdentifier()
+    {
+        return databaseInstanceIdentifier;
+    }
+
+    @BeanProperty(label = "instance")
+    public final void setDatabaseInstanceIdentifier(
+            final DatabaseInstanceIdentifier databaseInstanceIdentifier)
+    {
+        this.databaseInstanceIdentifier = databaseInstanceIdentifier;
+    }
+
+    public final GroupIdentifier getGroupIdentifier()
+    {
+        return groupIdentifier;
+    }
+
+    @BeanProperty(label = "group")
+    public final void setGroupIdentifier(final GroupIdentifier groupIdentifier)
+    {
+        this.groupIdentifier = groupIdentifier;
+    }
+
+    public final String getUserId()
+    {
+        return userId;
+    }
+
+    @BeanProperty(label = "user")
+    public final void setUserId(final String userId)
+    {
+        this.userId = userId;
+    }
+
+    //
+    // AbstractHashable
+    //
+
+    @Override
+    public final String toString()
+    {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(userId).append("=").append(role).append("@");
+        if (getGroupIdentifier() == null)
+        {
+            builder.append(getDatabaseInstanceIdentifier());
+        } else
+        {
+            builder.append(getGroupIdentifier());
+        }
+        return builder.toString();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSample.java
new file mode 100644
index 00000000000..19b1866d7d4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSample.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.types.SampleTypeCode;
+
+/**
+ * The full description of a new sample component.
+ * <p>
+ * Used when registering a sample component to the LIMS.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class NewSample implements Serializable, ISimpleEntityPropertiesHolder
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private SampleIdentifier sampleIdentifier;
+
+    private SampleTypeCode sampleTypeCode;
+
+    private SampleIdentifier parentSampleIdentifier;
+
+    private SampleIdentifier controlLayoutIdentifierOrNull;
+
+    private SimpleEntityProperty[] properties;
+
+    public NewSample()
+    {
+    }
+
+    public NewSample(final SampleIdentifier sampleIdentifier, final SampleTypeCode sampleTypeCode,
+            final SampleIdentifier controlLayoutOrNull)
+    {
+        this.sampleIdentifier = sampleIdentifier;
+        this.controlLayoutIdentifierOrNull = controlLayoutOrNull;
+        this.sampleTypeCode = sampleTypeCode;
+    }
+
+    public SimpleEntityProperty[] getProperties()
+    {
+        return properties;
+    }
+
+    public void setProperties(final SimpleEntityProperty[] properties)
+    {
+        this.properties = properties;
+    }
+
+    public final SampleIdentifier getSampleIdentifier()
+    {
+        return sampleIdentifier;
+    }
+
+    public final SampleIdentifier getParentSampleIdentifier()
+    {
+        return parentSampleIdentifier;
+    }
+
+    public final void setParentSampleIdentifier(final SampleIdentifier parentSampleIdentifier)
+    {
+        this.parentSampleIdentifier = parentSampleIdentifier;
+    }
+
+    public final SampleTypeCode getSampleTypeCode()
+    {
+        return sampleTypeCode;
+    }
+
+    /**
+     * Return the <i>Control Layout</i> {@link SampleIdentifier}.
+     * 
+     * @return <code>null</code> if not specified.
+     */
+    public final SampleIdentifier getControlLayoutIdentifier()
+    {
+        return controlLayoutIdentifierOrNull;
+    }
+
+    public final void setControlLayoutIdentifier(final SampleIdentifier controlLayoutIdentifier)
+    {
+        this.controlLayoutIdentifierOrNull = controlLayoutIdentifier;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof NewSample == false)
+        {
+            return false;
+        }
+        final NewSample that = (NewSample) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.getSampleIdentifier(), getSampleIdentifier());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getSampleIdentifier());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponent.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponent.java
new file mode 100644
index 00000000000..b8f48dfaac8
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponent.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * The full description of a new sample component.
+ * <p>
+ * Used when registering a sample component to the LIMS.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class NewSampleComponent extends NewSampleComponentWithFixedMaterialType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    @SuppressWarnings("hiding")
+    public final static NewSampleComponent[] EMPTY_ARRAY = new NewSampleComponent[0];
+
+    private String materialTypeCode;
+
+    public final String getMaterialTypeCode()
+    {
+        return materialTypeCode;
+    }
+
+    @BeanProperty(label = "material_type")
+    public final void setMaterialTypeCode(final String materialTypeCode)
+    {
+        this.materialTypeCode = materialTypeCode;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponentWithFixedMaterialType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponentWithFixedMaterialType.java
new file mode 100644
index 00000000000..0b639c936f6
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/NewSampleComponentWithFixedMaterialType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.common.annotation.BeanProperty;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * The full description of a new sample component.
+ * <p>
+ * Used when registering a sample component to the LIMS.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public class NewSampleComponentWithFixedMaterialType extends
+        Code<NewSampleComponentWithFixedMaterialType>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static NewSampleComponentWithFixedMaterialType[] EMPTY_ARRAY =
+            new NewSampleComponentWithFixedMaterialType[0];
+
+    private String materialCode;
+
+    public final String getMaterialCode()
+    {
+        return materialCode;
+    }
+
+    @BeanProperty(label = "material")
+    public final void setMaterialCode(final String materialCode)
+    {
+        this.materialCode = materialCode;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PersonPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PersonPE.java
new file mode 100644
index 00000000000..28e68def87e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PersonPE.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Email;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistence Entity</i> which represents a person.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.PERSONS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.USER_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class PersonPE extends HibernateAbstractRegistratrationHolder implements
+        Comparable<PersonPE>, IIdHolder, Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /**
+     * The user id of the system user.
+     */
+    public static final String SYSTEM_USER_ID = "system";
+
+    private GroupPE homeGroup;
+
+    private transient Long id;
+
+    private String userId;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String email;
+
+    private boolean systemUser;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private List<RoleAssignmentPE> roleAssignments = RoleAssignmentPE.EMPTY_LIST;
+
+    private final void setSystemUser(final boolean systemUser)
+    {
+        this.systemUser = systemUser;
+    }
+
+    @Column(name = ColumnNames.FIRST_NAME_COLUMN)
+    @Length(max = 30, message = ValidationMessages.FIRST_NAME_LENGTH_MESSAGE)
+    public final String getFirstName()
+    {
+        return firstName;
+    }
+
+    public final void setFirstName(final String firstName)
+    {
+        this.firstName = firstName;
+    }
+
+    @Column(name = ColumnNames.LAST_NAME_COLUMN)
+    @Length(max = 30, message = ValidationMessages.LAST_NAME_LENGTH_MESSAGE)
+    public final String getLastName()
+    {
+        return lastName;
+    }
+
+    public final void setLastName(final String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    @Email(message = ValidationMessages.EMAIL_EMAIL_MESSAGE)
+    @Length(max = 50, message = ValidationMessages.EMAIL_LENGTH_MESSAGE)
+    public final String getEmail()
+    {
+        return email;
+    }
+
+    public final void setEmail(final String email)
+    {
+        this.email = email;
+    }
+
+    @Column(name = ColumnNames.USER_COLUMN)
+    @Length(max = 20, message = ValidationMessages.USER_ID_LENGTH_MESSAGE)
+    @NotNull(message = ValidationMessages.USER_ID_NOT_NULL_MESSAGE)
+    public final String getUserId()
+    {
+        return userId;
+    }
+
+    public final void setUserId(final String userId)
+    {
+        this.userId = userId;
+        setSystemUser(SYSTEM_USER_ID.equals(userId));
+    }
+
+    @Transient
+    public final boolean isSystemUser()
+    {
+        return systemUser;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.GROUP_COLUMN)
+    public final GroupPE getHomeGroup()
+    {
+        return homeGroup;
+    }
+
+    public final void setHomeGroup(final GroupPE homeGroup)
+    {
+        this.homeGroup = homeGroup;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY, mappedBy = "person", cascade = CascadeType.ALL)
+    public final List<RoleAssignmentPE> getRoleAssignments()
+    {
+        return roleAssignments;
+    }
+
+    public final void setRoleAssignments(final List<RoleAssignmentPE> rolesAssignments)
+    {
+        this.roleAssignments = rolesAssignments;
+    }
+
+    //
+    // IIdHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.PERSON_SEQUENCE, sequenceName = SequenceNames.PERSON_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.PERSON_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof PersonPE == false)
+        {
+            return false;
+        }
+        final PersonPE that = (PersonPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(userId, that.userId);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(userId);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("userId", userId);
+        builder.append("firstName", firstName);
+        builder.append("lastName", lastName);
+        builder.append("email", email);
+        builder.append("systemUser", systemUser);
+        return builder.toString();
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(final PersonPE o)
+    {
+        final String thatUserID = o.userId;
+        if (userId == null)
+        {
+            return thatUserID == null ? 0 : -1;
+        }
+        if (thatUserID == null)
+        {
+            return 1;
+        }
+        return userId.compareTo(thatUserID);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Procedure.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Procedure.java
new file mode 100644
index 00000000000..37409c11eb5
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Procedure.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about a procedure.
+ * <p>
+ * <i>Note that equality, hash code calculation and comparison is based on the code of the
+ * {@link ProcedureType} since the procedure itself does not have a code.</i>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class Procedure implements Comparable<Procedure>, Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private Date registrationDate;
+
+    private ProcedureType procedureType;
+
+    private Experiment experiment;
+
+    private Sample[] resultSamples = new Sample[0];
+
+    private Sample[] inputSamples = new Sample[0];
+
+    public final ProcedureType getProcedureType()
+    {
+        return procedureType;
+    }
+
+    public final void setProcedureType(ProcedureType procedureType)
+    {
+        this.procedureType = procedureType;
+    }
+
+    /**
+     * Returns registrationDate.
+     * 
+     * @return <code>null</code> when undefined.
+     */
+    public final Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    /**
+     * Sets registrationDate.
+     * 
+     * @param registrationDate New value. Can be <code>null</code>.
+     */
+    public final void setRegistrationDate(Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    public final void setResultSamples(Sample[] samples)
+    {
+        this.resultSamples = samples;
+    }
+
+    /**
+     * Returns experiment.
+     * 
+     * @return <code>null</code> when undefined.
+     */
+    public final Experiment getExperiment()
+    {
+        return experiment;
+    }
+
+    /**
+     * Sets experiment.
+     * 
+     * @param experiment New value. Can be <code>null</code>.
+     */
+    public final void setExperiment(Experiment experiment)
+    {
+        this.experiment = experiment;
+    }
+
+    /**
+     * Never returns <code>null</code> but could return an empty array.
+     */
+    public final Sample[] getResultSamples()
+    {
+        if (resultSamples == null)
+        {
+            return new Sample[0];
+        }
+        return resultSamples;
+    }
+
+    /**
+     * Never returns <code>null</code> but could return an empty array.
+     */
+    public final Sample[] getInputSamples()
+    {
+        if (inputSamples == null)
+        {
+            return new Sample[0];
+        }
+        return inputSamples;
+    }
+
+    public final void setInputSamples(Sample[] inputSamples)
+    {
+        this.inputSamples = inputSamples;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof Procedure == false)
+        {
+            return false;
+        }
+        Procedure that = (Procedure) obj;
+        EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.registrationDate, registrationDate);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(registrationDate);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(Procedure o)
+    {
+        final String code = procedureType.getCode();
+        final String thatCode = o.procedureType.getCode();
+        if (code == null)
+        {
+            return thatCode == null ? 0 : -1;
+        }
+        if (thatCode == null)
+        {
+            return 1;
+        }
+        return code.compareTo(thatCode);
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedurePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedurePE.java
new file mode 100644
index 00000000000..eef9eb4c145
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedurePE.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.annotations.Generated;
+import org.hibernate.annotations.GenerationTime;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * <i>Persistent Entity</i> object of an entity 'procedure'.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.PROCEDURES_TABLE)
+public class ProcedurePE implements IIdHolder, Serializable
+{
+    public final static ProcedurePE[] EMPTY_ARRAY = new ProcedurePE[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final List<ProcedurePE> EMPTY_LIST = new ArrayList<ProcedurePE>();
+
+    private ProcedureTypePE procedureType;
+
+    private Date registrationDate;
+
+    private transient Long id;
+
+    private ExperimentPE experiment;
+
+    private SamplePE[] resultSamples = SamplePE.EMPTY_ARRAY;
+
+    // TODO 2008-09-10, Tomasz Pylak: this is a deprecated field for control layouts connected
+    // directly to procedures. The workflow which used it has been deleted. We can get rid of this
+    // field if we write a migration script which connection all the experiment samples to the
+    // control layout directly.
+    private SamplePE[] inputSamples = SamplePE.EMPTY_ARRAY;
+
+    private List<DataPE> data = DataPE.EMPTY_LIST;
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.PROPERTY_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.PROCEDURE_TYPE_COLUMN, updatable = false)
+    public ProcedureTypePE getProcedureType()
+    {
+        return procedureType;
+    }
+
+    public void setProcedureType(final ProcedureTypePE procedureType)
+    {
+        this.procedureType = procedureType;
+    }
+
+    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false, updatable = false)
+    @Generated(GenerationTime.INSERT)
+    public Date getRegistrationDate()
+    {
+        return HibernateAbstractRegistratrationHolder.getDate(registrationDate);
+    }
+
+    public void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    //
+    // IIdHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.PROCEDURE_SEQUENCE, sequenceName = SequenceNames.PROCEDURE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.PROCEDURE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    public void setExperiment(final ExperimentPE experiment)
+    {
+        this.experiment = experiment;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @NotNull(message = ValidationMessages.EXPERIMENT_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.EXPERIMENT_COLUMN, updatable = false)
+    public ExperimentPE getExperiment()
+    {
+        return experiment;
+    }
+
+    @Transient
+    public SamplePE[] getInputSamples()
+    {
+        return inputSamples;
+    }
+
+    @Transient
+    public SamplePE[] getResultSamples()
+    {
+        return resultSamples;
+    }
+
+    public void setResultSamples(final SamplePE[] resultSamples)
+    {
+        this.resultSamples = resultSamples;
+    }
+
+    public void setInputSamples(final SamplePE[] inputSamples)
+    {
+        this.inputSamples = inputSamples;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.PROCEDURE_PRODUCED_BY_COLUMN, updatable = false)
+    public List<DataPE> getData()
+    {
+        return data;
+    }
+
+    public void setData(final List<DataPE> data)
+    {
+        this.data = data;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("procedureType", getProcedureType());
+        builder.append("experiment", getExperiment());
+        return builder.toString();
+    }
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ProcedurePE == false)
+        {
+            return false;
+        }
+        final ProcedurePE that = (ProcedurePE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getProcedureType(), that.getProcedureType());
+        builder.append(getExperiment(), that.getExperiment());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getProcedureType());
+        builder.append(getExperiment());
+        return builder.toHashCode();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureType.java
new file mode 100644
index 00000000000..4cb6478b399
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureType.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.types.ProcedureTypeCode;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about a procedure type.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ProcedureType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private boolean dataAcquisition;
+
+    public ProcedureType()
+    {
+    }
+
+    public ProcedureType(final String code)
+    {
+        ProcedureTypeCode procedureTypeCode = ProcedureTypeCode.getProcedureTypeCode(code);
+        setCode(procedureTypeCode.getCode());
+        // TODO 2008-04-17, Franz-Josef Elmer: data acquisition flag should come from application
+        // server
+        setDataAcquisition(procedureTypeCode == ProcedureTypeCode.DATA_ACQUISITION);
+    }
+
+    /**
+     * Returns <code>true</code> if and only if this procedure type represents a data acquisition
+     * (or measurement) rather than a data processing (or derivation) step in a workflow.
+     */
+    public final boolean isDataAcquisition()
+    {
+        return dataAcquisition;
+    }
+
+    /**
+     * Sets the attribute which determines whether this procedure type represents a data acquisition
+     * (or measurement) rather than a data processing (or derivation) step in a workflow.
+     */
+    public final void setDataAcquisition(final boolean dataAcquisition)
+    {
+        this.dataAcquisition = dataAcquisition;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureTypePE.java
new file mode 100644
index 00000000000..ccc54233795
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcedureTypePE.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence Entity representing procedure type.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.PROCEDURE_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class ProcedureTypePE extends AbstractTypePE
+{
+    private boolean dataAcquisition;
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private DatabaseInstancePE databaseInstance;
+
+    @SequenceGenerator(name = SequenceNames.PROCEDURE_TYPE_SEQUENCE, sequenceName = SequenceNames.PROCEDURE_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.PROCEDURE_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    /**
+     * Returns <code>true</code> if and only if this procedure type represents a data acquisition
+     * (or measurement) rather than a data processing (or derivation) step in a workflow.
+     */
+    @Column(name = ColumnNames.IS_DATA_CQUSITION, nullable = false)
+    public final boolean isDataAcquisition()
+    {
+        return dataAcquisition;
+    }
+
+    /**
+     * Sets the attribute which determines whether this procedure type represents a data acquisition
+     * (or measurement) rather than a data processing (or derivation) step in a workflow.
+     */
+    public final void setDataAcquisition(final boolean dataAcquisition)
+    {
+        this.dataAcquisition = dataAcquisition;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingInstructionDTO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingInstructionDTO.java
new file mode 100644
index 00000000000..dcac257414c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingInstructionDTO.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+
+/**
+ * Processing instruction needed to process raw data.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public class ProcessingInstructionDTO extends AbstractRegistratrationHolder
+{
+    private static final long serialVersionUID = 1L;
+
+    public static final ProcessingInstructionDTO[] EMPTY_ARRAY = new ProcessingInstructionDTO[0];
+
+    transient private Long experimentID;
+
+    private String procedureTypeCode;
+
+    private String path;
+
+    private String description;
+
+    private byte[] parameters;
+
+    public ProcessingInstructionDTO()
+    {
+        super(null);
+    }
+
+    public final Long getExperimentID()
+    {
+        return experimentID;
+    }
+
+    public final void setExperimentID(final Long experimentID)
+    {
+        this.experimentID = experimentID;
+    }
+
+    public final String getProcedureTypeCode()
+    {
+        return procedureTypeCode;
+    }
+
+    public final void setProcedureTypeCode(final String procedureTypeCode)
+    {
+        this.procedureTypeCode = procedureTypeCode;
+    }
+
+    public final String getPath()
+    {
+        return path;
+    }
+
+    public final void setPath(final String path)
+    {
+        this.path = path;
+    }
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    /** can be null */
+    public final byte[] getParameters()
+    {
+        return parameters;
+    }
+
+    public final void setParameters(final byte[] parameters)
+    {
+        this.parameters = parameters;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingParameters.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingParameters.java
new file mode 100644
index 00000000000..bcf741b0cc2
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProcessingParameters.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Processing parameters are a binary byte sequence from a file. It is stored BASE64 encoded in
+ * order to be marshalling and unmarshalling for SOAP.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public class ProcessingParameters implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /**
+     * Creates an instance based on the specified byte array.
+     * 
+     * @return <code>null</code> if the argument is also <code>null</code>.
+     */
+    public final static ProcessingParameters tryCreateFrom(final byte[] bytesOrNull)
+    {
+        if (bytesOrNull == null)
+        {
+            return null;
+        }
+        final ProcessingParameters processingParameters = new ProcessingParameters();
+        processingParameters.setProcessingParameters(bytesOrNull);
+        return processingParameters;
+    }
+
+    private byte[] processingParameters;
+
+    private String fileDescription;
+
+    public final String getFileDescription()
+    {
+        return fileDescription;
+    }
+
+    public final void setFileDescription(final String fileDescription)
+    {
+        this.fileDescription = fileDescription;
+    }
+
+    public final byte[] getProcessingParameters()
+    {
+        return processingParameters;
+    }
+
+    public final void setProcessingParameters(final byte[] encodedProcessingParameters)
+    {
+        this.processingParameters = encodedProcessingParameters;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProjectPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProjectPE.java
new file mode 100644
index 00000000000..86d88834fd9
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ProjectPE.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <i>Persistence Entity</i> which represents a project.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.PROJECTS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.GROUP_COLUMN }) })
+public final class ProjectPE extends HibernateAbstractRegistratrationHolder implements
+        Comparable<ProjectPE>, IIdAndCodeHolder, Serializable
+{
+    public static final ProjectPE[] EMPTY_ARRAY = new ProjectPE[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    private GroupPE group;
+
+    private String code;
+
+    private String description;
+
+    private PersonPE projectLeader;
+
+    /** The number of experiments this project contains. */
+    private int size;
+
+    private DataStorePE dataStore;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATA_STORE_COLUMN, updatable = false)
+    public final DataStorePE getDataStore()
+    {
+        return dataStore;
+    }
+
+    public final void setDataStore(final DataStorePE dataStorePE)
+    {
+        this.dataStore = dataStorePE;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    /**
+     * Sets the group which this <code>ProjectDTO</code> is related to.
+     * 
+     * @throws AssertionError if <code>groupId</code> is defined but unequal
+     *             <code>group.getId()</code>.
+     */
+    public final void setGroup(final GroupPE group)
+    {
+        this.group = group;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.GROUP_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.GROUP_COLUMN, updatable = false)
+    public final GroupPE getGroup()
+    {
+        return group;
+    }
+
+    @Transient
+    public final int getSize()
+    {
+        return size;
+    }
+
+    public final void setSize(final int size)
+    {
+        this.size = size;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.PERSON_LEADER_COLUMN, updatable = false)
+    public final PersonPE getProjectLeader()
+    {
+        return projectLeader;
+    }
+
+    public final void setProjectLeader(final PersonPE projectLeader)
+    {
+        this.projectLeader = projectLeader;
+    }
+
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 1000, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ProjectPE == false)
+        {
+            return false;
+        }
+        final ProjectPE that = (ProjectPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("code", getCode());
+        builder.append("description", getDescription());
+        return builder.toString();
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(final ProjectPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+    //
+    // IIdHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.PROJECT_SEQUENCE, sequenceName = SequenceNames.PROJECT_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.PROJECT_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @Column(unique = true)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public final String getCode()
+    {
+        return code;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypeEntityTypeRelation.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypeEntityTypeRelation.java
new file mode 100644
index 00000000000..f1b9b2dee57
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypeEntityTypeRelation.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Class that defines a relation between a {@link PropertyTypePE} and a
+ * {@link EntityTypeMandatorilyRelation}.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public final class PropertyTypeEntityTypeRelation implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final PropertyTypeEntityTypeRelation[] EMPTY_ARRAY =
+            new PropertyTypeEntityTypeRelation[0];
+
+    private PropertyTypePE property;
+
+    private EntityTypeMandatorilyRelation[] relations = new EntityTypeMandatorilyRelation[0];
+
+    public final PropertyTypePE getProperty()
+    {
+        return property;
+    }
+
+    public final void setProperty(final PropertyTypePE property)
+    {
+        this.property = property;
+    }
+
+    public final EntityTypeMandatorilyRelation[] getRelations()
+    {
+        return relations;
+    }
+
+    public final void setRelations(final EntityTypeMandatorilyRelation[] relations)
+    {
+        this.relations = relations;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof PropertyTypeEntityTypeRelation == false)
+        {
+            return false;
+        }
+        final PropertyTypeEntityTypeRelation that = (PropertyTypeEntityTypeRelation) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.property, property);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(property);
+        return builder.toHashCode();
+    }
+
+    public static Comparator<PropertyTypeEntityTypeRelation> cerateComparator()
+    {
+        return new Comparator<PropertyTypeEntityTypeRelation>()
+            {
+
+                public int compare(final PropertyTypeEntityTypeRelation o1,
+                        final PropertyTypeEntityTypeRelation o2)
+                {
+                    final PropertyTypePE property1 = o1.getProperty();
+                    final PropertyTypePE property2 = o2.getProperty();
+                    if (property1 == null)
+                    {
+                        return property2 == null ? 0 : -1;
+                    }
+                    if (property2 == null)
+                    {
+                        return 1;
+                    }
+                    return property1.compareTo(property2);
+                }
+
+            };
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypePE.java
new file mode 100644
index 00000000000..ad1619badd5
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/PropertyTypePE.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing property type.
+ * <p>
+ * Example of property types: DESCRIPTION, PLATE_GEOMETRY.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.PROPERTY_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.IS_INTERNAL_NAMESPACE,
+                ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class PropertyTypePE extends HibernateAbstractRegistratrationHolder implements
+        Comparable<PropertyTypePE>, IIdAndCodeHolder
+{
+    public static final PropertyTypePE[] EMPTY_ARRAY = new PropertyTypePE[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String simpleCode;
+
+    private DataTypePE type;
+
+    private String description;
+
+    private String label;
+
+    private VocabularyPE vocabulary;
+
+    private boolean internalNamespace;
+
+    private boolean managedInternally;
+
+    private transient Long id;
+
+    private DatabaseInstancePE databaseInstance;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.CONTROLLED_VOCABULARY_COLUMN, updatable = false)
+    public VocabularyPE getVocabulary()
+    {
+        return vocabulary;
+    }
+
+    public void setVocabulary(final VocabularyPE vocabulary)
+    {
+        this.vocabulary = vocabulary;
+    }
+
+    /**
+     * Sets code in 'database format' - without 'user prefix'. To set full code (with user prefix
+     * use {@link #setCode(String)}).
+     */
+    private void setSimpleCode(final String simpleCode)
+    {
+        this.simpleCode = simpleCode.toUpperCase();
+    }
+
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    private String getSimpleCode()
+    {
+        return simpleCode;
+    }
+
+    public void setCode(final String fullCode)
+    {
+        setInternalNamespace(CodeConverter.isInternalNamespace(fullCode));
+        setSimpleCode(CodeConverter.tryToDatabase(fullCode));
+    }
+
+    @Transient
+    public String getCode()
+    {
+        return CodeConverter.tryToBusinessLayer(getSimpleCode(), isInternalNamespace() == false);
+    }
+
+    @NotNull(message = ValidationMessages.DATA_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATA_TYPE_COLUMN, updatable = false)
+    public final DataTypePE getType()
+    {
+        return type;
+    }
+
+    public final void setType(final DataTypePE type)
+    {
+        this.type = type;
+    }
+
+    @NotNull(message = ValidationMessages.DESCRIPTION_NOT_NULL_MESSAGE)
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 80, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    public final void setDescription(final String description)
+    {
+        this.description = description;
+    }
+
+    @NotNull(message = ValidationMessages.LABEL_NOT_NULL_MESSAGE)
+    @Column(name = ColumnNames.LABEL_COLUMN)
+    @Length(max = 40, message = ValidationMessages.LABEL_LENGTH_MESSAGE)
+    public final String getLabel()
+    {
+        return label;
+    }
+
+    public final void setLabel(final String label)
+    {
+        this.label = label;
+    }
+
+    @NotNull
+    @Column(name = ColumnNames.IS_MANAGED_INTERNALLY)
+    public boolean isManagedInternally()
+    {
+        return managedInternally;
+    }
+
+    public void setManagedInternally(final boolean managedInternally)
+    {
+        this.managedInternally = managedInternally;
+    }
+
+    @NotNull
+    @Column(name = ColumnNames.IS_INTERNAL_NAMESPACE)
+    public boolean isInternalNamespace()
+    {
+        return internalNamespace;
+    }
+
+    public void setInternalNamespace(final boolean internalNamespace)
+    {
+        this.internalNamespace = internalNamespace;
+    }
+
+    @SequenceGenerator(name = SequenceNames.PROPERTY_TYPES_SEQUENCE, sequenceName = SequenceNames.PROPERTY_TYPES_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.PROPERTY_TYPES_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    //
+    // Comparable
+    //
+
+    /**
+     * If <code>null</code> values are present for <code>code</code>, then they come first.
+     */
+    public final int compareTo(final PropertyTypePE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof PropertyTypePE == false)
+        {
+            return false;
+        }
+        final PropertyTypePE that = (PropertyTypePE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getSimpleCode(), that.getSimpleCode());
+        builder.append(getDatabaseInstance(), that.getDatabaseInstance());
+        builder.append(isInternalNamespace(), that.isInternalNamespace());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getSimpleCode());
+        builder.append(getDatabaseInstance());
+        builder.append(isInternalNamespace());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return getCode();
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/QueryRestriction.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/QueryRestriction.java
new file mode 100644
index 00000000000..13c58cdd32d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/QueryRestriction.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.MaterialIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * A query restriction that is applied to experiments.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public class QueryRestriction implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private boolean suppressInvalidated;
+
+    private ProjectIdentifier projectIdentifier;
+
+    private GroupIdentifier groupIdentifier;
+
+    private MaterialIdentifier materialIdentifier;
+
+    private TimeInterval timeInterval;
+
+    /**
+     * The experiment type code.
+     */
+    private String experimentTypeCode;
+
+    public final boolean isSuppressInvalidated()
+    {
+        return suppressInvalidated;
+    }
+
+    public final void setSuppressInvalidated(final boolean suppressInvalid)
+    {
+        this.suppressInvalidated = suppressInvalid;
+    }
+
+    public final MaterialIdentifier getMaterialIdentifier()
+    {
+        return materialIdentifier;
+    }
+
+    public final void setMaterialIdentifier(final MaterialIdentifier materialIdentifier)
+    {
+        this.materialIdentifier = materialIdentifier;
+    }
+
+    public final ProjectIdentifier tryGetProjectIdentifier()
+    {
+        return projectIdentifier;
+    }
+
+    public final void setProjectIdentifier(final ProjectIdentifier projectIdentifier)
+    {
+        this.projectIdentifier = projectIdentifier;
+    }
+
+    public final GroupIdentifier tryGetGroupIdentifier()
+    {
+        return groupIdentifier;
+    }
+
+    public final void setGroupIdentifier(final GroupIdentifier groupIdentifier)
+    {
+        this.groupIdentifier = groupIdentifier;
+    }
+
+    public final TimeInterval getTimeInterval()
+    {
+        return timeInterval;
+    }
+
+    public final void setTimeInterval(final TimeInterval timeInterval)
+    {
+        this.timeInterval = timeInterval;
+    }
+
+    public final String getExperimentTypeCode()
+    {
+        return experimentTypeCode;
+    }
+
+    public final void setExperimentTypeCode(final String experimentTypeCode)
+    {
+        this.experimentTypeCode = experimentTypeCode;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        return EqualsBuilder.reflectionEquals(this, obj);
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        return HashCodeBuilder.reflectionHashCode(this);
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleAssignmentPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleAssignmentPE.java
new file mode 100644
index 00000000000..4ad1e6de598
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleAssignmentPE.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.annotations.Check;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistent Entity corresponding containing informations about role assignment.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Check(constraints = ColumnNames.DATABASE_INSTANCE_COLUMN + " IS NOT NULL AND "
+        + ColumnNames.GROUP_COLUMN + " IS NULL OR " + ColumnNames.DATABASE_INSTANCE_COLUMN
+        + " IS NULL AND " + ColumnNames.GROUP_COLUMN + " IS NOT NULL")
+@Table(name = TableNames.ROLE_ASSIGNMENTS_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.PERSON_GRANTEE_COLUMN, ColumnNames.ROLE_COLUMN, ColumnNames.GROUP_COLUMN,
+                ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class RoleAssignmentPE extends HibernateAbstractRegistratrationHolder implements
+        IIdHolder, Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final RoleAssignmentPE[] EMPTY_ARRAY = new RoleAssignmentPE[0];
+
+    public static final List<RoleAssignmentPE> EMPTY_LIST =
+            Collections.<RoleAssignmentPE> emptyList();
+
+    private transient Long id;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private GroupPE group;
+
+    private PersonPE person;
+
+    private RoleCode role;
+
+    @NotNull(message = ValidationMessages.ROLE_NOT_NULL_MESSAGE)
+    @Column(name = ColumnNames.ROLE_COLUMN)
+    @Enumerated(EnumType.STRING)
+    public final RoleCode getRole()
+    {
+        return role;
+    }
+
+    public final void setRole(final RoleCode role)
+    {
+        this.role = role;
+    }
+
+    @NotNull(message = ValidationMessages.PERSON_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.PERSON_GRANTEE_COLUMN, updatable = false)
+    public final PersonPE getPerson()
+    {
+        return person;
+    }
+
+    public final void setPerson(final PersonPE person)
+    {
+        this.person = person;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.GROUP_COLUMN, updatable = false)
+    public final GroupPE getGroup()
+    {
+        return group;
+    }
+
+    public final void setGroup(final GroupPE group)
+    {
+        this.group = group;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public final DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public final void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    //
+    // IIdHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.ROLE_ASSIGNMENT_SEQUENCE, sequenceName = SequenceNames.ROLE_ASSIGNMENT_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.ROLE_ASSIGNMENT_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof RoleAssignmentPE == false)
+        {
+            return false;
+        }
+        final RoleAssignmentPE that = (RoleAssignmentPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(role, that.role);
+        builder.append(person, that.person);
+        builder.append(databaseInstance, that.databaseInstance);
+        builder.append(group, that.group);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(role);
+        builder.append(person);
+        builder.append(databaseInstance);
+        builder.append(group);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleCode.java
new file mode 100644
index 00000000000..cbcd81039ad
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/RoleCode.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * The <i>openBIS</i> role codes.
+ * <p>
+ * These names reflect the ones that could be found in the database.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public enum RoleCode
+{
+    ADMIN, USER, OBSERVER, ETL_SERVER;
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Sample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Sample.java
new file mode 100644
index 00000000000..64624d91855
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Sample.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about a sample.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class Sample implements Serializable, Comparable<Sample>, ISimpleEntityPropertiesHolder
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private SampleIdentifier sampleIdentifier;
+
+    private SampleType sampleType;
+
+    private PersonPE registrator;
+
+    private ExternalData[] measurementData = new ExternalData[0];
+
+    private ExternalData[] derivedData = new ExternalData[0];
+
+    private Procedure procedure;
+
+    private Sample generatedFrom;
+
+    private Sample top;
+
+    private InvalidationPE invalidationOrNull;
+
+    /**
+     * The identifier of control layout assigned to the sample or null if nothing is assigned.
+     */
+    private SampleIdentifier controlLayoutIdentifierOrNull;
+
+    /** Registration date of this sample. */
+    private Date registrationDate;
+
+    private SimpleEntityProperty[] properties;
+
+    public EntityType getEntityType()
+    {
+        return getSampleType();
+    }
+
+    public final SampleType getSampleType()
+    {
+        return sampleType;
+    }
+
+    public final void setSampleType(final SampleType sampleType)
+    {
+        this.sampleType = sampleType;
+    }
+
+    /**
+     * Returns registrator.
+     * 
+     * @return <code>null</code> when undefined.
+     */
+    public final PersonPE getRegistrator()
+    {
+        return registrator;
+    }
+
+    /**
+     * Sets registrator.
+     * 
+     * @param registrator New value. Can be <code>null</code>.
+     */
+    public final void setRegistrator(final PersonPE registrator)
+    {
+        this.registrator = registrator;
+    }
+
+    public final Procedure getProcedure()
+    {
+        return procedure;
+    }
+
+    public final void setProcedure(final Procedure procedure)
+    {
+        this.procedure = procedure;
+    }
+
+    /**
+     * Never returns <code>null</code> but could return an empty array of
+     * <code>ExternalData</code>.
+     */
+    public final ExternalData[] getMeasurementData()
+    {
+        if (measurementData == null)
+        {
+            return new ExternalData[0];
+        }
+        return measurementData;
+    }
+
+    /**
+     * Sets <code>measurementData</code>.
+     * 
+     * @param externalData new value. Could be <code>null</code>.
+     */
+    public final void setMeasurementData(final ExternalData[] externalData)
+    {
+        this.measurementData = externalData;
+    }
+
+    /**
+     * Never returns <code>null</code> but could return an empty array of
+     * <code>ExternalData</code>.
+     */
+    public final ExternalData[] getDerivedData()
+    {
+        if (derivedData == null)
+        {
+            return new ExternalData[0];
+        }
+        return derivedData;
+    }
+
+    /**
+     * Sets <code>derivedData</code>.
+     * 
+     * @param externalData new value. Could be <code>null</code>.
+     */
+    public final void setDerivedData(final ExternalData[] externalData)
+    {
+        this.derivedData = externalData;
+    }
+
+    public final Sample getGeneratedFrom()
+    {
+        return generatedFrom;
+    }
+
+    public final void setGeneratedFrom(final Sample generatedFrom)
+    {
+        this.generatedFrom = generatedFrom;
+    }
+
+    public final Sample getTop()
+    {
+        return top;
+    }
+
+    public final void setTop(final Sample top)
+    {
+        this.top = top;
+    }
+
+    public final Date getRegistrationDate()
+    {
+        return registrationDate;
+    }
+
+    public final void setRegistrationDate(final Date registrationDate)
+    {
+        this.registrationDate = registrationDate;
+    }
+
+    /** Returns invalidation data or null */
+    public InvalidationPE getInvalidation()
+    {
+        return invalidationOrNull;
+    }
+
+    public void setInvalidation(final InvalidationPE invalidation)
+    {
+        this.invalidationOrNull = invalidation;
+    }
+
+    public SampleIdentifier getSampleIdentifier()
+    {
+        return sampleIdentifier;
+    }
+
+    public void setSampleIdentifier(SampleIdentifier sampleIdentifier)
+    {
+        this.sampleIdentifier = sampleIdentifier;
+    }
+
+    /** can be null */
+    public final SampleIdentifier getControlLayoutIdentifier()
+    {
+        return controlLayoutIdentifierOrNull;
+    }
+
+    public final void setControlLayoutIdentifier(SampleIdentifier controlLayoutIdentifierOrNull)
+    {
+        this.controlLayoutIdentifierOrNull = controlLayoutIdentifierOrNull;
+    }
+
+    //
+    // IEntityPropertiesHolder
+    //
+
+    public final SimpleEntityProperty[] getProperties()
+    {
+        return properties;
+    }
+
+    public final void setProperties(final SimpleEntityProperty[] properties)
+    {
+        this.properties = properties;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj == null || obj instanceof Sample == false)
+        {
+            return false;
+        }
+        Sample sample = (Sample) obj;
+        return sampleIdentifier.equals(sample.getSampleIdentifier());
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return sampleIdentifier == null ? 43 : sampleIdentifier.hashCode();
+    }
+
+    public int compareTo(Sample sample)
+    {
+        SampleIdentifier thatIdent = sample.getSampleIdentifier();
+        SampleIdentifier thisIdent = getSampleIdentifier();
+        if (thisIdent == null)
+        {
+            return thatIdent == null ? 0 : -1;
+        }
+        if (thatIdent == null)
+        {
+            return 1;
+        }
+
+        return thisIdent.compareTo(thatIdent);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleFilter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleFilter.java
new file mode 100644
index 00000000000..0793b58506d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleFilter.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierPattern;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleOwnerIdentifier;
+
+/**
+ * Bean specifying a {@link SamplePE} filter.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public class SampleFilter extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private SampleIdentifierPattern[] patterns;
+
+    private boolean notRegisteredToExperiment;
+
+    private boolean hideInvalidated;
+
+    /** see class getters documentation */
+    public SampleFilter(final SampleIdentifierPattern[] patterns,
+            final boolean notRegisteredToExperiment, final boolean hideInvalidated)
+    {
+        assert patterns != null : "Unspecified patterns";
+        this.patterns = patterns;
+        this.notRegisteredToExperiment = notRegisteredToExperiment;
+        this.hideInvalidated = hideInvalidated;
+    }
+
+    /**
+     * Returns whether only those samples should be passing the filters that are not registered to
+     * an experiment.
+     */
+    public final boolean isNotRegisteredToExperiment()
+    {
+        return notRegisteredToExperiment;
+    }
+
+    /**
+     * Filters samples visible for specified owner and with code matching the wildcards pattern (* =
+     * any string, ? = any character). Note, that if there are no patterns, no sample will match.
+     */
+    public final SampleIdentifierPattern[] getPatterns()
+    {
+        return patterns;
+    }
+
+    /**
+     * Returns either the patterns specified in the constructor or if not defined default patterns
+     * based on the specified home group.
+     */
+    public SampleIdentifierPattern[] getPatternsOrDefaultPatterns(GroupPE homeGroupOrNull)
+    {
+        if (patterns.length > 0)
+        {
+            return patterns;
+        }
+        if (homeGroupOrNull == null || homeGroupOrNull.getCode() == null)
+        {
+            SampleOwnerIdentifier owner =
+                    new SampleOwnerIdentifier(DatabaseInstanceIdentifier.createHome());
+            return new SampleIdentifierPattern[]
+                { SampleIdentifierPattern.createOwnedBy(owner, "*") };
+        }
+        GroupIdentifier groupIdentifier =
+                new GroupIdentifier(DatabaseInstanceIdentifier.HOME, homeGroupOrNull.getCode());
+        return SampleIdentifierPattern.createGroupVisible(groupIdentifier, "*");
+    }
+
+    /** If <code>true</code> only valid samples are returned. */
+    public final boolean isHideInvalidated()
+    {
+        return hideInvalidated;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGenerationDTO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGenerationDTO.java
new file mode 100644
index 00000000000..c1223535133
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleGenerationDTO.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A <code>SampleGeneration</code> encapsulates a generator <code>SampleDTO</code> and its
+ * generated <code>SampleDTO</code>s.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class SampleGenerationDTO implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /**
+     * The <code>Sample</code> parent.
+     */
+    private SamplePE generator;
+
+    /** The <code>Sample</code> children. */
+    private SamplePE[] generated;
+
+    public SampleGenerationDTO()
+    {
+
+    }
+
+    public SampleGenerationDTO(final SamplePE generator, final List<SamplePE> generated)
+    {
+        assert generator != null : "Generator can not be null.";
+        assert generated != null : "Generated can not be null.";
+        setGenerator(generator);
+        setGenerated(generated.toArray(SamplePE.EMPTY_ARRAY));
+    }
+
+    /**
+     * Never returns <code>null</code> but could return an empty list.
+     */
+    public final SamplePE[] getGenerated()
+    {
+        return generated;
+    }
+
+    public final SamplePE getGenerator()
+    {
+        return generator;
+    }
+
+    public void setGenerator(final SamplePE generator)
+    {
+        this.generator = generator;
+    }
+
+    public void setGenerated(final SamplePE[] generated)
+    {
+        this.generated = generated;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
new file mode 100644
index 00000000000..f27725e6287
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePE.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.annotations.Check;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.IdentifierHelper;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+
+/**
+ * <i>Persistent Entity</i> object of an entity 'sample'.
+ * 
+ * @author Christian Ribeaud
+ */
+@Entity
+@Table(name = TableNames.SAMPLES_TABLE)
+@Check(constraints = "(" + ColumnNames.DATABASE_INSTANCE_COLUMN + " IS NOT NULL AND "
+        + ColumnNames.GROUP_COLUMN + " IS NULL) OR (" + ColumnNames.DATABASE_INSTANCE_COLUMN
+        + " IS NULL AND " + ColumnNames.GROUP_COLUMN + " IS NOT NULL)")
+public class SamplePE extends HibernateAbstractRegistratrationHolder implements IIdAndCodeHolder,
+        Comparable<SamplePE>, IEntityPropertiesHolder<SamplePropertyPE>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final SamplePE[] EMPTY_ARRAY = new SamplePE[0];
+
+    public static final List<SamplePE> EMPTY_LIST = Collections.emptyList();
+
+    private Long id;
+
+    private String code;
+
+    private SampleTypePE sampleType;
+
+    private DatabaseInstancePE databaseInstance;
+
+    private GroupPE group;
+
+    private SampleIdentifier sampleIdentifier;
+
+    private SamplePE controlLayout;
+
+    private SamplePE container;
+
+    private SamplePE top;
+
+    private SamplePE generatedFrom;
+
+    private List<ProcedurePE> procedures = ProcedurePE.EMPTY_LIST;
+
+    private ProcedurePE validProcedure;
+
+    private ExternalDataPE[] measurementData = ExternalDataPE.EMPTY_ARRAY;
+
+    private ExternalDataPE[] derivedData = ExternalDataPE.EMPTY_ARRAY;
+
+    /**
+     * Invalidation information.
+     * <p>
+     * If not <code>null</code>, then this sample is considered as <i>invalid</i>.
+     * </p>
+     */
+    private InvalidationPE invalidation;
+
+    private List<SamplePropertyPE> properties = SamplePropertyPE.EMPTY_LIST;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.INVALIDATION_COLUMN)
+    public InvalidationPE getInvalidation()
+    {
+        return invalidation;
+    }
+
+    public void setInvalidation(final InvalidationPE invalidation)
+    {
+        this.invalidation = invalidation;
+    }
+
+    @Transient
+    public SampleIdentifier getSampleIdentifier()
+    {
+        if (sampleIdentifier == null)
+        {
+            sampleIdentifier = IdentifierHelper.createIdentifier(this);
+        }
+        return sampleIdentifier;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.GROUP_COLUMN, updatable = false)
+    public GroupPE getGroup()
+    {
+        return group;
+    }
+
+    public void setGroup(final GroupPE group)
+    {
+        this.group = group;
+    }
+
+    public void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public final void setId(final Long id)
+    {
+        this.id = id;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.SAMPLE_TYPE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.SAMPLE_TYPE_COLUMN, updatable = false)
+    public SampleTypePE getSampleType()
+    {
+        return sampleType;
+    }
+
+    public void setSampleType(final SampleTypePE sampleType)
+    {
+        this.sampleType = sampleType;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "sample")
+    private List<SamplePropertyPE> getSampleProperties()
+    {
+        return properties;
+    }
+
+    private void setSampleProperties(final List<SamplePropertyPE> properties)
+    {
+        this.properties = properties;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.CONTROL_LAYOUT_SAMPLE_COLUMN, updatable = false)
+    public SamplePE getControlLayout()
+    {
+        return controlLayout;
+    }
+
+    public void setControlLayout(final SamplePE controlLayout)
+    {
+        this.controlLayout = controlLayout;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.PART_OF_SAMPLE_COLUMN, updatable = false)
+    public SamplePE getContainer()
+    {
+        return container;
+    }
+
+    public void setContainer(final SamplePE container)
+    {
+        this.container = container;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.TOP_SAMPLE_COLUMN)
+    public SamplePE getTop()
+    {
+        return top;
+    }
+
+    public void setTop(final SamplePE top)
+    {
+        this.top = top;
+    }
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.GENERATED_FROM_SAMPLE_COLUMN)
+    public SamplePE getGeneratedFrom()
+    {
+        return generatedFrom;
+    }
+
+    public void setGeneratedFrom(final SamplePE generatedFrom)
+    {
+        this.generatedFrom = generatedFrom;
+    }
+
+    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+    @JoinTable(name = TableNames.SAMPLE_INPUTS_TABLE, joinColumns = @JoinColumn(name = ColumnNames.SAMPLE_COLUMN), inverseJoinColumns = @JoinColumn(name = ColumnNames.PROCEDURE_COLUMN))
+    public List<ProcedurePE> getProcedures()
+    {
+        return procedures;
+    }
+
+    public void setProcedures(final List<ProcedurePE> procedures)
+    {
+        this.procedures = procedures;
+    }
+
+    @Transient
+    public ProcedurePE getValidProcedure()
+    {
+        return validProcedure;
+    }
+
+    public void setValidProcedure(final ProcedurePE validProcedure)
+    {
+        this.validProcedure = validProcedure;
+    }
+
+    @Transient
+    public ExternalDataPE[] getMeasurementData()
+    {
+        return measurementData;
+    }
+
+    public void setMeasurementData(final ExternalDataPE[] measurementData)
+    {
+        this.measurementData = measurementData;
+    }
+
+    @Transient
+    public ExternalDataPE[] getDerivedData()
+    {
+        return derivedData;
+    }
+
+    public void setDerivedData(final ExternalDataPE[] derivedData)
+    {
+        this.derivedData = derivedData;
+    }
+
+    //
+    // IIdAndCodeHolder
+    //
+
+    @SequenceGenerator(name = SequenceNames.SAMPLE_SEQUENCE, sequenceName = SequenceNames.SAMPLE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.SAMPLE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof SamplePE == false)
+        {
+            return false;
+        }
+        final SamplePE that = (SamplePE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        builder.append(getSampleType(), that.getSampleType());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        builder.append(getSampleType());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("code", getCode());
+        builder.append("sampleType", getSampleType());
+        return builder.toString();
+    }
+
+    //
+    // Compare
+    //
+
+    public final int compareTo(final SamplePE o)
+    {
+        return getSampleIdentifier().compareTo(o.getSampleIdentifier());
+    }
+
+    //
+    // IEntityPropertiesHolder
+    //
+
+    @Transient
+    public List<SamplePropertyPE> getProperties()
+    {
+        return getSampleProperties();
+    }
+
+    public void setProperties(final List<SamplePropertyPE> properties)
+    {
+        for (final SamplePropertyPE sampleProperty : properties)
+        {
+            final SamplePE parent = sampleProperty.getSample();
+            if (parent != null)
+            {
+                parent.getProperties().remove(sampleProperty);
+            }
+            sampleProperty.setSample(this);
+        }
+        setSampleProperties(properties);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePropertyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePropertyPE.java
new file mode 100644
index 00000000000..8c4d5b09f33
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SamplePropertyPE.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing sample property.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.SAMPLE_PROPERTIES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.ID_COLUMN }) })
+public class SamplePropertyPE extends EntityPropertyPE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final SamplePropertyPE[] EMPTY_ARRAY = new SamplePropertyPE[0];
+
+    public static final List<SamplePropertyPE> EMPTY_LIST =
+            Collections.<SamplePropertyPE> emptyList();
+
+    private SamplePE sample;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = ColumnNames.SAMPLE_COLUMN, updatable = false)
+    public SamplePE getSample()
+    {
+        return sample;
+    }
+
+    public void setSample(final SamplePE sample)
+    {
+        this.sample = sample;
+    }
+
+    //
+    // EntityPropertyPE
+    //
+
+    @NotNull(message = ValidationMessages.SAMPLE_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = SampleTypePropertyTypePE.class)
+    @JoinColumn(name = ColumnNames.SAMPLE_TYPE_PROPERTY_TYPE_COLUMN, updatable = false)
+    public EntityTypePropertyTypePE getEntityTypePropertyType()
+    {
+        return entityTypePropertyType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.SAMPLE_PROPERTY_SEQUENCE, sequenceName = SequenceNames.SAMPLE_PROPERTY_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.SAMPLE_PROPERTY_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    @Transient
+    public Long getEntityId()
+    {
+        return entityId;
+    }
+
+    @Override
+    public void setEntityId(final Long entityId)
+    {
+        sample = new SamplePE();
+        sample.setId(entityId);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleType.java
new file mode 100644
index 00000000000..50382371e4e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Kind of <i>Java Bean</i> or <i>Value Object</i> which transports through Web Service any
+ * information we would like to know about a sample type.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class SampleType extends EntityType
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final SampleType[] EMPTY_ARRAY = new SampleType[0];
+    
+    private boolean plate;
+
+    private boolean controlLayout;
+
+    public final boolean isPlate()
+    {
+        return plate;
+    }
+
+    public final void setPlate(boolean plate)
+    {
+        this.plate = plate;
+    }
+
+    public final boolean isControlLayout()
+    {
+        return controlLayout;
+    }
+
+    public final void setControlLayout(final boolean controlLayout)
+    {
+        this.controlLayout = controlLayout;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePE.java
new file mode 100644
index 00000000000..cf1a436f075
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePE.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.types.SampleTypeCode;
+
+/**
+ * Persistence Entity representing 'sample type'.
+ * 
+ * @author Christian Ribeaud
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.SAMPLE_TYPES_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public final class SampleTypePE extends EntityTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    @Transient
+    public final boolean isPlate()
+    {
+        return getCode().endsWith("_PLATE");
+    }
+
+    @Transient
+    public final boolean isControlLayout()
+    {
+        return SampleTypeCode.CONTROL_LAYOUT.getCode().equals(getCode());
+    }
+
+    //
+    // EntityTypePE
+    //
+
+    @SequenceGenerator(name = SequenceNames.SAMPLE_TYPE_SEQUENCE, sequenceName = SequenceNames.SAMPLE_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.SAMPLE_TYPE_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePropertyTypePE.java
new file mode 100644
index 00000000000..cc909d5a280
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SampleTypePropertyTypePE.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing sample type - property type relation.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.SAMPLE_TYPE_PROPERTY_TYPE_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.SAMPLE_TYPE_COLUMN, ColumnNames.PROPERTY_TYPE_COLUMN }) })
+public class SampleTypePropertyTypePE extends EntityTypePropertyTypePE
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final SampleTypePropertyTypePE[] EMPTY_ARRAY = new SampleTypePropertyTypePE[0];
+
+    public SampleTypePropertyTypePE()
+    {
+
+    }
+
+    //
+    // EntityTypePropertyTypePE
+    //
+
+    @NotNull(message = ValidationMessages.SAMPLE_TYPE_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER, targetEntity = SampleTypePE.class)
+    @JoinColumn(name = ColumnNames.SAMPLE_TYPE_COLUMN)
+    public EntityTypePE getEntityType()
+    {
+        return entityType;
+    }
+
+    @SequenceGenerator(name = SequenceNames.SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE, sequenceName = SequenceNames.SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE)
+    @Column(insertable = false, updatable = false)
+    public Long getId()
+    {
+        return id;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SequenceNames.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SequenceNames.java
new file mode 100644
index 00000000000..b852fca8a07
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SequenceNames.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * The database sequence names.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class SequenceNames
+{
+
+    public static final String CONTROLLED_VOCABULARY_SEQUENCE = "CONTROLLED_VOCABULARY_ID_SEQ";
+
+    public static final String CONTROLLED_VOCABULARY_TERM_SEQUENCE = "CVTE_ID_SEQ";
+
+    public static final String DATA_SEQUENCE = "DATA_ID_SEQ";
+
+    public static final String DATA_SET_RELATIONSHIP_SEQUENCE = "DATA_SET_RELATIONSHIP_ID_SEQ";
+
+    public static final String DATA_STORE_SEQUENCE = "DATA_STORE_ID_SEQ";
+
+    public static final String DATA_TYPE_SEQUENCE = "DATA_TYPE_ID_SEQ";
+
+    public static final String DATABASE_INSTANCE_SEQUENCE = "DATABASE_INSTANCE_ID_SEQ";
+
+    public static final String EXPERIMENT_ATTACHMENT_SEQUENCE = "EXPERIMENT_ATTACHMENT_ID_SEQ";
+
+    public static final String EXPERIMENT_PROPERTY_SEQUENCE = "EXPERIMENT_PROPERTY_ID_SEQ";
+
+    public static final String EXPERIMENT_SEQUENCE = "EXPERIMENT_ID_SEQ";
+
+    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE = "ETPT_ID_SEQ";
+
+    public static final String EXPERIMENT_TYPE_SEQUENCE = "EXPERIMENT_TYPE_ID_SEQ";
+
+    public static final String FILE_FORMAT_TYPE_SEQUENCE = "FILE_FORMAT_TYPE_ID_SEQ";
+
+    public static final String GROUP_SEQUENCE = "GROUP_ID_SEQ";
+
+    public static final String INVALIDATION_SEQUENCE = "INVALIDATION_ID_SEQ";
+
+    public static final String LOCATOR_TYPE_SEQUENCE = "LOCATOR_TYPE_ID_SEQ";
+
+    public static final String MATERIAL_BATCH_SEQUENCE = "MATERIAL_BATCH_ID_SEQ";
+
+    public static final String MATERIAL_PROPERTY_SEQUENCE = "MATERIAL_PROPERTY_ID_SEQ";
+
+    public static final String MATERIAL_SEQUENCE = "MATERIAL_ID_SEQ";
+
+    public static final String MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE = "MTPT_ID_SEQ";
+
+    public static final String DATA_SET_TYPE_SEQUENCE = "DATA_SET_TYPE_ID_SEQ";
+
+    public final static String PERSON_SEQUENCE = "PERSON_ID_SEQ";
+
+    public static final String MATERIAL_TYPE_SEQUENCE = "MATERIAL_TYPE_ID_SEQ";
+
+    public static final String PROCEDURE_SEQUENCE = "PROCEDURE_ID_SEQ";
+
+    public static final String PROCEDURE_TYPE_SEQUENCE = "PROCEDURE_TYPE_ID_SEQ";
+
+    public static final String PROJECT_SEQUENCE = "PROJECT_ID_SEQ";
+
+    public static final String PROPERTY_TYPES_SEQUENCE = "PROPERTY_TYPE_ID_SEQ";
+
+    public static final String ROLE_ASSIGNMENT_SEQUENCE = "ROLE_ASSIGNMENT_ID_SEQ";
+
+    public static final String SAMPLE_INPUT_SEQUENCE = "SAMPLE_INPUT_ID_SEQ";
+
+    public static final String SAMPLE_MATERIAL_BATCH_SEQUENCE = "SAMPLE_MATERIAL_BATCH_ID_SEQ";
+
+    public static final String SAMPLE_PROPERTY_SEQUENCE = "SAMPLE_PROPERTY_ID_SEQ";
+
+    public static final String SAMPLE_SEQUENCE = "SAMPLE_ID_SEQ";
+
+    public static final String SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE = "STPT_ID_SEQ";
+
+    public static final String SAMPLE_TYPE_SEQUENCE = "SAMPLE_TYPE_ID_SEQ";
+
+    private SequenceNames()
+    {
+        // Can not be instantiated.
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
index 42dc5012498..a370a583682 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/Session.java
@@ -20,8 +20,6 @@ import org.apache.commons.lang.time.DateFormatUtils;
 
 import ch.systemsx.cisd.authentication.BasicSession;
 import ch.systemsx.cisd.authentication.Principal;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 
 /**
  * Extendion of {@link BasicSession} which may holds a {@link PersonPE} instance.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SimpleEntityProperty.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SimpleEntityProperty.java
new file mode 100644
index 00000000000..5f7961bce8c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/SimpleEntityProperty.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityDataType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityPropertyValue;
+
+/**
+ * Simple version of EntityProperty which can be expressed in web service definition language<br>
+ * Deprecated methods should be used only during bean conversion.
+ * 
+ * @author Tomasz Pylak
+ */
+public final class SimpleEntityProperty extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public final static SimpleEntityProperty[] EMPTY_ARRAY = new SimpleEntityProperty[0];
+
+    /** Label of the property, which is shown to the user. */
+    private String label;
+
+    private String code;
+
+    private EntityDataType dataType;
+
+    private Serializable value;
+
+    public SimpleEntityProperty()
+    {
+    }
+
+    public SimpleEntityProperty(final String name, final String label,
+            final EntityDataType dataType, final Serializable valueOrNull)
+    {
+        this.code = name;
+        this.label = label;
+        this.dataType = dataType;
+        this.value = valueOrNull;
+    }
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    public final EntityDataType getDataType()
+    {
+        return dataType;
+    }
+
+    public final Serializable getValue()
+    {
+        return value;
+    }
+
+    // can be null
+    public String getUntypedValue()
+    {
+        return EntityPropertyValue.createFromSimple(this).tryGetUntypedValue();
+    }
+
+    public final String getLabel()
+    {
+        return label;
+    }
+
+    public final void setLabel(final String label)
+    {
+        this.label = label;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public final void setDataType(final EntityDataType dataType)
+    {
+        this.dataType = dataType;
+    }
+
+    public final void setValue(final Serializable value)
+    {
+        this.value = value;
+    }
+
+    public final void setValue(final String value)
+    {
+        this.value = value;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/StorageFormat.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/StorageFormat.java
new file mode 100644
index 00000000000..7a9dba1a7f8
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/StorageFormat.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * An enumeration that describes what format an external data set is stored in.
+ * 
+ * @author Bernd Rinn
+ */
+public enum StorageFormat
+{
+
+    /** The proprietary data format as acquired from the measurement device. */
+    PROPRIETARY("PROPRIETARY"),
+    /**
+     * The standardized data according to the Biological Data Standard format, using a directory
+     * container.
+     */
+    BDS_DIRECTORY("BDS_DIRECTORY");
+
+    private static final Map<String, StorageFormat> codeMap = new HashMap<String, StorageFormat>();
+
+    static
+    {
+        for (final StorageFormat format : values())
+        {
+            assert codeMap.containsKey(format.code) == false : "Duplicate code";
+            codeMap.put(format.code, format);
+        }
+    }
+
+    private final String code;
+
+    private StorageFormat(final String code)
+    {
+        this.code = code;
+    }
+
+    /**
+     * Returns the code (string representation) of this storage format.
+     * <p>
+     * Use this instead of {@link #toString()} when storing in the database.
+     */
+    public final String getCode()
+    {
+        return code;
+    }
+
+    /**
+     * Returns the appropriate format for the given <var>code</var>, or <code>null</code>, if
+     * there is no format for this <var>code</var>.
+     */
+    public final static StorageFormat tryGetFromCode(final String code)
+    {
+        return codeMap.get(code);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TableNames.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TableNames.java
new file mode 100644
index 00000000000..caa8242d38f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TableNames.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * This class lists the tables that can be found in the database.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class TableNames
+{
+
+    public static final String CONTROLLED_VOCABULARY_TABLE = "controlled_vocabularies";
+
+    public static final String CONTROLLED_VOCABULARY_TERM_TABLE = "controlled_vocabulary_terms";
+
+    public static final Object CONTROLLED_VOCABULARY_TERMS_TABLE = "controlled_vocabulary_terms";
+
+    public static final String DATA_SET_RELATIONSHIPS_TABLE = "data_set_relationships";
+
+    public static final String DATA_STORES_TABLE = "data_stores";
+
+    public static final String DATA_TABLE = "data";
+
+    public static final String DATA_TYPES_TABLE = "data_types";
+
+    public static final String DATABASE_INSTANCES_TABLE = "database_instances";
+
+    public static final String EXPERIMENT_ATTACHMENTS_TABLE = "experiment_attachments";
+
+    public static final String EXPERIMENT_PROPERTIES_TABLE = "experiment_properties";
+
+    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_TABLE =
+            "experiment_type_property_types";
+
+    public static final String EXPERIMENT_TYPES_TABLE = "experiment_types";
+
+    public static final String EXPERIMENTS_TABLE = "experiments";
+
+    public static final String EXTERNAL_DATA_TABLE = "external_data";
+
+    public static final String FILE_FORMAT_TYPES_TABLE = "file_format_types";
+
+    public static final String GROUPS_TABLE = "groups";
+
+    public static final String INVALIDATION_TABLE = "invalidations";
+
+    public static final String LOCATOR_TYPES_TABLE = "locator_types";
+
+    public static final String MATERIAL_BATCHES_TABLE = "material_batches";
+
+    public static final String MATERIAL_PROPERTIES_TABLE = "material_properties";
+
+    public static final String MATERIAL_TYPE_PROPERTY_TYPE_TABLE = "material_type_property_types";
+
+    public static final String MATERIAL_TYPES_TABLE = "material_types";
+
+    public static final String MATERIALS_TABLE = "materials";
+
+    public static final String DATA_SET_TYPES_TABLE = "data_set_types";
+
+    public static final String PERSONS_TABLE = "persons";
+
+    public static final String PROCEDURE_TYPES_TABLE = "procedure_types";
+
+    public static final String PROCEDURES_TABLE = "procedures";
+
+    public static final String PROJECTS_TABLE = "projects";
+
+    public static final String PROPERTY_TYPES_TABLE = "property_types";
+
+    public static final String ROLE_ASSIGNMENTS_TABLE = "role_assignments";
+
+    public static final String SAMPLE_INPUTS_TABLE = "sample_inputs";
+
+    public static final String SAMPLE_MATERIAL_BATCHES_TABLE = "sample_material_batches";
+
+    public static final String SAMPLE_PROPERTIES_TABLE = "sample_properties";
+
+    public static final String SAMPLE_TYPE_PROPERTY_TYPE_TABLE = "sample_type_property_types";
+
+    public static final String SAMPLE_TYPES_TABLE = "sample_types";
+
+    public static final String SAMPLES_TABLE = "samples";
+
+    private TableNames()
+    {
+        // This class can not be instantiated.
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TimeInterval.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TimeInterval.java
new file mode 100644
index 00000000000..d4f83d05939
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/TimeInterval.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * A time range composed of a <code>from</code> and of an <code>until</code> date.
+ * <p>
+ * Note that both dates can be <code>null</code>.
+ * </p>
+ * 
+ * @author Franz-Josef Elmer
+ */
+public final class TimeInterval implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private Date from;
+
+    private Date until;
+
+    public TimeInterval()
+    {
+    }
+
+    public TimeInterval(final Date from, final Date until)
+    {
+        check(from, until);
+        this.from = from;
+        this.until = until;
+    }
+
+    private void check(final Date fromDate, final Date untilDate)
+    {
+        if (fromDate != null && untilDate != null && fromDate.getTime() > untilDate.getTime())
+        {
+            throw new IllegalArgumentException("From date is after until date: " + fromDate + " > "
+                    + untilDate);
+        }
+    }
+
+    public final Date getFrom()
+    {
+        return from;
+    }
+
+    public final void setFrom(final Date from)
+    {
+        check(until, from);
+        this.from = from;
+    }
+
+    public final Date getUntil()
+    {
+        return until;
+    }
+
+    public final void setUntil(final Date until)
+    {
+        check(until, from);
+        this.until = until;
+    }
+
+    public final boolean isInside(final Date date)
+    {
+        assert date != null : "Unspecified date.";
+        final long time = date.getTime();
+        return (from == null || from.getTime() <= time)
+                && (until == null || time <= until.getTime());
+    }
+
+    public final boolean overlapsWith(final TimeInterval timeInterval)
+    {
+        assert timeInterval != null : "Unspecified time interval.";
+        return isBeforeOrEqual(from, timeInterval.getUntil())
+                && isBeforeOrEqual(timeInterval.getFrom(), until);
+    }
+
+    /**
+     * Whether given <var>olderDate</var> is before or equal to given <var>youngerDate</var>.
+     * <p>
+     * Returns <code>true</code> if one of given arguments is <code>null</code>.
+     * </p>
+     */
+    private final static boolean isBeforeOrEqual(final Date olderDate, final Date youngerDate)
+    {
+        return olderDate == null || youngerDate == null
+                || olderDate.getTime() <= youngerDate.getTime();
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof TimeInterval == false)
+        {
+            return false;
+        }
+        final TimeInterval that = (TimeInterval) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(that.from, from);
+        builder.append(that.until, until);
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(from);
+        builder.append(until);
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ValidationMessages.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ValidationMessages.java
new file mode 100644
index 00000000000..5fa54478317
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/ValidationMessages.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+/**
+ * This class lists the validation messages.
+ * <p>
+ * Each field definition follows schema:
+ * <code>&lt;field-name&gt;_&lt;validation-annotation&gt;_MESSAGE</code>.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ValidationMessages
+{
+
+    private static final String CAN_NOT_BE_NULL = " can not be null.";
+
+    private static final String LENGTH_PREFIX = "Given ";
+
+    private static final String LENGTH_SUFFIX =
+            " '%s' is too long (maximal length: {max} characters).";
+
+    public static final String ATTACHMENT_CONTENT_NOT_NULL_MESSAGE =
+            "The content of the attachment" + CAN_NOT_BE_NULL;
+
+    public static final String CODE_LENGTH_MESSAGE =
+            "Given code '%s' is either too short (minimal length: {min} character) "
+                    + "or too long (maximal length: {max} characters).";
+
+    public static final String CODE_NOT_NULL_MESSAGE = "Code" + CAN_NOT_BE_NULL;
+
+    public static final String CODE_PATTERN_MESSAGE =
+            "Given code '%s' contains illegal characters (allowed: A-Z, a-z, 0-9, _ and -)";
+
+    public static final String DATA_TYPE_NOT_NULL_MESSAGE = "Data type" + CAN_NOT_BE_NULL;
+
+    public static final String DATABASE_INSTANCE_NOT_NULL_MESSAGE =
+            "Database instance" + CAN_NOT_BE_NULL;
+
+    public final static String DESCRIPTION_LENGTH_MESSAGE =
+            LENGTH_PREFIX + "description" + LENGTH_SUFFIX;
+
+    public static final String DESCRIPTION_NOT_NULL_MESSAGE = "Description" + CAN_NOT_BE_NULL;
+
+    public static final String DOWNLOAD_URL_NOT_NULL_MESSAGE = "Download URL" + CAN_NOT_BE_NULL;
+
+    public static final String EMAIL_EMAIL_MESSAGE = "Given email address '%s' is not a valid one.";
+
+    public static final String EMAIL_LENGTH_MESSAGE =
+            LENGTH_PREFIX + "email address" + LENGTH_SUFFIX;
+
+    public static final String EXPERIMENT_NOT_NULL_MESSAGE = "Experiment " + CAN_NOT_BE_NULL;
+
+    public static final String EXPERIMENT_TYPE_NOT_NULL_MESSAGE =
+            "Experiment type" + CAN_NOT_BE_NULL;
+
+    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_NOT_NULL_MESSAGE =
+            "Experiment type - property type" + CAN_NOT_BE_NULL;
+
+    public static final String FILE_FORMAT_TYPE_NOT_NULL_MESSAGE =
+            "File format type" + CAN_NOT_BE_NULL;
+
+    public static final String FILE_NAME_LENGTH_MESSAGE =
+            LENGTH_PREFIX + "file name" + LENGTH_SUFFIX;
+
+    public static final String FILE_NAME_NOT_NULL_MESSAGE = "File name" + CAN_NOT_BE_NULL;
+
+    public static final String FIRST_NAME_LENGTH_MESSAGE =
+            LENGTH_PREFIX + "first name" + LENGTH_SUFFIX;
+
+    public static final String GROUP_NOT_NULL_MESSAGE = "Group" + CAN_NOT_BE_NULL;
+
+    public static final String IS_COMPLETE_NOT_NULL_MESSAGE = "Complete flag" + CAN_NOT_BE_NULL;
+
+    public static final String LABEL_LENGTH_MESSAGE = LENGTH_PREFIX + "label" + LENGTH_SUFFIX;
+
+    public static final String LABEL_NOT_NULL_MESSAGE = "Label" + CAN_NOT_BE_NULL;
+
+    public static final String LAST_NAME_LENGTH_MESSAGE =
+            LENGTH_PREFIX + "last name" + LENGTH_SUFFIX;
+
+    public static final String LOCATION_LENGTH_MESSAGE = LENGTH_PREFIX + "location" + LENGTH_SUFFIX;
+
+    public static final String LOCATION_NOT_NULL_MESSAGE = "Location" + CAN_NOT_BE_NULL;
+
+    public static final String LOCATION_NOT_RELATIVE = "Location is not relative";
+
+    public static final String LOCATOR_TYPE_NOT_NULL_MESSAGE = "Locator type" + CAN_NOT_BE_NULL;
+
+    public static final String MATERIAL_TYPE_NOT_NULL_MESSAGE = "Material type" + CAN_NOT_BE_NULL;
+
+    public static final String MATERIAL_NOT_NULL_MESSAGE = "Material" + CAN_NOT_BE_NULL;
+
+    public static final String MATERIAL_TYPE_PROPERTY_TYPE_NOT_NULL_MESSAGE =
+            "Material type - property type" + CAN_NOT_BE_NULL;
+
+    public static final String DATA_SET_TYPE_NOT_NULL_MESSAGE = "Data set type" + CAN_NOT_BE_NULL;
+
+    public static final String PERSON_NOT_NULL_MESSAGE = "Person" + CAN_NOT_BE_NULL;
+
+    public static final String PROCEDURE_NOT_NULL_MESSAGE = "Procedure" + CAN_NOT_BE_NULL;
+
+    public static final String PROPERTY_TYPE_NOT_NULL_MESSAGE = "Property type" + CAN_NOT_BE_NULL;
+
+    public static final String ROLE_NOT_NULL_MESSAGE = "Role" + CAN_NOT_BE_NULL;
+
+    public static final String SAMPLE_TYPE_NOT_NULL_MESSAGE = "Sample type" + CAN_NOT_BE_NULL;
+
+    public static final String SAMPLE_TYPE_PROPERTY_TYPE_NOT_NULL_MESSAGE =
+            "Sample type - property type" + CAN_NOT_BE_NULL;
+
+    public static final String STORAGE_FORMAT_NOT_NULL_MESSAGE = "Storage format" + CAN_NOT_BE_NULL;
+
+    public static final String USER_ID_LENGTH_MESSAGE = LENGTH_PREFIX + "user id" + LENGTH_SUFFIX;
+
+    public static final String USER_ID_NOT_NULL_MESSAGE = "User id" + CAN_NOT_BE_NULL;
+
+    public static final String UUID_NOT_NULL_MESSAGE = "UUID" + CAN_NOT_BE_NULL;
+
+    public static final String VALUE_LENGTH_MESSAGE = LENGTH_PREFIX + "value" + LENGTH_SUFFIX;
+
+    public static final String VERSION_NOT_NULL_MESSAGE = "Version" + CAN_NOT_BE_NULL;
+
+    public static final String VOCABULARY_NOT_NULL_MESSAGE = "Vocabulary" + CAN_NOT_BE_NULL;
+
+    public static final String PROJECT_NOT_NULL_MESSAGE = "Project" + CAN_NOT_BE_NULL;
+
+    private ValidationMessages()
+    {
+        // Can not be instantiated.
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
new file mode 100644
index 00000000000..97f6d55b670
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.Transient;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing controlled vocabulary.
+ * 
+ * @author Tomasz Pylak
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.CONTROLLED_VOCABULARY_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.IS_INTERNAL_NAMESPACE,
+                ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public class VocabularyPE extends HibernateAbstractRegistratrationHolder implements
+        IIdAndCodeHolder, Comparable<VocabularyPE>, Serializable
+{
+
+    public final static VocabularyPE[] EMPTY_ARRAY = new VocabularyPE[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private transient Long id;
+
+    private String simpleCode;
+
+    private String description;
+
+    private List<VocabularyTermPE> terms = VocabularyTermPE.EMPTY_LIST;
+
+    private boolean managedInternally;
+
+    private boolean internalNamespace;
+
+    private DatabaseInstancePE databaseInstance;
+
+    public VocabularyPE()
+    {
+    }
+
+    @Column(name = ColumnNames.CODE_COLUMN)
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    private String getSimpleCode()
+    {
+        return simpleCode;
+    }
+
+    /**
+     * Sets code in 'database format' - without 'user prefix'. To set full code (with user prefix
+     * use {@link #setCode(String)}).
+     */
+    private void setSimpleCode(final String simpleCode)
+    {
+        this.simpleCode = simpleCode;
+    }
+
+    @Column(name = ColumnNames.DESCRIPTION_COLUMN)
+    @Length(max = 80, message = ValidationMessages.DESCRIPTION_LENGTH_MESSAGE)
+    public String getDescription()
+    {
+        return description;
+    }
+
+    public void setDescription(final String descriptionOrNull)
+    {
+        this.description = descriptionOrNull;
+    }
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    @NotNull(message = ValidationMessages.DATABASE_INSTANCE_NOT_NULL_MESSAGE)
+    @JoinColumn(name = ColumnNames.DATABASE_INSTANCE_COLUMN, updatable = false)
+    public DatabaseInstancePE getDatabaseInstance()
+    {
+        return databaseInstance;
+    }
+
+    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
+    {
+        this.databaseInstance = databaseInstance;
+    }
+
+    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "vocabulary")
+    public List<VocabularyTermPE> getTerms()
+    {
+        return terms;
+    }
+
+    @SequenceGenerator(name = SequenceNames.CONTROLLED_VOCABULARY_SEQUENCE, sequenceName = SequenceNames.CONTROLLED_VOCABULARY_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.CONTROLLED_VOCABULARY_SEQUENCE)
+    public final Long getId()
+    {
+        return id;
+    }
+
+    public void setTerms(final List<VocabularyTermPE> terms)
+    {
+        for (final VocabularyTermPE term : terms)
+        {
+            term.setVocabulary(this);
+        }
+        this.terms = terms;
+    }
+
+    @Column(name = ColumnNames.IS_MANAGED_INTERNALLY, nullable = false)
+    public boolean isManagedInternally()
+    {
+        return managedInternally;
+    }
+
+    public void setManagedInternally(final boolean managedInternally)
+    {
+        this.managedInternally = managedInternally;
+    }
+
+    @Column(name = ColumnNames.IS_INTERNAL_NAMESPACE, nullable = false)
+    public boolean isInternalNamespace()
+    {
+        return internalNamespace;
+    }
+
+    public void setInternalNamespace(final boolean internalNamespace)
+    {
+        this.internalNamespace = internalNamespace;
+    }
+
+    public void setId(final long id)
+    {
+        this.id = id;
+
+    }
+
+    public void setCode(final String fullCode)
+    {
+        setInternalNamespace(CodeConverter.isInternalNamespace(fullCode));
+        setSimpleCode(CodeConverter.tryToDatabase(fullCode));
+    }
+
+    @Transient
+    public String getCode()
+    {
+        return CodeConverter.tryToBusinessLayer(getSimpleCode(), isInternalNamespace() == false);
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof VocabularyPE == false)
+        {
+            return false;
+        }
+        final VocabularyPE that = (VocabularyPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("simpleCode", getSimpleCode());
+        builder.append("internalNamespace", isInternalNamespace());
+        builder.append("managedInternally", isManagedInternally());
+        return builder.toString();
+    }
+
+    //
+    // Comparable
+    //
+
+    public final int compareTo(final VocabularyPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyTermPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyTermPE.java
new file mode 100644
index 00000000000..0139df65fea
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyTermPE.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.validator.Length;
+import org.hibernate.validator.NotNull;
+import org.hibernate.validator.Pattern;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing vocabulary term.
+ * 
+ * @author Tomasz Pylak
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.CONTROLLED_VOCABULARY_TERM_TABLE, uniqueConstraints =
+    { @UniqueConstraint(columnNames =
+        { ColumnNames.CODE_COLUMN, ColumnNames.CONTROLLED_VOCABULARY_COLUMN }) })
+public class VocabularyTermPE extends HibernateAbstractRegistratrationHolder implements
+        IIdAndCodeHolder, Comparable<VocabularyTermPE>, Serializable
+{
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final List<VocabularyTermPE> EMPTY_LIST = Collections.emptyList();
+
+    public static final VocabularyTermPE[] EMPTY_ARRAY = new VocabularyTermPE[0];
+
+    private transient Long id;
+
+    private String code;
+
+    private VocabularyPE vocabulary;
+
+    public VocabularyTermPE()
+    {
+    }
+
+    @NotNull(message = ValidationMessages.CODE_NOT_NULL_MESSAGE)
+    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+    @Pattern(regex = AbstractIdAndCodeHolder.CODE_PATTERN, flags = java.util.regex.Pattern.CASE_INSENSITIVE, message = ValidationMessages.CODE_PATTERN_MESSAGE)
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(final String code)
+    {
+        this.code = CodeConverter.tryToDatabase(code);
+    }
+
+    public void setId(final long id)
+    {
+        this.id = id;
+
+    }
+
+    @SequenceGenerator(name = SequenceNames.CONTROLLED_VOCABULARY_TERM_SEQUENCE, sequenceName = SequenceNames.CONTROLLED_VOCABULARY_TERM_SEQUENCE, allocationSize = 1)
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.CONTROLLED_VOCABULARY_TERM_SEQUENCE)
+    public Long getId()
+    {
+        return id;
+    }
+
+    @NotNull(message = ValidationMessages.VOCABULARY_NOT_NULL_MESSAGE)
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = ColumnNames.CONTROLLED_VOCABULARY_COLUMN, updatable = false)
+    public VocabularyPE getVocabulary()
+    {
+        return vocabulary;
+    }
+
+    public void setVocabulary(final VocabularyPE vocabulary)
+    {
+        this.vocabulary = vocabulary;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof VocabularyTermPE == false)
+        {
+            return false;
+        }
+        final VocabularyTermPE that = (VocabularyTermPE) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getCode(), that.getCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public final String toString()
+    {
+        final ToStringBuilder builder =
+                new ToStringBuilder(this,
+                        ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+        builder.append("code", getCode());
+        return builder.toString();
+    }
+
+    //
+    // Comparable
+    //
+
+    public final int compareTo(final VocabularyTermPE o)
+    {
+        return AbstractIdAndCodeHolder.compare(this, o);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedGroupException.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedGroupException.java
new file mode 100644
index 00000000000..0f4f210f89e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/exception/UndefinedGroupException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.exception;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * This <code>UserFailureException</code> extension signals that no group has been specified.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class UndefinedGroupException extends UserFailureException
+{
+    private static final long serialVersionUID = 1L;
+
+    private final static String MESSAGE = "Group not specified, home group unknown";
+
+    public UndefinedGroupException()
+    {
+        super(MESSAGE);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/Location.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/Location.java
new file mode 100644
index 00000000000..3037e5a93ed
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/Location.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.hibernate;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.hibernate.validator.ValidatorClass;
+
+/**
+ * The string has to be a location
+ * 
+ * @author Christian Ribeaud
+ */
+@Target(
+    { METHOD, FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@ValidatorClass(LocationValidator.class)
+public @interface Location
+{
+
+    /**
+     * Whether given location must be relative or not. Default is <code>true</code>.
+     */
+    boolean relative() default true;
+
+    String message() default "{validator.location}";
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/LocationValidator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/LocationValidator.java
new file mode 100644
index 00000000000..232205c4b37
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/hibernate/LocationValidator.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.hibernate;
+
+import java.io.Serializable;
+
+import org.apache.commons.io.FilenameUtils;
+import org.hibernate.validator.Validator;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Check a specified location.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class LocationValidator implements Validator<Location>, Serializable
+{
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private boolean relative;
+
+    //
+    // Validator
+    //
+
+    public final void initialize(final Location location)
+    {
+        relative = location.relative();
+    }
+
+    public final boolean isValid(final Object value)
+    {
+        final String location = (String) value;
+        final int prefixLength = FilenameUtils.getPrefixLength(location);
+        if (relative)
+        {
+            return prefixLength == 0;
+        } else
+        {
+            return prefixLength > 0;
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifier.java
new file mode 100644
index 00000000000..10f0205b262
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifier.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.common.utilities.StringUtilities;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Uniquely identifies a database instance.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DatabaseInstanceIdentifier implements Serializable
+{
+    public final static class Constants
+    {
+        public static final char IDENTIFIER_SEPARATOR = '/';
+
+        public static final char DATABASE_INSTANCE_SEPARATOR = ':';
+    }
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /** see {@link #getDatabaseInstanceCode()} documentation */
+    private String databaseInstanceCode;
+
+    public static final String HOME = null;
+
+    public static DatabaseInstanceIdentifier createHome()
+    {
+        return new DatabaseInstanceIdentifier(HOME);
+    }
+
+    public DatabaseInstanceIdentifier(final String databaseInstanceCode)
+    {
+        this.databaseInstanceCode = databaseInstanceCode;
+    }
+
+    /**
+     * Usually you should not access database instance code directly. Look for appropriate helpers.
+     * 
+     * @return local or <i>UUID</i> of the database instance. It is treated as <i>UUID</i> if it
+     *         has a canonical UUID format.
+     */
+    public final String getDatabaseInstanceCode()
+    {
+        return StringUtils.upperCase(databaseInstanceCode);
+    }
+
+    public final void setDatabaseInstanceCode(final String databaseInstanceCode)
+    {
+        this.databaseInstanceCode = databaseInstanceCode;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof DatabaseInstanceIdentifier == false)
+        {
+            return false;
+        }
+        final DatabaseInstanceIdentifier that = (DatabaseInstanceIdentifier) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getDatabaseInstanceCode(), that.getDatabaseInstanceCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getDatabaseInstanceCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        if (databaseInstanceCode == null)
+        {
+            return "";
+        } else
+        {
+            return databaseInstanceCode;
+        }
+    }
+
+    public boolean isHomeDatabase()
+    {
+        return databaseInstanceCode == null;
+    }
+
+    /** Do not use this method. It exists just to make automatic bean conversion possible */
+    @Deprecated
+    public void setHomeDatabase(boolean isHomeDatabase)
+    {
+        // empty
+    }
+
+    /** Do not use this constructor. It exists just to make automatic bean conversion possible */
+    @Deprecated
+    public DatabaseInstanceIdentifier()
+    {
+    }
+
+    public int compareTo(DatabaseInstanceIdentifier other)
+    {
+        return StringUtilities.compareNullable(databaseInstanceCode, other
+                .getDatabaseInstanceCode());
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifier.java
new file mode 100644
index 00000000000..28b54034a85
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifier.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifies an experiment.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class ExperimentIdentifier extends ProjectIdentifier
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    final static String CODE_SEPARATOR = "/";
+
+    private String experimentCode;
+
+    public ExperimentIdentifier()
+    {
+        this(null, null, null, null);
+    }
+    
+    public ExperimentIdentifier(final ProjectIdentifier projectIdentifier, final String experimentCode)
+    {
+        this(projectIdentifier.getDatabaseInstanceCode(), projectIdentifier.getGroupCode(),
+                projectIdentifier.getProjectCode(), experimentCode);
+    }
+
+    public ExperimentIdentifier(final String projectCode, final String experimentCode)
+    {
+        this(DatabaseInstanceIdentifier.HOME, GroupIdentifier.HOME_GROUP, projectCode,
+                experimentCode);
+    }
+
+    public ExperimentIdentifier(final String databaseInstanceCode, final String groupCode,
+            final String projectCode, final String experimentCode)
+    {
+        super(databaseInstanceCode, groupCode, projectCode);
+        setExperimentCode(experimentCode);
+    }
+
+    public String getExperimentCode()
+    {
+        return StringUtils.upperCase(experimentCode);
+    }
+
+    public void setExperimentCode(final String experimentCode)
+    {
+        this.experimentCode = experimentCode;
+    }
+
+    /**
+     * Returns an unique description of this object.
+     */
+    public final String describe()
+    {
+        final StringBuilder builder = new StringBuilder();
+        builder.append(getProjectCode());
+        builder.append(CODE_SEPARATOR);
+        builder.append(getExperimentCode());
+        return builder.toString();
+    }
+
+    //
+    // ProjectIdentifier
+    //
+
+    @Override
+    public final String toString()
+    {
+        return super.toString() + Constants.IDENTIFIER_SEPARATOR + experimentCode;
+    }
+
+    @Override
+    public final boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ExperimentIdentifier == false)
+        {
+            return false;
+        }
+        final ExperimentIdentifier that = (ExperimentIdentifier) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getDatabaseInstanceCode(), that.getDatabaseInstanceCode());
+        builder.append(getGroupCode(), that.getGroupCode());
+        builder.append(getProjectCode(), that.getProjectCode());
+        builder.append(getExperimentCode(), that.getExperimentCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public final int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getDatabaseInstanceCode());
+        builder.append(getGroupCode());
+        builder.append(getProjectCode());
+        builder.append(getExperimentCode());
+        return builder.toHashCode();
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifier.java
new file mode 100644
index 00000000000..1a055b98212
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifier.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.common.utilities.StringUtilities;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifies a group.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class GroupIdentifier extends DatabaseInstanceIdentifier
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String groupCodeOrNull;
+
+    public static final String HOME_GROUP = null;
+
+    public static GroupIdentifier createHome()
+    {
+        return new GroupIdentifier(HOME_GROUP, DatabaseInstanceIdentifier.HOME);
+    }
+
+    public GroupIdentifier(final DatabaseInstanceIdentifier databaseInstanceIdentifier,
+            final String groupCode)
+    {
+        this(databaseInstanceIdentifier.getDatabaseInstanceCode(), groupCode);
+    }
+
+    public GroupIdentifier(final String databaseInstanceCode, final String groupCode)
+    {
+        super(databaseInstanceCode);
+        setGroupCode(groupCode);
+    }
+
+    public final String getGroupCode()
+    {
+        return StringUtils.upperCase(groupCodeOrNull);
+    }
+
+    public final void setGroupCode(final String groupCode)
+    {
+        this.groupCodeOrNull = groupCode;
+    }
+
+    //
+    // DatabaseInstanceIdentifier
+    //
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof GroupIdentifier == false)
+        {
+            return false;
+        }
+        final GroupIdentifier that = (GroupIdentifier) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getDatabaseInstanceCode(), that.getDatabaseInstanceCode());
+        builder.append(getGroupCode(), that.getGroupCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getDatabaseInstanceCode());
+        builder.append(getGroupCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        if (getDatabaseInstanceCode() == null)
+        {
+            return Constants.IDENTIFIER_SEPARATOR + groupCodeOrNull;
+        } else
+        {
+            return super.toString() + Constants.DATABASE_INSTANCE_SEPARATOR
+                    + Constants.IDENTIFIER_SEPARATOR + groupCodeOrNull;
+        }
+    }
+
+    public boolean isHomeGroup()
+    {
+        return groupCodeOrNull == null;
+    }
+
+    /** Do not use this constructor. It exists just to make automatic bean conversion possible */
+    @Deprecated
+    public GroupIdentifier()
+    {
+        super();
+    }
+
+    /** this method exists just to make automatic bean conversion possible */
+    @Deprecated
+    public void setHomeGroup(boolean isHomeGroup)
+    {
+        // empty
+    }
+
+    public int compareTo(GroupIdentifier other)
+    {
+        int dbCompare = super.compareTo(other);
+        if (dbCompare == 0)
+        {
+            return StringUtilities.compareNullable(getGroupCode(), other.getGroupCode());
+        } else
+        {
+            return dbCompare;
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
new file mode 100644
index 00000000000..d8e46c1ac4b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/IdentifierHelper.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+
+/**
+ * Some useful methods around identifiers.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class IdentifierHelper
+{
+
+    private IdentifierHelper()
+    {
+        // Can not be instantiated.
+    }
+
+    /**
+     * Creates a {@link GroupIdentifier} from given <var>groupPE</var>.
+     */
+    public final static GroupIdentifier createIdentifier(final GroupPE groupPE)
+    {
+        assert groupPE != null : "Unspecified group";
+        assert groupPE.getDatabaseInstance() != null : "Any group must "
+                + "be attached to a database instance";
+        return new GroupIdentifier(groupPE.getDatabaseInstance().getCode(), groupPE.getCode());
+    }
+
+    /**
+     * Creates a {@link GroupIdentifier} from given <var>groupPE</var>.
+     */
+    public final static DatabaseInstanceIdentifier createIdentifier(
+            final DatabaseInstancePE databaseInstancePE)
+    {
+        assert databaseInstancePE != null : "Unspecified database instance";
+        return new DatabaseInstanceIdentifier(databaseInstancePE.getCode());
+    }
+
+    /**
+     * Creates a {@link SampleIdentifier} from given <var>samplePE</var>.
+     */
+    public final static SampleIdentifier createIdentifier(final SamplePE samplePE)
+    {
+        assert samplePE != null : "Unspecified sample";
+        final DatabaseInstancePE databaseInstance = samplePE.getDatabaseInstance();
+        final GroupPE group = samplePE.getGroup();
+        final String sampleCode = samplePE.getCode();
+        if (databaseInstance != null)
+        {
+            return new SampleIdentifier(createIdentifier(databaseInstance), sampleCode);
+        } else if (group != null)
+        {
+            return new SampleIdentifier(createIdentifier(group), samplePE.getCode());
+        } else
+        {
+            return SampleIdentifier.createHomeGroup(sampleCode);
+        }
+    }
+
+    /**
+     * Creates a {@link ProjectIdentifier} from given <var>project</var>.
+     */
+    public final static ProjectIdentifier createIdentifier(final ProjectPE project)
+    {
+        assert project != null : "Unspecified project";
+        final GroupPE group = project.getGroup();
+        final DatabaseInstancePE databaseInstance = group.getDatabaseInstance();
+        final ProjectIdentifier identifier =
+                new ProjectIdentifier(databaseInstance.getCode(), group.getCode(), project
+                        .getCode());
+        return identifier;
+    }
+
+    /**
+     * Creates a {@link ExperimentIdentifier} from given <var>experiment</var>.
+     */
+    public final static ExperimentIdentifier createIdentifier(final ExperimentPE experiment)
+    {
+        assert experiment != null : "Unspecified experiment";
+        final ExperimentIdentifier experimentIdentifier =
+                new ExperimentIdentifier(createIdentifier(experiment.getProject()), experiment
+                        .getCode());
+        return experimentIdentifier;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/MaterialIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/MaterialIdentifier.java
new file mode 100644
index 00000000000..af69d5e3a99
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/MaterialIdentifier.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifier for searching material through <i>Web Service</i> lookup methods in the database.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class MaterialIdentifier extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    /**
+     * The material code of this material: together with typeCode uniquely identifies the material.
+     * <p>
+     * Could not be <code>null</code>.
+     * </p>
+     */
+    private String code;
+
+    /**
+     * The code of material type of this material: together with code uniquely identifies the
+     * material.
+     * <p>
+     * Could not be <code>null</code>.
+     * </p>
+     */
+    private String typeCode;
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    public final void setCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public String getTypeCode()
+    {
+        return typeCode;
+    }
+
+    public void setTypeCode(final String typeCode)
+    {
+        this.typeCode = typeCode;
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifier.java
new file mode 100644
index 00000000000..47f3a07d95f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifier.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifies a project.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class ProjectIdentifier extends GroupIdentifier
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private String projectCode;
+
+    public ProjectIdentifier(final String instanceCode, final String groupCode,
+            final String projectCode)
+    {
+        super(instanceCode, groupCode);
+        setProjectCode(projectCode);
+    }
+
+    public ProjectIdentifier(final String groupCode, final String projectCode)
+    {
+        this(null, groupCode, projectCode);
+    }
+
+    public String getProjectCode()
+    {
+        return StringUtils.upperCase(projectCode);
+    }
+
+    public void setProjectCode(final String projectCode)
+    {
+        this.projectCode = projectCode;
+    }
+
+    //
+    // GroupIdentifier
+    //
+
+    @Override
+    public boolean equals(final Object obj)
+    {
+        if (obj == this)
+        {
+            return true;
+        }
+        if (obj instanceof ProjectIdentifier == false)
+        {
+            return false;
+        }
+        final ProjectIdentifier that = (ProjectIdentifier) obj;
+        final EqualsBuilder builder = new EqualsBuilder();
+        builder.append(getDatabaseInstanceCode(), that.getDatabaseInstanceCode());
+        builder.append(getGroupCode(), that.getGroupCode());
+        builder.append(getProjectCode(), that.getProjectCode());
+        return builder.isEquals();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final HashCodeBuilder builder = new HashCodeBuilder();
+        builder.append(getDatabaseInstanceCode());
+        builder.append(getGroupCode());
+        builder.append(getProjectCode());
+        return builder.toHashCode();
+    }
+
+    @Override
+    public String toString()
+    {
+        if (getGroupCode() == null)
+        {
+            return projectCode;
+        } else
+        {
+            return super.toString() + Constants.IDENTIFIER_SEPARATOR + projectCode;
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
new file mode 100644
index 00000000000..5d0e27a7f7d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifier.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import ch.systemsx.cisd.common.exceptions.InternalErr;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifies a sample.
+ * 
+ * @author Izabela Adamczyk
+ * @author Tomasz Pylak
+ */
+public class SampleIdentifier extends SampleOwnerIdentifier implements Comparable<SampleIdentifier>
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    public static final SampleIdentifier[] EMPTY_ARRAY = new SampleIdentifier[0];
+
+    private String sampleCode;
+
+    private SampleIdentifier(final DatabaseInstanceIdentifier databaseInstanceIdentOrNull,
+            final GroupIdentifier groupIdentOrNull, final String sampleCode)
+    {
+        super(databaseInstanceIdentOrNull, groupIdentOrNull);
+        this.sampleCode = sampleCode;
+    }
+
+    public static SampleIdentifier createOwnedBy(final SampleOwnerIdentifier owner,
+            final String sampleCode)
+    {
+        if (owner.isDatabaseInstanceLevel())
+        {
+            return new SampleIdentifier(owner.getDatabaseInstanceLevel(), sampleCode);
+        } else if (owner.isGroupLevel())
+        {
+            return new SampleIdentifier(owner.getGroupLevel(), sampleCode);
+        } else
+        {
+            throw InternalErr.error();
+        }
+    }
+
+    /** Database-instance level {@link SampleIdentifier}. */
+    public SampleIdentifier(final DatabaseInstanceIdentifier instanceIdentifier,
+            final String sampleCode)
+    {
+        this(instanceIdentifier, null, sampleCode);
+    }
+
+    /** Group level {@link SampleIdentifier}. */
+    public SampleIdentifier(final GroupIdentifier groupIdentifier, final String sampleCode)
+    {
+        this(null, groupIdentifier, sampleCode);
+    }
+
+    /** Home group level {@link SampleIdentifier} with type. */
+    public static SampleIdentifier createHomeGroup(final String sampleCode)
+    {
+        return new SampleIdentifier(GroupIdentifier.createHome(), sampleCode);
+    }
+
+    public String getSampleCode()
+    {
+        return sampleCode;
+    }
+
+    @Override
+    public String toString()
+    {
+        return super.toString() + sampleCode;
+    }
+
+    @Deprecated
+    public void setSampleCode(final String sampleCode)
+    {
+        this.sampleCode = sampleCode;
+    }
+
+    // for bean conversion only!
+    @Deprecated
+    public SampleIdentifier()
+    {
+        super(null, null);
+    }
+
+    //
+    // Comparable
+    //
+
+    public int compareTo(final SampleIdentifier o)
+    {
+        final int ownerCmp = super.compareTo(o);
+        if (ownerCmp == 0)
+        {
+            return sampleCode.compareTo(o.sampleCode);
+        } else
+        {
+            return ownerCmp;
+        }
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierPattern.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierPattern.java
new file mode 100644
index 00000000000..b14322ec906
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierPattern.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Identifies a group of samples on the same level (in certain group or on database level)
+ * 
+ * @author Tomasz Pylak
+ */
+public class SampleIdentifierPattern extends AbstractHashable implements Serializable
+{
+    public final static SampleIdentifierPattern[] EMPTY_ARRAY = new SampleIdentifierPattern[0];
+
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    private final SampleOwnerIdentifier owner;
+
+    private final String sampleCodePattern;
+
+    /**
+     * Matches samples from the specified group and the database instance to which this group
+     * belongs. Only samples with the code matching sampleCodePattern will be selected.
+     */
+    public static SampleIdentifierPattern[] createGroupVisible(GroupIdentifier groupIdentifier,
+            String sampleCodePattern)
+    {
+        SampleOwnerIdentifier groupOwner = new SampleOwnerIdentifier(groupIdentifier);
+        SampleIdentifierPattern groupPattern =
+                new SampleIdentifierPattern(sampleCodePattern, groupOwner);
+
+        SampleOwnerIdentifier dbOwner =
+                new SampleOwnerIdentifier((DatabaseInstanceIdentifier) groupIdentifier);
+        SampleIdentifierPattern dbPattern = new SampleIdentifierPattern(sampleCodePattern, dbOwner);
+
+        return new SampleIdentifierPattern[]
+            { groupPattern, dbPattern };
+    }
+
+    /**
+     * Matches samples owned by the specified owner. Only samples with the code matching
+     * sampleCodePattern will be selected.
+     */
+    public static SampleIdentifierPattern createOwnedBy(SampleOwnerIdentifier owner,
+            String sampleCodePattern)
+    {
+        return new SampleIdentifierPattern(sampleCodePattern, owner);
+    }
+
+    private SampleIdentifierPattern(String sampleCodePattern, SampleOwnerIdentifier owner)
+    {
+        this.owner = owner;
+        this.sampleCodePattern = sampleCodePattern;
+    }
+
+    public SampleOwnerIdentifier getSampleOwner()
+    {
+        return owner;
+    }
+
+    public String getSampleCodePattern()
+    {
+        return sampleCodePattern;
+    }
+
+    @Override
+    public String toString()
+    {
+        return owner.toString() + sampleCodePattern;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
new file mode 100644
index 00000000000..26ab745b2c2
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleOwnerIdentifier.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import java.io.Serializable;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier.Constants;
+
+/**
+ * Identifies an owner of a sample: group or database instance.
+ * 
+ * @author Tomasz Pylak
+ */
+public class SampleOwnerIdentifier extends AbstractHashable implements Serializable
+{
+    private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+    // if not null, sample is defined on the group level
+    private GroupIdentifier groupIdentOrNull;
+
+    // if not null, sample is defined on the database instance level
+    private DatabaseInstanceIdentifier databaseInstanceIdentOrNull;
+
+    protected SampleOwnerIdentifier(final DatabaseInstanceIdentifier databaseInstanceIdentOrNull,
+            final GroupIdentifier groupIdentOrNull)
+    {
+        this.databaseInstanceIdentOrNull = databaseInstanceIdentOrNull;
+        this.groupIdentOrNull = groupIdentOrNull;
+    }
+
+    /** Database-instance level {@link SampleOwnerIdentifier}. */
+    public SampleOwnerIdentifier(final DatabaseInstanceIdentifier instanceIdentifier)
+    {
+        this(checkNotNull(instanceIdentifier), null);
+    }
+
+    private static DatabaseInstanceIdentifier checkNotNull(DatabaseInstanceIdentifier identifier)
+    {
+        assert identifier != null : "database identifier cannot be null";
+        return identifier;
+    }
+
+    /** Group level {@link SampleOwnerIdentifier}. */
+    public SampleOwnerIdentifier(final GroupIdentifier groupIdentifier)
+    {
+        this(null, checkNotNull(groupIdentifier));
+    }
+
+    private static GroupIdentifier checkNotNull(GroupIdentifier identifier)
+    {
+        assert identifier != null : "group identifier cannot be null";
+        return identifier;
+    }
+
+    /** @return if sample is connected to its home group */
+    public boolean isInsideHomeGroup()
+    {
+        return isGroupLevel() && groupIdentOrNull.isHomeGroup();
+    }
+
+    /**
+     * true if sample belongs to the group. {@link #isDatabaseInstanceLevel()} will return false in
+     * such a case.
+     */
+    public boolean isGroupLevel()
+    {
+        return groupIdentOrNull != null;
+    }
+
+    /**
+     * true if sample belongs to the database instance. {@link #isGroupLevel()} will return false in
+     * such a case.
+     */
+    public boolean isDatabaseInstanceLevel()
+    {
+        return databaseInstanceIdentOrNull != null;
+    }
+
+    @Override
+    public String toString()
+    {
+        if (isGroupLevel())
+        {
+            if (isInsideHomeGroup())
+            {
+                return "";
+            } else
+            {
+                return groupIdentOrNull.toString() + Constants.IDENTIFIER_SEPARATOR;
+            }
+        } else if (isDatabaseInstanceLevel())
+        {
+            if (databaseInstanceIdentOrNull.isHomeDatabase())
+            {
+                return "" + Constants.IDENTIFIER_SEPARATOR;
+            } else
+            {
+                return databaseInstanceIdentOrNull.getDatabaseInstanceCode()
+                        + Constants.DATABASE_INSTANCE_SEPARATOR + Constants.IDENTIFIER_SEPARATOR;
+            }
+        } else
+        {
+            throw new IllegalStateException("sample owner is unknown");
+        }
+    }
+
+    /**
+     * It is a good pattern to use {@link #isDatabaseInstanceLevel()} before calling this method.
+     * 
+     * @return The database instance which is the owner or null if the owner is not a database
+     *         instance but a group.
+     */
+    public DatabaseInstanceIdentifier getDatabaseInstanceLevel()
+    {
+        return databaseInstanceIdentOrNull;
+    }
+
+    /**
+     * It is a good pattern to use {@link #isGroupLevel()} before calling this method.
+     * 
+     * @return The group which is the owner or null if the owner is not a group, but database
+     *         instance.
+     */
+    public GroupIdentifier getGroupLevel()
+    {
+        return groupIdentOrNull;
+    }
+
+    // for bean conversion only!
+    @Deprecated
+    public void setGroupLevel(GroupIdentifier groupIdentOrNull)
+    {
+        this.groupIdentOrNull = groupIdentOrNull;
+    }
+
+    // for bean conversion only!
+    @Deprecated
+    public void setDatabaseInstanceLevel(DatabaseInstanceIdentifier databaseInstanceIdentOrNull)
+    {
+        this.databaseInstanceIdentOrNull = databaseInstanceIdentOrNull;
+    }
+    
+    public int compareTo(SampleOwnerIdentifier other)
+    {
+        if (isGroupLevel())
+        {
+            if (other.isGroupLevel())
+            {
+                return getGroupLevel().compareTo(other.getGroupLevel());
+            } else
+            {
+                return 1;
+            }
+        } else if (isDatabaseInstanceLevel())
+        {
+            if (other.isGroupLevel())
+            {
+                return -1;
+            } else
+            {
+                return getDatabaseInstanceLevel().compareTo(other.getDatabaseInstanceLevel());
+            }
+        } else
+            throw new IllegalStateException("sample owner is unknown");
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityDataType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityDataType.java
new file mode 100644
index 00000000000..9bce0957a85
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityDataType.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+import java.io.Serializable;
+
+/**
+ * Available types of entity properties in the database.
+ * 
+ * @author Tomasz Pylak
+ */
+public enum EntityDataType implements Serializable
+{
+    INTEGER("INT"), VARCHAR("STRING"), REAL("DOUBLE"), TIMESTAMP("DATE"), BOOLEAN("BOOLEAN"),
+    CONTROLLEDVOCABULARY("VOCABULARY");
+
+    private final String niceRepresentation;
+
+    private EntityDataType(final String niceRepresentation)
+    {
+        this.niceRepresentation = niceRepresentation;
+    }
+
+    /**
+     * Returns a nice representation of this enumeration item.
+     */
+    public final String getNiceRepresentation()
+    {
+        return niceRepresentation;
+    }
+
+    //
+    // Object
+    //
+
+    @Override
+    public final String toString()
+    {
+        return getNiceRepresentation();
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityKind.java
new file mode 100644
index 00000000000..cc46d50bb19
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityKind.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+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.ExperimentPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePropertyTypePE;
+
+/**
+ * Enumeration of entity kinds.
+ * 
+ * @author Franz-Josef Elmer
+ */
+public enum EntityKind
+{
+    MATERIAL("material", MaterialTypePE.class, MaterialTypePropertyTypePE.class,
+            MaterialPropertyPE.class),
+
+    EXPERIMENT("experiment", ExperimentTypePE.class, ExperimentTypePropertyTypePE.class,
+            ExperimentPropertyPE.class),
+
+    SAMPLE("sample", SampleTypePE.class, SampleTypePropertyTypePE.class, SamplePropertyPE.class);
+
+    private final String entityLabel;
+
+    private transient final Class<?> typeClass;
+
+    private transient final Class<?> assignmentClass;
+
+    private transient final Class<?> propertyClass;
+
+    private EntityKind(final String entityLabel, final Class<?> typeClass,
+            final Class<?> assignmentClass, Class<?> propertyClass)
+    {
+        this.entityLabel = entityLabel;
+        this.typeClass = typeClass;
+        this.assignmentClass = assignmentClass;
+        this.propertyClass = propertyClass;
+    }
+
+    @SuppressWarnings("unchecked")
+    private final static <T> Class<T> cast(final Class<?> clazz)
+    {
+        return (Class<T>) clazz;
+    }
+
+    public final String getLabel()
+    {
+        return entityLabel;
+    }
+
+    public final <T extends EntityTypePE> Class<T> getTypeClass()
+    {
+        return cast(typeClass);
+    }
+
+    public final <T extends EntityTypePropertyTypePE> Class<T> getEntityTypePropertyTypeAssignmentClass()
+    {
+        return cast(assignmentClass);
+    }
+
+    public <T extends EntityPropertyPE> Class<T> getEntityPropertyClass()
+    {
+        return cast(propertyClass);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityProperties.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityProperties.java
new file mode 100644
index 00000000000..5d919b517fb
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityProperties.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyTypeDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleEntityProperty;
+
+/**
+ * Type property implementation with some extensions used by DAOs.<br>
+ * Note that "orNull" and "try" naming convention is used everywhere.
+ * 
+ * @author Tomasz Pylak
+ */
+public class EntityProperties extends AbstractHashable
+{
+    // TODO 2008-02-16, Tomasz Pylak: this field should be removed, setProperty has to have schema
+    // as parameter.
+    // It will make instance of this class smaller, so we could delete SimpleEntityProperty class
+    // and replace it with this class when axis web-service interface will not be used anymore.
+    private final EntityPropertyTypeDTOContainer propertyTypeContainer;
+
+    private final Map<String, EntityPropertyValue> properties;
+
+    public EntityProperties(final EntityPropertyTypeDTOContainer propertiesSchema)
+    {
+        this.properties = new LinkedHashMap<String, EntityPropertyValue>();
+        this.propertyTypeContainer = propertiesSchema;
+        createInitialProperties();
+    }
+
+    private final void createInitialProperties()
+    {
+        for (final String name : propertyTypeContainer.getAllPropertyCodes())
+        {
+            final EntityPropertyTypeDTO spec = propertyTypeContainer.getPropertyType(name);
+            final EntityPropertyValue value =
+                    EntityPropertyValue.createFromUntyped(null, spec.getDataTypeCode());
+            properties.put(name, value);
+        }
+    }
+
+    public boolean hasProperty(final String name)
+    {
+        return properties.containsKey(name);
+    }
+
+    public final EntityPropertyValue getProperty(final String name) throws IllegalArgumentException
+    {
+        final EntityPropertyValue value = properties.get(name);
+        if (value == null)
+        {
+            throw new IllegalArgumentException("No entity property value for '" + name + "'.");
+        }
+        return value;
+    }
+
+    // checks if value is mandatory and casts it to appropriate type
+    public final void setProperty(final String name, final String untypedValueOrNull)
+    {
+        final EntityPropertyValue value =
+                propertyTypeContainer.validateAndCreateValue(name, untypedValueOrNull);
+        properties.put(name, value);
+    }
+
+    public static EntityProperties createFromSimple(final SimpleEntityProperty[] simpleProperties,
+            final EntityPropertyTypeDTOContainer propertySchema)
+    {
+        if (simpleProperties == null)
+        {
+            return null;
+        }
+        final EntityProperties properties = new EntityProperties(propertySchema);
+        for (int i = 0; i < simpleProperties.length; i++)
+        {
+            final SimpleEntityProperty property = simpleProperties[i];
+            final String name = property.getCode();
+            if (propertySchema.hasPropertySchema(name))
+            {
+                properties.setProperty(name, EntityPropertyValue.createFromSimple(property)
+                        .tryGetUntypedValue());
+            } else
+            {
+                throw new IllegalArgumentException("Unknown property '" + name + "'.");
+            }
+        }
+        return properties;
+    }
+
+    public SimpleEntityProperty[] createSimple()
+    {
+        final List<SimpleEntityProperty> result = new ArrayList<SimpleEntityProperty>();
+        for (final Map.Entry<String, EntityPropertyValue> entry : properties.entrySet())
+        {
+            final String label =
+                    propertyTypeContainer.getPropertyType(entry.getKey()).getPropertyType()
+                            .getLabel();
+            SimpleEntityProperty property = entry.getValue().createSimple(entry.getKey(), label);
+            result.add(property);
+        }
+        return result.toArray(new SimpleEntityProperty[result.size()]);
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyTypeDTOContainer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyTypeDTOContainer.java
new file mode 100644
index 00000000000..b00f37ad8fc
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyTypeDTOContainer.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+
+import ch.rinn.restrictions.Private;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyTypeDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+
+/**
+ * Stores a set ({@link Map}) of {@link EntityPropertyTypeDTO}s and provides useful methods.
+ * 
+ * @author Tomasz Pylak
+ */
+public class EntityPropertyTypeDTOContainer extends AbstractHashable
+{
+    /**
+     * Factory method for creating {@link EntityPropertyTypeDTOContainer}s from
+     * {@link EntityPropertyTypeDTO} lists.
+     * 
+     * @param propertyTypes
+     */
+    public static EntityPropertyTypeDTOContainer create(
+            final List<EntityPropertyTypeDTO> propertyTypes)
+    {
+        final EntityPropertyTypeDTOContainer container = new EntityPropertyTypeDTOContainer();
+        for (final EntityPropertyTypeDTO entityPropertyType : propertyTypes)
+        {
+            container.addEntityPropertyType(entityPropertyType);
+        }
+        return container;
+    }
+
+    /**
+     * Factory method for creating {@link EntityPropertyTypeDTOContainer}s from
+     * {@link EntityPropertyTypeDTO} array.
+     * 
+     * @param entityPropertyTypeTable
+     */
+    public static EntityPropertyTypeDTOContainer createFromTable(
+            final EntityPropertyTypeDTO[] entityPropertyTypeTable)
+    {
+        if (entityPropertyTypeTable == null)
+        {
+            return null;
+        }
+        final EntityPropertyTypeDTOContainer schema = new EntityPropertyTypeDTOContainer();
+        for (final EntityPropertyTypeDTO entityPropertyType : entityPropertyTypeTable)
+        {
+            schema.addEntityPropertyType(entityPropertyType);
+        }
+        return schema;
+    }
+
+    private static UserFailureException createMandatoryException(final String name)
+    {
+        return UserFailureException.fromTemplate(
+                "Property '%s' is mandatory and cannot be set to the empty value.", name);
+    }
+
+    private final Map<String, EntityPropertyTypeDTO> container;
+
+    private EntityPropertyTypeDTOContainer()
+    {
+        this.container = new LinkedHashMap<String, EntityPropertyTypeDTO>();
+    }
+
+    /**
+     * Returns an array of {@link EntityPropertyTypeDTO} which typeCodes were stored in container.
+     */
+    public EntityPropertyTypeDTO[] createTable()
+    {
+        final Set<String> allCodes = container.keySet();
+        final EntityPropertyTypeDTO[] result = new EntityPropertyTypeDTO[allCodes.size()];
+        int i = 0;
+        for (final String code : allCodes)
+        {
+            final EntityPropertyTypeDTO orig = getPropertyType(code);
+            result[i] = orig;
+            i++;
+        }
+        return result;
+    }
+
+    /**
+     * Returns an array of propertyTypeCodes stored in the container.
+     */
+    public String[] getAllPropertyCodes()
+    {
+        return container.keySet().toArray(new String[0]);
+    }
+
+    /**
+     * Returns {@link EntityPropertyTypeDTO} for given <var>propertyTypeCode</var>.
+     * 
+     * @param propertyTypeCode
+     * @throws UserFailureException if there is no {@link EntityPropertyTypeDTO} with specified
+     *             <var>propertyTypeCode</var>.
+     */
+    public EntityPropertyTypeDTO getPropertyType(final String propertyTypeCode)
+    {
+        final EntityPropertyTypeDTO type = tryGetPropertyType(propertyTypeCode);
+        if (type == null)
+        {
+            throw UserFailureException.fromTemplate("Unknown property '%s'", propertyTypeCode);
+        }
+        return type;
+    }
+
+    /**
+     * Returns true if container contains given propertyTypeCode.
+     * 
+     * @param propertyTypeCode
+     */
+    public boolean hasPropertySchema(final String propertyTypeCode)
+    {
+        return container.containsKey(propertyTypeCode);
+    }
+
+    /**
+     * Returns {@link EntityPropertyTypeDTO} or null for given propertyTypeCode.
+     * 
+     * @param propertyTypeCode
+     */
+    public EntityPropertyTypeDTO tryGetPropertyType(final String propertyTypeCode)
+    {
+        return container.get(StringUtils.upperCase(propertyTypeCode));
+    }
+
+    /**
+     * Checks if value is mandatory and casts it to appropriate type.
+     * 
+     * @param propertyTypeCode
+     * @param untypedValueOrNull
+     */
+    public EntityPropertyValue validateAndCreateValue(final String propertyTypeCode,
+            final String untypedValueOrNull)
+    {
+        final String upperCaseCode = StringUtils.upperCase(propertyTypeCode);
+        final EntityPropertyTypeDTO propertyType = getPropertyType(upperCaseCode);
+        assert propertyType != null;
+        if (propertyType.isMandatory() && untypedValueOrNull == null)
+        {
+            throw createMandatoryException(upperCaseCode);
+        }
+        return EntityPropertyValue.createFromUntyped(untypedValueOrNull, propertyType
+                .getDataTypeCode());
+    }
+
+    /**
+     * Adds {@link EntityPropertyTypeDTO} to container.
+     * 
+     * @param entityPropertyType
+     * @throws IllegalArgumentException if property was already present
+     */
+    private void addEntityPropertyType(final EntityPropertyTypeDTO entityPropertyType)
+    {
+        final String propertyTypeCode = entityPropertyType.getPropertyType().getCode();
+        if (container.get(propertyTypeCode) != null)
+        {
+            throw new IllegalArgumentException("property already present: " + propertyTypeCode);
+        }
+        container.put(propertyTypeCode, entityPropertyType);
+    }
+
+    //
+    // Methods introduced for testing purposes
+    //
+
+    /**
+     * <i>Only to be used in unit tests.</i>
+     */
+    public static EntityPropertyTypeDTOContainer only4TestingCreateEmpty()
+    {
+        return new EntityPropertyTypeDTOContainer();
+    }
+
+    /**
+     * <i>Only to be used in unit tests.</i>
+     * <p>
+     * Fails if property was already present.
+     */
+    @Private
+    public EntityPropertyTypeDTO only4TestingAddEntityPropertyType(final long id,
+            final boolean isMandatory, final Date registrationDate, final PersonPE registrator,
+            final PropertyTypePE propertyType)
+    {
+        final EntityPropertyTypeDTO entityPropertyType =
+                new EntityPropertyTypeDTO(id, isMandatory, registrationDate, registrator,
+                        propertyType);
+        addEntityPropertyType(entityPropertyType);
+        return entityPropertyType;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyValue.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyValue.java
new file mode 100644
index 00000000000..3baee030f8c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/EntityPropertyValue.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+import java.io.Serializable;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import ch.systemsx.cisd.common.exceptions.InternalErr;
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import ch.systemsx.cisd.common.utilities.DateFormatThreadLocal;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleEntityProperty;
+
+/**
+ * Storage of entity property value. Use casting methods with tryAs prefix to extract a value. Note
+ * that if a value of a certain type is stored (e.g. integer), than using a casting method different
+ * than tryAsInteger is a programming error! Use {@code getType()} method to figure out the type of
+ * value, which is stored.
+ * 
+ * @author Tomasz Pylak
+ */
+// TODO 2007-11-22, Christian Ribeaud: typed methods 'tryAsDouble', 'tryAsInteger' and 'tryAsString'
+// should be removed as they are only used inside the property type framework.
+public class EntityPropertyValue extends AbstractHashable
+{
+    private static final String TRUE_VALUE = "true";
+
+    private static final String FALSE_VALUE = "false";
+
+    public static final ThreadLocal<SimpleDateFormat> CANONICAL_DATE_FORMAT =
+            new DateFormatThreadLocal("yyyy-MM-dd HH:mm:ss Z");
+
+    private final EntityDataType type;
+
+    private final Object valueOrNull;
+
+    private EntityPropertyValue(final Object valueOrNull, final EntityDataType type)
+    {
+        this.valueOrNull = valueOrNull;
+        this.type = type;
+    }
+
+    /** @return the type of value, which is stored */
+    public EntityDataType getType()
+    {
+        return type;
+    }
+
+    /** @return true if the stored value is null (type independent) */
+    public boolean isNull()
+    {
+        return valueOrNull == null;
+    }
+
+    /** throws exception when value cannot be properly casted */
+    public static EntityPropertyValue createFromUntyped(final String untypedValueOrNull,
+            final EntityDataType type) throws UserFailureException
+    {
+        if (untypedValueOrNull == null)
+        {
+            return new EntityPropertyValue(null, type);
+        }
+        try
+        {
+            return internalCreateFromUntyped(untypedValueOrNull, type);
+        } catch (final NumberFormatException e)
+        {
+            throw UserFailureException.fromTemplate(
+                    "Value '%s' has improper format. It should be of type '%s'",
+                    untypedValueOrNull, type.getNiceRepresentation());
+        }
+    }
+
+    private static EntityPropertyValue internalCreateFromUntyped(final String untypedValue,
+            final EntityDataType type)
+    {
+        if (type.equals(EntityDataType.INTEGER))
+        {
+            return createInteger(Integer.parseInt(untypedValue));
+        } else if (type.equals(EntityDataType.REAL))
+        {
+            return createDouble(Double.parseDouble(untypedValue));
+        } else if (type.equals(EntityDataType.VARCHAR))
+        {
+            return createString(untypedValue);
+        } else if (type.equals(EntityDataType.BOOLEAN))
+        {
+            return createBoolean(parseBoolean(untypedValue));
+        } else if (type.equals(EntityDataType.TIMESTAMP))
+        {
+            return createDate(parseDate(untypedValue));
+        } else if (type.equals(EntityDataType.CONTROLLEDVOCABULARY))
+        {
+            return createVocabularyTerm(untypedValue);
+        } else
+        {
+            throw InternalErr.error();
+        }
+    }
+
+    private static Date parseDate(final String untypedValue)
+    {
+        try
+        {
+            return CANONICAL_DATE_FORMAT.get().parse(untypedValue);
+        } catch (final ParseException ex)
+        {
+            throw UserFailureException.fromTemplate(
+                    "Date value '%s' has improper format. The proper format is '%s'.",
+                    untypedValue, CANONICAL_DATE_FORMAT.get().toPattern());
+        }
+    }
+
+    private static Boolean parseBoolean(final String untypedValue)
+    {
+        if (untypedValue.equalsIgnoreCase(TRUE_VALUE))
+        {
+            return Boolean.TRUE;
+        } else if (untypedValue.equalsIgnoreCase(FALSE_VALUE))
+        {
+            return Boolean.FALSE;
+        } else
+        {
+            throw UserFailureException.fromTemplate(
+                    "Boolean value '%s' has improper format. It should be either '%s' or '%s',",
+                    untypedValue, TRUE_VALUE, FALSE_VALUE);
+        }
+    }
+
+    public static EntityPropertyValue createInteger(final Integer valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.INTEGER);
+    }
+
+    public static EntityPropertyValue createDouble(final Double valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.REAL);
+    }
+
+    public static EntityPropertyValue createString(final String valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.VARCHAR);
+    }
+
+    public static EntityPropertyValue createVocabularyTerm(final String valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.CONTROLLEDVOCABULARY);
+    }
+
+    public static EntityPropertyValue createBoolean(final Boolean valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.BOOLEAN);
+    }
+
+    public static EntityPropertyValue createDate(final Date valOrNull)
+    {
+        return new EntityPropertyValue(valOrNull, EntityDataType.TIMESTAMP);
+    }
+
+    // --- casting methods, fail if type does not match
+
+    public String tryAsString()
+    {
+        ensure(type.equals(EntityDataType.VARCHAR));
+        return (String) valueOrNull;
+    }
+
+    public Integer tryAsInteger()
+    {
+        ensure(type.equals(EntityDataType.INTEGER));
+        return (Integer) valueOrNull;
+    }
+
+    public Double tryAsDouble()
+    {
+        ensure(type.equals(EntityDataType.REAL));
+        return (Double) valueOrNull;
+    }
+
+    public Boolean tryAsBoolean()
+    {
+        ensure(type.equals(EntityDataType.BOOLEAN));
+        return (Boolean) valueOrNull;
+    }
+
+    public Date tryAsDate()
+    {
+        ensure(type.equals(EntityDataType.TIMESTAMP));
+        return (Date) valueOrNull;
+    }
+
+    /** returns canonical representation of the value */
+    public String tryGetUntypedValue()
+    {
+        if (valueOrNull == null)
+        {
+            return null;
+        }
+        if (type.equals(EntityDataType.INTEGER) || type.equals(EntityDataType.REAL)
+                || type.equals(EntityDataType.VARCHAR)
+                || type.equals(EntityDataType.CONTROLLEDVOCABULARY))
+        {
+            return valueOrNull.toString();
+        } else if (type.equals(EntityDataType.BOOLEAN))
+        {
+            return tryAsBoolean() ? TRUE_VALUE : FALSE_VALUE;
+        } else if (type.equals(EntityDataType.TIMESTAMP))
+        {
+            return CANONICAL_DATE_FORMAT.get().format(tryAsDate());
+        } else
+        {
+            throw InternalErr.error();
+        }
+    }
+
+    private void ensure(final boolean value)
+    {
+        assert value : "Type does not match";
+    }
+
+    public SimpleEntityProperty createSimple(final String code, final String label)
+    {
+        return new SimpleEntityProperty(code, label, type, (Serializable) this.valueOrNull);
+    }
+
+    public static EntityPropertyValue createFromSimple(SimpleEntityProperty property)
+    {
+        return new EntityPropertyValue(property.getValue(), property.getDataType());
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/PropertiesHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/PropertiesHelper.java
new file mode 100644
index 00000000000..2b96970699c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/properties/PropertiesHelper.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import ch.systemsx.cisd.common.collections.ListSet;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ISimpleEntityPropertiesHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+
+/**
+ * A static helper class which contains helpful methods around {@link PropertyTypePE},
+ * {@link ISimpleEntityPropertiesHolder}.
+ * 
+ * @author Tomasz Pylak
+ */
+public final class PropertiesHelper
+{
+
+    private PropertiesHelper()
+    {
+        // Can not be instantiated.
+    }
+
+    /**
+     * Returns a description of given <var>propertyType</var>.
+     */
+    public static final String getTypeDescription(final PropertyTypePE propertyType)
+    {
+        assert propertyType != null : "Unspecified property type";
+        final DataTypePE dataType = propertyType.getType();
+        String type = dataType != null ? dataType.getCode().name() : getSimpleType(propertyType);
+        final String vocabularyCode = getVocabularyCode(propertyType);
+        if (vocabularyCode != null)
+        {
+            type = type + "(" + vocabularyCode + ")";
+        }
+        return type;
+    }
+
+    public static final String getSimpleType(final PropertyTypePE propertyType)
+    {
+        return propertyType.getType() == null ? null : propertyType.getType().getCode().name();
+    }
+
+    public static String getVocabularyCode(final PropertyTypePE propertyType)
+    {
+        final VocabularyPE vocabulary = propertyType.getVocabulary();
+        if (vocabulary == null || StringUtils.isEmpty(vocabulary.getCode()))
+        {
+            return null;
+        } else
+        {
+            return vocabulary.getCode();
+        }
+    }
+
+    public final static <T extends EntityPropertyPE> ListSet createPropertiesListSet(
+            final IEntityPropertiesHolder<T>[] entities)
+    {
+        final ListSet table = new ListSet();
+        for (int rowIndex = 0; rowIndex < entities.length; rowIndex++)
+        {
+            final List<T> properties = entities[rowIndex].getProperties();
+            assert properties != null : "Unspecified properties";
+            for (final EntityPropertyPE property : properties)
+            {
+                final PropertyTypePE propertyType =
+                        property.getEntityTypePropertyType().getPropertyType();
+                table.addToList(propertyType.getCode(), propertyType.getLabel(), property
+                        .tryGetUntypedValue(), rowIndex);
+            }
+        }
+        return table;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/DataSetTypeCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/DataSetTypeCode.java
new file mode 100644
index 00000000000..58e56881ae4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/DataSetTypeCode.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.types;
+
+/**
+ * The current <code>DataSetType</code> codes.
+ * <p>
+ * This enumeration should reflect the values in the database and is <i>Unit</i> tested to ensure
+ * this point.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public enum DataSetTypeCode
+{
+    HCS_IMAGE("HCS_IMAGE"), HCS_IMAGE_ANALYSIS_DATA("HCS_IMAGE_ANALYSIS_DATA"), UNKNOWN("UNKNOWN");
+
+    private final String code;
+
+    private DataSetTypeCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    /** For given <var>typeCode</var> returns the corresponding <code>DataSetTypeCode</code>. */
+    public final static DataSetTypeCode getDataSetTypeCode(final String typeCode)
+    {
+        assert typeCode != null : "Unspecified data set type code.";
+        for (final DataSetTypeCode dataSetTypeCode : values())
+        {
+            if (dataSetTypeCode.code.equalsIgnoreCase(typeCode))
+            {
+                return dataSetTypeCode;
+            }
+        }
+        throw new IllegalArgumentException(String.format("No data set type for given code '%s'.",
+                typeCode));
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ExperimentTypeCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ExperimentTypeCode.java
new file mode 100644
index 00000000000..1bd6015c4b4
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ExperimentTypeCode.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.types;
+
+/**
+ * The current <code>ExperimentType</code> codes.
+ * <p>
+ * This enumeration should reflect the values in the database and is <i>Unit</i> tested to ensure
+ * this point.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public enum ExperimentTypeCode
+{
+    SIRNA_HCS("SIRNA_HCS"), COMPOUND_HCS("COMPOUND_HCS");
+
+    private final String code;
+
+    private ExperimentTypeCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    /** For given <var>typeCode</var> returns the corresponding <code>ExperimentTypeCode</code>. */
+    public final static ExperimentTypeCode getExperimentTypeCode(final String typeCode)
+    {
+        assert typeCode != null : "Unspecified experiment type code.";
+        for (final ExperimentTypeCode experimentTypeCode : values())
+        {
+            if (experimentTypeCode.code.equalsIgnoreCase(typeCode))
+            {
+                return experimentTypeCode;
+            }
+        }
+        throw new IllegalArgumentException(String.format("No experiment type for given code '%s'.",
+                typeCode));
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/MaterialTypeCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/MaterialTypeCode.java
new file mode 100644
index 00000000000..fde7c1f1557
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/MaterialTypeCode.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.types;
+
+/**
+ * The current <code>MaterialType</code> codes.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class MaterialTypeCode
+{
+    private MaterialTypeCode()
+    {
+        // Can not be instantiated.
+    }
+
+    public static final String GENE = "GENE";
+
+    public static final String OLIGO = "OLIGO";
+
+    public static final String VIRUS = "VIRUS";
+
+    public static final String CONTROL = "CONTROL";
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ProcedureTypeCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ProcedureTypeCode.java
new file mode 100644
index 00000000000..99a39199a4f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/ProcedureTypeCode.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.types;
+
+/**
+ * The current <code>ProcedureType</code> codes.
+ * <p>
+ * This enumeration should reflect the values in the database and is <i>Unit</i> tested to ensure
+ * this point.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public enum ProcedureTypeCode
+{
+    DATA_ACQUISITION("DATA_ACQUISITION"), IMAGE_ANALYSIS("IMAGE_ANALYSIS"), UNKNOWN("UNKNOWN");
+
+    private final String code;
+
+    private ProcedureTypeCode(final String code)
+    {
+        this.code = code;
+    }
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    /** For given <var>typeCode</var> returns the corresponding <code>ProcedureTypeCode</code>. */
+    public final static ProcedureTypeCode getProcedureTypeCode(final String typeCode)
+    {
+        assert typeCode != null : "Unspecified procedure type code.";
+        for (final ProcedureTypeCode procedureTypeCode : values())
+        {
+            if (procedureTypeCode.code.equalsIgnoreCase(typeCode))
+            {
+                return procedureTypeCode;
+            }
+        }
+        throw new IllegalArgumentException(String.format("No procedure type for given code '%s'.",
+                typeCode));
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/SampleTypeCode.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/SampleTypeCode.java
new file mode 100644
index 00000000000..ed247aa80d0
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/types/SampleTypeCode.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2007 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.types;
+
+/**
+ * The current <code>SampleType</code> codes.
+ * <p>
+ * This enumeration should reflect the values in the database and is <i>Unit</i> tested to ensure
+ * this point.
+ * </p>
+ * 
+ * @author Christian Ribeaud
+ */
+public enum SampleTypeCode
+{
+    CELL_PLATE("CELL_PLATE", true, "cell plate"), 
+    CONTROL_LAYOUT("CONTROL_LAYOUT", false, "control layout"), 
+    DILUTION_PLATE("DILUTION_PLATE", true, "dilution plate"),
+    MASTER_PLATE("MASTER_PLATE", false, "master plate"), 
+    REINFECT_PLATE("REINFECT_PLATE", true, "reinfection plate"),
+    WELL("WELL", false, "well");
+
+    private final String code;
+
+    private final boolean parentRequired;
+
+    private final String description;
+
+    private SampleTypeCode(final String code, final boolean parentRequired, final String description)
+    {
+        this.code = code;
+        this.parentRequired = parentRequired;
+        this.description = description;
+    }
+
+    public final String getCode()
+    {
+        return code;
+    }
+
+    public final boolean isParentRequired()
+    {
+        return parentRequired;
+    }
+
+    public final String getDescription()
+    {
+        return description;
+    }
+
+    /** For given <var>typeCode</var> returns the corresponding <code>SampleTypeCode</code>. */
+    public final static SampleTypeCode getSampleTypeCode(final String typeCode)
+    {
+        assert typeCode != null : "Unspecified sample type code.";
+        for (final SampleTypeCode sampleTypeCode : values())
+        {
+            if (sampleTypeCode.code.equalsIgnoreCase(typeCode))
+            {
+                return sampleTypeCode;
+            }
+        }
+        throw new IllegalArgumentException(String.format("No sample type for given code '%s'.",
+                typeCode));
+    }
+}
\ No newline at end of file
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestUtil.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestUtil.java
index c88ea744587..53aec475e29 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestUtil.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/AuthorizationTestUtil.java
@@ -31,15 +31,15 @@ import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
-import ch.systemsx.cisd.lims.base.util.CodeConverter;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDatabaseInstanceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGroupDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.CodeConverter;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 
 /**
  * Utility methods for {@link AuthorizationAdvisor}. Can be used to test authorization of concrete
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java
index 4ba01e085e3..a2a16e6e48d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultAccessControllerTest.java
@@ -30,13 +30,13 @@ import org.testng.annotations.Test;
 import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
 import ch.systemsx.cisd.openbis.generic.server.authorization.IAccessController.Argument;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RoleSet;
 import ch.systemsx.cisd.openbis.generic.server.authorization.annotation.RolesAllowed;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 
 /**
  * Test cases for corresponding {@link DefaultAccessController} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilterTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilterTest.java
index d2dea5b6a84..6946eb687eb 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilterTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/DefaultReturnValueFilterTest.java
@@ -42,9 +42,9 @@ import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogInitializer;
 import ch.systemsx.cisd.common.test.LogMonitoringAppender;
 import ch.systemsx.cisd.common.utilities.StringUtilities;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.server.authorization.DefaultReturnValueFilter;
 import ch.systemsx.cisd.openbis.generic.server.authorization.validator.IValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 
 /**
  * Test cases for corresponding {@link DefaultReturnValueFilter} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutorTest.java
index 0e08e1e7a43..b2ee0080dea 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/PredicateExecutorTest.java
@@ -31,11 +31,11 @@ import org.testng.annotations.Test;
 import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.utilities.StringUtilities;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.IPredicate;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Test cases for corresponding {@link PredicateExecutor} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifierTest.java
index d169842ed77..54499e66d54 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifierTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/RoleWithIdentifierTest.java
@@ -27,15 +27,13 @@ import java.util.Set;
 import org.testng.annotations.Test;
 
 import ch.rinn.restrictions.Friend;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
-import ch.systemsx.cisd.openbis.generic.server.authorization.Role;
-import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.Role.RoleLevel;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Test cases for corresponding {@link RoleWithIdentifier} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicateTest.java
index 4313747463e..47730520304 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/DatabaseInstanceIdentifierPredicateTest.java
@@ -33,15 +33,15 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.DatabaseInstanceIdentifier;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.authorization.RoleWithIdentifierTest;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDatabaseInstanceDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Test cases for corresponding {@link DatabaseInstanceIdentifierPredicate} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicateTest.java
index 8f846a12b3f..2e1ebd3a9d6 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/GroupIdentifierPredicateTest.java
@@ -33,13 +33,13 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.exceptions.StatusFlag;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.identifier.GroupIdentifier;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDatabaseInstanceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGroupDAO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
 
 /**
  * Test cases for corresponding {@link GroupIdentifierPredicate} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicateTest.java
index e4084df64d2..0a2f21e6043 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/NewExperimentPredicateTest.java
@@ -20,8 +20,8 @@ import static org.testng.AssertJUnit.assertFalse;
 
 import org.testng.annotations.Test;
 
-import ch.systemsx.cisd.lims.base.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.NewExperimentPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewExperiment;
 
 /**
  * Test cases for corresponding {@link NewExperimentPredicate} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicateTest.java
index f895e02269e..1ce0d2d99a3 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/predicate/QueryRestrictionPredicateTest.java
@@ -20,8 +20,8 @@ import static org.testng.AssertJUnit.assertFalse;
 
 import org.testng.annotations.Test;
 
-import ch.systemsx.cisd.lims.base.dto.QueryRestriction;
 import ch.systemsx.cisd.openbis.generic.server.authorization.predicate.QueryRestrictionPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.dto.QueryRestriction;
 
 /**
  * Test cases for corresponding {@link QueryRestrictionPredicate} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidatorTest.java
index 1f07de0c749..6c383a238e7 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/authorization/validator/GroupValidatorTest.java
@@ -24,12 +24,11 @@ import java.util.List;
 
 import org.testng.annotations.Test;
 
-import ch.systemsx.cisd.lims.base.dto.DatabaseInstancePE;
-import ch.systemsx.cisd.lims.base.dto.GroupPE;
-import ch.systemsx.cisd.lims.base.dto.PersonPE;
-import ch.systemsx.cisd.lims.base.dto.RoleAssignmentPE;
-import ch.systemsx.cisd.lims.base.role.RoleCode;
-import ch.systemsx.cisd.openbis.generic.server.authorization.validator.GroupValidator;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.RoleCode;
 
 /**
  * Test cases for corresponding {@link GroupValidator} class.
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifierTest.java
new file mode 100644
index 00000000000..7264b9de553
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/DatabaseInstanceIdentifierTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.test.EqualsHashCodeTestCase;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+
+/**
+ * Test cases for corresponding {@link DatabaseInstanceIdentifier} class.
+ * 
+ * @author Christian Ribeaud
+ */
+@Test
+public final class DatabaseInstanceIdentifierTest extends
+        EqualsHashCodeTestCase<DatabaseInstanceIdentifier>
+{
+
+    //
+    // EqualsHashCodeTestCase
+    //
+
+    @Override
+    protected final DatabaseInstanceIdentifier createInstance() throws Exception
+    {
+        return new DatabaseInstanceIdentifier("DB1");
+    }
+
+    @Override
+    protected final DatabaseInstanceIdentifier createNotEqualInstance() throws Exception
+    {
+        return new DatabaseInstanceIdentifier("db2");
+    }
+
+    @Test
+    public final void testEqualsIgnoreCase()
+    {
+        assertEquals(new DatabaseInstanceIdentifier("db2"), new DatabaseInstanceIdentifier("DB2"));
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierTest.java
new file mode 100644
index 00000000000..ab3a3c1737f
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.test.EqualsHashCodeTestCase;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+
+/**
+ * Test cases for corresponding {@link ExperimentIdentifier} class.
+ * 
+ * @author Christian Ribeaud
+ */
+@Test
+public final class ExperimentIdentifierTest extends EqualsHashCodeTestCase<ExperimentIdentifier>
+{
+
+    //
+    // EqualsHashCodeTestCase
+    //
+
+    @Override
+    protected final ExperimentIdentifier createInstance() throws Exception
+    {
+        return new ExperimentIdentifier("DB1", "G", "P1", "E1");
+    }
+
+    @Override
+    protected final ExperimentIdentifier createNotEqualInstance() throws Exception
+    {
+        return new ExperimentIdentifier("DB1", "G", "p1", "e2");
+    }
+
+    @Test
+    public final void testEqualsIgnoreCase()
+    {
+        assertEquals(new ExperimentIdentifier("DB1", "G", "P", "E"), new ExperimentIdentifier(
+                "DB1", "G", "p", "e"));
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifierTest.java
new file mode 100644
index 00000000000..887366223cf
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/GroupIdentifierTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.test.EqualsHashCodeTestCase;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+
+/**
+ * Test cases for corresponding {@link GroupIdentifier} class.
+ * 
+ * @author Christian Ribeaud
+ */
+@Test
+public class GroupIdentifierTest extends EqualsHashCodeTestCase<GroupIdentifier>
+{
+
+    //
+    // EqualsHashCodeTestCase
+    //
+
+    @Override
+    protected final GroupIdentifier createInstance() throws Exception
+    {
+        return new GroupIdentifier("DB1", "G");
+    }
+
+    @Override
+    protected final GroupIdentifier createNotEqualInstance() throws Exception
+    {
+        return new GroupIdentifier((String) null, "G");
+    }
+
+    @Test
+    public final void testEqualsIgnoreCase()
+    {
+        assertEquals(new GroupIdentifier("DB2", "G"), new GroupIdentifier("DB2", "g"));
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifierTest.java
new file mode 100644
index 00000000000..c5913759225
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ProjectIdentifierTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.common.test.EqualsHashCodeTestCase;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+
+/**
+ * Test cases for corresponding {@link ProjectIdentifier} class.
+ * 
+ * @author Christian Ribeaud
+ */
+@Test
+public final class ProjectIdentifierTest extends EqualsHashCodeTestCase<ProjectIdentifier>
+{
+
+    //
+    // EqualsHashCodeTestCase
+    //
+
+    @Override
+    protected final ProjectIdentifier createInstance() throws Exception
+    {
+        return new ProjectIdentifier("DB1", "G", "P1");
+    }
+
+    @Override
+    protected final ProjectIdentifier createNotEqualInstance() throws Exception
+    {
+        return new ProjectIdentifier("DB1", "G", "p2");
+    }
+
+    @Test
+    public final void testEqualsIgnoreCase()
+    {
+        assertEquals(new ProjectIdentifier("DB1", "G", "P"), new ProjectIdentifier("DB1", "G", "p"));
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java
new file mode 100644
index 00000000000..f54b6ce5368
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/SampleIdentifierTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.dto.identifier;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.GroupIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+
+/**
+ * Test cases for corresponding {@link SampleIdentifier} class.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class SampleIdentifierTest
+{
+    final static String SAMPLE_TYPE = "TYPE1";
+
+    @Test
+    public final void testToStringDbLevel()
+    {
+        final SampleIdentifier sampleIdentifier =
+                new SampleIdentifier(new DatabaseInstanceIdentifier("DB"), "SAMP");
+        assertEquals(sampleIdentifier.toString(), "DB:/SAMP");
+    }
+
+    @Test
+    public final void testToStringGroupLevelHomeBd()
+    {
+        final SampleIdentifier sampleIdentifier =
+                new SampleIdentifier(new GroupIdentifier(DatabaseInstanceIdentifier.HOME, "GR"),
+                        "SAMP");
+        assertEquals(sampleIdentifier.toString(), "/GR/SAMP");
+    }
+
+    @Test
+    public final void testToStringGroupLevel()
+    {
+        final SampleIdentifier sampleIdentifier =
+                new SampleIdentifier(new GroupIdentifier("DB", "GR"), "SAMP");
+        assertEquals(sampleIdentifier.toString(), "DB:/GR/SAMP");
+    }
+
+    @Test
+    public final void testToStringHomeGroupLevel()
+    {
+        final SampleIdentifier sampleIdentifier = SampleIdentifier.createHomeGroup("SAMP");
+        assertEquals(sampleIdentifier.toString(), "SAMP");
+    }
+
+    @Test
+    public final void testCompareIdentifiers()
+    {
+        DatabaseInstanceIdentifier homeDb = DatabaseInstanceIdentifier.createHome();
+        DatabaseInstanceIdentifier otherDb = new DatabaseInstanceIdentifier("db");
+
+        String g1 = "AG";
+        String g2 = "BG";
+        String c1 = "A";
+        String c2 = "B";
+        SampleIdentifier[] expectedOrder =
+                new SampleIdentifier[]
+                    { SampleIdentifier.createHomeGroup(c1), SampleIdentifier.createHomeGroup(c2),
+                            new SampleIdentifier(new GroupIdentifier(homeDb, g1), c1),
+                            new SampleIdentifier(new GroupIdentifier(homeDb, g2), c1),
+                            new SampleIdentifier(new GroupIdentifier(homeDb, g2), c2),
+                            new SampleIdentifier(new GroupIdentifier(otherDb, g1), c1),
+                            new SampleIdentifier(new GroupIdentifier(otherDb, g1), c2),
+                            new SampleIdentifier(new GroupIdentifier(otherDb, g2), c1),
+                            new SampleIdentifier(new GroupIdentifier(otherDb, g2), c2) };
+
+        SampleIdentifier[] idents = revert(expectedOrder);
+        Arrays.sort(idents);
+        assertEquals(Arrays.asList(expectedOrder), Arrays.asList(idents));
+    }
+
+    private static SampleIdentifier[] revert(SampleIdentifier[] expectedOrder)
+    {
+        SampleIdentifier[] idents = new SampleIdentifier[expectedOrder.length];
+        for (int i = 0; i < idents.length; i++)
+        {
+            idents[idents.length - i - 1] = expectedOrder[i];
+        }
+        return idents;
+    }
+}
-- 
GitLab