diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index 107ecdf97707456dafe64522da753ab7ac859b41..807c9bac0b5544581fd59c554262dd11580dfaa1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteri
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.VocabularyTermWithStats;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
@@ -59,316 +60,377 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
  * 
  * @author Franz-Josef Elmer
  */
-public interface ICommonClientService extends IClientService
-{
-    /**
-     * Returns a list of all groups which belong to the specified database instance.
-     */
-    public List<Group> listGroups(String databaseInstanceCode) throws UserFailureException;
-
-    /**
-     * Registers a new group with specified code and optional description and group leader ID.
-     */
-    public void registerGroup(String groupCode, String descriptionOrNull, String groupLeaderOrNull)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of all persons which belong to the current database instance.
-     */
-    public List<Person> listPersons() throws UserFailureException;
-
-    /**
-     * Registers a new person with specified code.
-     */
-    public void registerPerson(String code) throws UserFailureException;
-
-    /**
-     * Returns a list of all roles.
-     */
-    public List<RoleAssignment> listRoles() throws UserFailureException;
-
-    /**
-     * Registers a new role from given role set code, group code and person code
-     */
-    public void registerGroupRole(RoleSetCode roleSetCode, String group, String person)
-            throws UserFailureException;
-
-    /**
-     * Deletes the role described by given role set code, group code and person code
-     */
-    public void deleteGroupRole(RoleSetCode roleSetCode, String group, String person)
-            throws UserFailureException;
-
-    /**
-     * Registers a new role from given role set code and person code
-     */
-    public void registerInstanceRole(RoleSetCode roleSetCode, String person)
-            throws UserFailureException;
-
-    /**
-     * Deletes the role described by given role set code and person code
-     */
-    public void deleteInstanceRole(RoleSetCode roleSetCode, String person)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of sample types.
-     */
-    public List<SampleType> listSampleTypes() throws UserFailureException;
-
-    /**
-     * Returns a list of samples for given sample type.
-     */
-    public ResultSet<Sample> listSamples(final ListSampleCriteria criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a key which can be used be the export servlet (and eventually
-     * {@link #getExportTable(String, String)}) to reference the export criteria in an easy way.
-     */
-    public String prepareExportSamples(final TableExportCriteria<Sample> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of experiments.
-     */
-    public ResultSet<Experiment> listExperiments(final ListExperimentsCriteria criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of materials.
-     */
-    public ResultSet<Material> listMaterials(final ListMaterialCriteria criteria)
-            throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for experiments.
-     */
-
-    public String prepareExportExperiments(final TableExportCriteria<Experiment> criteria)
-            throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for data set search hits.
-     */
-    public String prepareExportDataSetSearchHits(TableExportCriteria<ExternalData> exportCriteria)
-            throws UserFailureException;
-
-    /**
-     * Lists the entities matching the search.
-     */
-    public ResultSet<MatchingEntity> listMatchingEntities(
-            final SearchableEntity searchableEntityOrNull, final String queryText,
-            final IResultSetConfig<String, MatchingEntity> resultSetConfig)
-            throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for matching entites.
-     */
-    public String prepareExportMatchingEntities(final TableExportCriteria<MatchingEntity> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a chunk of the property types list.
-     */
-    public ResultSet<PropertyType> listPropertyTypes(
-            DefaultResultSetConfig<String, PropertyType> criteria) throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for property types.
-     */
-    public String prepareExportPropertyTypes(final TableExportCriteria<PropertyType> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a chunk of the property types assignment list.
-     */
-    public ResultSet<EntityTypePropertyType<?>> listPropertyTypeAssignments(
-            DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria);
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for property types assignments.
-     */
-    public String prepareExportPropertyTypeAssignments(
-            final TableExportCriteria<EntityTypePropertyType<?>> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of all projects.
-     */
-    public ResultSet<Project> listProjects(DefaultResultSetConfig<String, Project> criteria)
-            throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for projects.
-     */
-    public String prepareExportProjects(final TableExportCriteria<Project> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of all vocabularies.
-     * <p>
-     * Note that the vocabulary terms are included/loaded.
-     * </p>
-     */
-    public ResultSet<Vocabulary> listVocabularies(boolean withTerms, boolean excludeInternal,
-            DefaultResultSetConfig<String, Vocabulary> criteria) throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for Vocabularies.
-     */
-    public String prepareExportVocabularies(final TableExportCriteria<Vocabulary> criteria)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of all vocabulary terms for a specified vocabulary.
-     */
-    public ResultSet<VocabularyTermWithStats> listVocabularyTerms(Vocabulary vocabulary,
-            DefaultResultSetConfig<String, VocabularyTermWithStats> resultSetConfig);
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for Vocabulary Terms.
-     */
-    public String prepareExportVocabularyTerms(TableExportCriteria<VocabularyTermWithStats> criteria);
-
-    public ResultSet<? extends EntityType> listMaterialTypes(
-            DefaultResultSetConfig<String, MaterialType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for MaterialType.
-     */
-    public String prepareExportMaterialTypes(final TableExportCriteria<MaterialType> criteria)
-            throws UserFailureException;
-
-    public ResultSet<? extends EntityType> listSampleTypes(
-            DefaultResultSetConfig<String, SampleType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for SampleType.
-     */
-    public String prepareExportSampleTypes(final TableExportCriteria<SampleType> criteria)
-            throws UserFailureException;
-
-    public ResultSet<? extends EntityType> listExperimentTypes(
-            DefaultResultSetConfig<String, ExperimentType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for ExperimentType.
-     */
-    public String prepareExportExperimentTypes(final TableExportCriteria<ExperimentType> criteria)
-            throws UserFailureException;
-
-    /**
-     * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)}
-     * or {@link #prepareExportExperiments(TableExportCriteria)} has been invoked before and
-     * returned with an exportDataKey passed here as a parameter.
-     */
-    public String getExportTable(String exportDataKey, String lineSeparator)
-            throws UserFailureException;
-
-    /**
-     * Removes the session result set associated with given key.
-     */
-    public void removeResultSet(final String resultSetKey) throws UserFailureException;
-
-    /**
-     * For given <var>sampleIdentifier</var> returns corresponding list of {@link ExternalData}.
-     */
-    public ResultSet<ExternalData> listSampleDataSets(final String sampleIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria) throws UserFailureException;
-
-    public ResultSet<ExternalData> listExperimentDataSets(String experimentIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria) throws UserFailureException;
-
-    /**
-     * Lists the searchable entities.
-     */
-    public List<SearchableEntity> listSearchableEntities() throws UserFailureException;
-
-    /**
-     * Returns a list of all experiment types.
-     */
-    public List<ExperimentType> listExperimentTypes() throws UserFailureException;
-
-    /**
-     * Returns a list of all data types.
-     */
-    public List<DataType> listDataTypes() throws UserFailureException;
-
-    /**
-     * Assigns property type to entity type.
-     */
-    public String assignPropertyType(EntityKind entityKind, String propertyTypeCode,
-            String entityTypeCode, boolean isMandatory, String defaultValue)
-            throws UserFailureException;
-
-    /**
-     * Registers given {@link PropertyType}.
-     */
-    public void registerPropertyType(final PropertyType propertyType) throws UserFailureException;
-
-    /**
-     * Registers given {@link Vocabulary}.
-     */
-    public void registerVocabulary(final Vocabulary vocabulary) throws UserFailureException;
-
-    /**
-     * Registers given {@link Project}.
-     */
-    public void registerProject(final Project project) throws UserFailureException;
-
-    /**
-     * Returns {@link ExternalData} fulfilling given {@link DataSetSearchCriteria}.
-     */
-    public ResultSet<ExternalData> searchForDataSets(DataSetSearchCriteria criteria,
-            final IResultSetConfig<String, ExternalData> resultSetConfig)
-            throws UserFailureException;
-
-    /**
-     * Returns a list of all material types.
-     */
-    public List<MaterialType> listMaterialTypes() throws UserFailureException;
-
-    /**
-     * Like {@link #prepareExportSamples(TableExportCriteria)}, but for materials.
-     */
-    public String prepareExportMaterials(final TableExportCriteria<Material> criteria)
-            throws UserFailureException;
-
-    /** Registers a new material type */
-    public void registerMaterialType(MaterialType entityType) throws UserFailureException;
-
-    /** Registers a new sample type */
-    public void registerSampleType(SampleType entityType) throws UserFailureException;
-
-    /** Registers a new experiment type */
-    public void registerExperimentType(ExperimentType entityType) throws UserFailureException;
-
-    /**
-     * Updates experiment.
-     */
-    public void updateExperiment(String attachmentSessionKey, final String experimentIdentifier,
-            List<ExperimentProperty> properties, String newProjectIdentifier, Date version)
-            throws UserFailureException;
-
-    /**
-     * Updates material.
-     */
-    public void updateMaterial(final String materialIdentifier, List<MaterialProperty> properties,
-            Date version) throws UserFailureException;
-
-    /**
-     * Updates sample.
-     */
-    public void updateSample(final String sampleIdentifier, List<SampleProperty> properties,
-            ExperimentIdentifier experimentIdentifierOrNull, Date version)
-            throws UserFailureException;
-
-    /** Deletes the specified data sets. */
-    public void deleteDataSets(List<String> dataSetCodes, String reason)
-            throws UserFailureException;
+public interface ICommonClientService extends IClientService {
+	/**
+	 * Returns a list of all groups which belong to the specified database
+	 * instance.
+	 */
+	public List<Group> listGroups(String databaseInstanceCode)
+			throws UserFailureException;
+
+	/**
+	 * Registers a new group with specified code and optional description and
+	 * group leader ID.
+	 */
+	public void registerGroup(String groupCode, String descriptionOrNull,
+			String groupLeaderOrNull) throws UserFailureException;
+
+	/**
+	 * Returns a list of all persons which belong to the current database
+	 * instance.
+	 */
+	public List<Person> listPersons() throws UserFailureException;
+
+	/**
+	 * Registers a new person with specified code.
+	 */
+	public void registerPerson(String code) throws UserFailureException;
+
+	/**
+	 * Returns a list of all roles.
+	 */
+	public List<RoleAssignment> listRoles() throws UserFailureException;
+
+	/**
+	 * Registers a new role from given role set code, group code and person code
+	 */
+	public void registerGroupRole(RoleSetCode roleSetCode, String group,
+			String person) throws UserFailureException;
+
+	/**
+	 * Deletes the role described by given role set code, group code and person
+	 * code
+	 */
+	public void deleteGroupRole(RoleSetCode roleSetCode, String group,
+			String person) throws UserFailureException;
+
+	/**
+	 * Registers a new role from given role set code and person code
+	 */
+	public void registerInstanceRole(RoleSetCode roleSetCode, String person)
+			throws UserFailureException;
+
+	/**
+	 * Deletes the role described by given role set code and person code
+	 */
+	public void deleteInstanceRole(RoleSetCode roleSetCode, String person)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of sample types.
+	 */
+	public List<SampleType> listSampleTypes() throws UserFailureException;
+
+	/**
+	 * Returns a list of samples for given sample type.
+	 */
+	public ResultSet<Sample> listSamples(final ListSampleCriteria criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a key which can be used be the export servlet (and eventually
+	 * {@link #getExportTable(String, String)}) to reference the export criteria
+	 * in an easy way.
+	 */
+	public String prepareExportSamples(
+			final TableExportCriteria<Sample> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of experiments.
+	 */
+	public ResultSet<Experiment> listExperiments(
+			final ListExperimentsCriteria criteria) throws UserFailureException;
+
+	/**
+	 * Returns a list of materials.
+	 */
+	public ResultSet<Material> listMaterials(final ListMaterialCriteria criteria)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * experiments.
+	 */
+
+	public String prepareExportExperiments(
+			final TableExportCriteria<Experiment> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for data set
+	 * search hits.
+	 */
+	public String prepareExportDataSetSearchHits(
+			TableExportCriteria<ExternalData> exportCriteria)
+			throws UserFailureException;
+
+	/**
+	 * Lists the entities matching the search.
+	 */
+	public ResultSet<MatchingEntity> listMatchingEntities(
+			final SearchableEntity searchableEntityOrNull,
+			final String queryText,
+			final IResultSetConfig<String, MatchingEntity> resultSetConfig)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for matching
+	 * entites.
+	 */
+	public String prepareExportMatchingEntities(
+			final TableExportCriteria<MatchingEntity> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a chunk of the property types list.
+	 */
+	public ResultSet<PropertyType> listPropertyTypes(
+			DefaultResultSetConfig<String, PropertyType> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for property
+	 * types.
+	 */
+	public String prepareExportPropertyTypes(
+			final TableExportCriteria<PropertyType> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a chunk of the property types assignment list.
+	 */
+	public ResultSet<EntityTypePropertyType<?>> listPropertyTypeAssignments(
+			DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria);
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for property
+	 * types assignments.
+	 */
+	public String prepareExportPropertyTypeAssignments(
+			final TableExportCriteria<EntityTypePropertyType<?>> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all projects.
+	 */
+	public ResultSet<Project> listProjects(
+			DefaultResultSetConfig<String, Project> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * projects.
+	 */
+	public String prepareExportProjects(
+			final TableExportCriteria<Project> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all vocabularies.
+	 * <p>
+	 * Note that the vocabulary terms are included/loaded.
+	 * </p>
+	 */
+	public ResultSet<Vocabulary> listVocabularies(boolean withTerms,
+			boolean excludeInternal,
+			DefaultResultSetConfig<String, Vocabulary> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * Vocabularies.
+	 */
+	public String prepareExportVocabularies(
+			final TableExportCriteria<Vocabulary> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all vocabulary terms for a specified vocabulary.
+	 */
+	public ResultSet<VocabularyTermWithStats> listVocabularyTerms(
+			Vocabulary vocabulary,
+			DefaultResultSetConfig<String, VocabularyTermWithStats> resultSetConfig);
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * Vocabulary Terms.
+	 */
+	public String prepareExportVocabularyTerms(
+			TableExportCriteria<VocabularyTermWithStats> criteria);
+
+	public ResultSet<? extends EntityType> listMaterialTypes(
+			DefaultResultSetConfig<String, MaterialType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * MaterialType.
+	 */
+	public String prepareExportMaterialTypes(
+			final TableExportCriteria<MaterialType> criteria)
+			throws UserFailureException;
+
+	public ResultSet<? extends EntityType> listSampleTypes(
+			DefaultResultSetConfig<String, SampleType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * SampleType.
+	 */
+	public String prepareExportSampleTypes(
+			final TableExportCriteria<SampleType> criteria)
+			throws UserFailureException;
+
+	public ResultSet<? extends EntityType> listExperimentTypes(
+			DefaultResultSetConfig<String, ExperimentType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * ExperimentType.
+	 */
+	public String prepareExportExperimentTypes(
+			final TableExportCriteria<ExperimentType> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Assumes that preparation of the export (
+	 * {@link #prepareExportSamples(TableExportCriteria)} or
+	 * {@link #prepareExportExperiments(TableExportCriteria)} has been invoked
+	 * before and returned with an exportDataKey passed here as a parameter.
+	 */
+	public String getExportTable(String exportDataKey, String lineSeparator)
+			throws UserFailureException;
+
+	/**
+	 * Removes the session result set associated with given key.
+	 */
+	public void removeResultSet(final String resultSetKey)
+			throws UserFailureException;
+
+	/**
+	 * For given <var>sampleIdentifier</var> returns corresponding list of
+	 * {@link ExternalData}.
+	 */
+	public ResultSet<ExternalData> listSampleDataSets(
+			final String sampleIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria)
+			throws UserFailureException;
+
+	public ResultSet<ExternalData> listExperimentDataSets(
+			String experimentIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria)
+			throws UserFailureException;
+
+	/**
+	 * Lists the searchable entities.
+	 */
+	public List<SearchableEntity> listSearchableEntities()
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all experiment types.
+	 */
+	public List<ExperimentType> listExperimentTypes()
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all data types.
+	 */
+	public List<DataType> listDataTypes() throws UserFailureException;
+
+	/**
+	 * Assigns property type to entity type.
+	 */
+	public String assignPropertyType(EntityKind entityKind,
+			String propertyTypeCode, String entityTypeCode,
+			boolean isMandatory, String defaultValue)
+			throws UserFailureException;
+
+	/**
+	 * Registers given {@link PropertyType}.
+	 */
+	public void registerPropertyType(final PropertyType propertyType)
+			throws UserFailureException;
+
+	/**
+	 * Registers given {@link Vocabulary}.
+	 */
+	public void registerVocabulary(final Vocabulary vocabulary)
+			throws UserFailureException;
+
+	/**
+	 * Registers given {@link Project}.
+	 */
+	public void registerProject(final Project project)
+			throws UserFailureException;
+
+	/**
+	 * Returns {@link ExternalData} fulfilling given
+	 * {@link DataSetSearchCriteria}.
+	 */
+	public ResultSet<ExternalData> searchForDataSets(
+			DataSetSearchCriteria criteria,
+			final IResultSetConfig<String, ExternalData> resultSetConfig)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all material types.
+	 */
+	public List<MaterialType> listMaterialTypes() throws UserFailureException;
+
+	/**
+	 * Like {@link #prepareExportSamples(TableExportCriteria)}, but for
+	 * materials.
+	 */
+	public String prepareExportMaterials(
+			final TableExportCriteria<Material> criteria)
+			throws UserFailureException;
+
+	/** Registers a new material type */
+	public void registerMaterialType(MaterialType entityType)
+			throws UserFailureException;
+
+	/** Registers a new sample type */
+	public void registerSampleType(SampleType entityType)
+			throws UserFailureException;
+
+	/** Registers a new experiment type */
+	public void registerExperimentType(ExperimentType entityType)
+			throws UserFailureException;
+
+	/**
+	 * Updates experiment.
+	 */
+	public void updateExperiment(String attachmentSessionKey,
+			final String experimentIdentifier,
+			List<ExperimentProperty> properties, String newProjectIdentifier,
+			Date version) throws UserFailureException;
+
+	/**
+	 * Updates material.
+	 */
+	public void updateMaterial(final String materialIdentifier,
+			List<MaterialProperty> properties, Date version)
+			throws UserFailureException;
+
+	/**
+	 * Updates sample.
+	 */
+	public void updateSample(final String sampleIdentifier,
+			List<SampleProperty> properties,
+			ExperimentIdentifier experimentIdentifierOrNull, Date version)
+			throws UserFailureException;
+
+	/** Deletes the specified data sets. */
+	public void deleteDataSets(List<String> dataSetCodes, String reason)
+			throws UserFailureException;
+
+	/**
+	 * Returns a list of all available data set types.
+	 */
+	public List<DataSetType> listDataSetTypes() throws UserFailureException;
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index 4abd04d10c62da42f9c13d85a1e36b595c0fc727..412354b5d668eb557c58c3d0698935539aea60cf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -19,8 +19,6 @@ package ch.systemsx.cisd.openbis.generic.client.web.client;
 import java.util.Date;
 import java.util.List;
 
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentIdentifier;
@@ -41,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteri
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.VocabularyTermWithStats;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
@@ -56,273 +55,322 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
 /**
  * Asynchronous version of {@link ICommonClientService}.
  * 
  * @author Franz-Josef Elmer
  */
-public interface ICommonClientServiceAsync extends IClientServiceAsync
-{
-    /** @see ICommonClientService#listGroups(String) */
-    public void listGroups(String databaseInstanceCode, AsyncCallback<List<Group>> callback);
-
-    /** @see ICommonClientService#registerGroup(String, String, String) */
-    public void registerGroup(String groupCode, String descriptionOrNull, String groupLeaderOrNull,
-            AsyncCallback<Void> callback);
-
-    /** @see ICommonClientService#listPersons() */
-    public void listPersons(AsyncCallback<List<Person>> asyncCallback);
-
-    /** @see ICommonClientService#registerPerson(String) */
-    public void registerPerson(String code, AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#listRoles() */
-    public void listRoles(AsyncCallback<List<RoleAssignment>> asyncCallback);
-
-    /** @see ICommonClientService#registerGroupRole(RoleSetCode, String, String) */
-    public void registerGroupRole(RoleSetCode roleSetCode, String group, String person,
-            AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#deleteGroupRole(RoleSetCode, String, String) */
-    public void deleteGroupRole(RoleSetCode roleSetCode, String group, String person,
-            AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#registerInstanceRole(RoleSetCode, String) */
-    public void registerInstanceRole(RoleSetCode roleSetCode, String person,
-            AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#deleteInstanceRole(RoleSetCode, String) */
-    public void deleteInstanceRole(RoleSetCode roleSetCode, String person,
-            AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#listSampleTypes() */
-    public void listSampleTypes(AsyncCallback<List<SampleType>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listSamples(ListSampleCriteria)
-     */
-    public void listSamples(final ListSampleCriteria criteria,
-            AsyncCallback<ResultSet<Sample>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#prepareExportSamples(TableExportCriteria)
-     */
-    public void prepareExportSamples(final TableExportCriteria<Sample> criteria,
-            AsyncCallback<String> asyncCallback);
-
-    /** @see ICommonClientService#listPropertyTypeAssignments(DefaultResultSetConfig) */
-    public void listPropertyTypeAssignments(
-            DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria,
-            final AsyncCallback<ResultSet<EntityTypePropertyType<?>>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#prepareExportPropertyTypeAssignments(TableExportCriteria)
-     */
-    public void prepareExportPropertyTypeAssignments(
-            final TableExportCriteria<EntityTypePropertyType<?>> criteria,
-            AsyncCallback<String> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listExperiments(ListExperimentsCriteria)
-     */
-    public void listExperiments(
-            final ListExperimentsCriteria criteria,
-            AsyncCallback<ResultSet<ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#prepareExportExperiments(TableExportCriteria)
-     */
-    public void prepareExportExperiments(TableExportCriteria<Experiment> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /**
-     * @see ICommonClientService#prepareExportDataSetSearchHits(TableExportCriteria)
-     */
-    public void prepareExportDataSetSearchHits(TableExportCriteria<ExternalData> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listPropertyTypes(DefaultResultSetConfig) */
-    public void listPropertyTypes(DefaultResultSetConfig<String, PropertyType> criteria,
-            final AsyncCallback<ResultSet<PropertyType>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#prepareExportPropertyTypes(TableExportCriteria)
-     */
-    public void prepareExportPropertyTypes(final TableExportCriteria<PropertyType> criteria,
-            AsyncCallback<String> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listMatchingEntities(SearchableEntity, String, IResultSetConfig)
-     */
-    public void listMatchingEntities(final SearchableEntity searchableEntity,
-            final String queryText, final IResultSetConfig<String, MatchingEntity> resultSetConfig,
-            final AsyncCallback<ResultSet<MatchingEntity>> asyncCallback);
-
-    /** @see ICommonClientService#prepareExportMatchingEntities(TableExportCriteria) */
-    public void prepareExportMatchingEntities(TableExportCriteria<MatchingEntity> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listProjects(DefaultResultSetConfig) */
-    public void listProjects(DefaultResultSetConfig<String, Project> criteria,
-            final AsyncCallback<ResultSet<Project>> asyncCallback);
-
-    /** @see ICommonClientService#prepareExportProjects(TableExportCriteria) */
-    public void prepareExportProjects(TableExportCriteria<Project> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listVocabularies(boolean, boolean, DefaultResultSetConfig) */
-    public void listVocabularies(final boolean withTerms, boolean excludeInternal,
-            DefaultResultSetConfig<String, Vocabulary> criteria,
-            final AsyncCallback<ResultSet<Vocabulary>> asyncCallback);
-
-    /** @see ICommonClientService#prepareExportVocabularies(TableExportCriteria) */
-    public void prepareExportVocabularies(TableExportCriteria<Vocabulary> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listVocabularyTerms(Vocabulary, DefaultResultSetConfig) */
-    public void listVocabularyTerms(Vocabulary vocabulary,
-            DefaultResultSetConfig<String, VocabularyTermWithStats> resultSetConfig,
-            AsyncCallback<ResultSet<VocabularyTermWithStats>> callback);
-
-    /** @see ICommonClientService#prepareExportVocabularyTerms(TableExportCriteria) */
-    public void prepareExportVocabularyTerms(
-            TableExportCriteria<VocabularyTermWithStats> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listMaterialTypes(DefaultResultSetConfig) */
-    public void listMaterialTypes(DefaultResultSetConfig<String, EntityType> criteria,
-            final AsyncCallback<ResultSet<EntityType>> asyncCallback)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /** @see ICommonClientService#prepareExportMaterialTypes(TableExportCriteria) */
-    public void prepareExportMaterialTypes(final TableExportCriteria<EntityType> criteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listSampleTypes(DefaultResultSetConfig) */
-    public void listSampleTypes(DefaultResultSetConfig<String, EntityType> criteria,
-            final AsyncCallback<ResultSet<EntityType>> asyncCallback)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /** @see ICommonClientService#prepareExportSampleTypes(TableExportCriteria) */
-    public void prepareExportSampleTypes(final TableExportCriteria<EntityType> criteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#listExperimentTypes(DefaultResultSetConfig) */
-    public void listExperimentTypes(DefaultResultSetConfig<String, EntityType> criteria,
-            final AsyncCallback<ResultSet<EntityType>> asyncCallback)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
-
-    /** @see ICommonClientService#prepareExportExperimentTypes(TableExportCriteria) */
-    public void prepareExportExperimentTypes(final TableExportCriteria<EntityType> criteria,
-            AsyncCallback<String> callback);
-
-    /**
-     * @see ICommonClientService#getExportTable(String, String)
-     */
-    public void getExportTable(String exportDataKey, String lineSeparator,
-            AsyncCallback<String> asyncCallback);
-
-    /**
-     * @see ICommonClientService#removeResultSet(String)
-     */
-    public void removeResultSet(final String resultSetKey, final AsyncCallback<Void> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listSampleDataSets(String, DefaultResultSetConfig)
-     */
-    public void listSampleDataSets(String sampleIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria,
-            AsyncCallback<ResultSet<ExternalData>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listExperimentDataSets(String, DefaultResultSetConfig)
-     */
-    public void listExperimentDataSets(String experimentIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria,
-            AsyncCallback<ResultSet<ExternalData>> asyncCallback);
-
-    /**
-     * @see ICommonClientService#listSearchableEntities()
-     */
-    public void listSearchableEntities(final AsyncCallback<List<SearchableEntity>> asyncCallback);
-
-    /** @see ICommonClientService#listExperimentTypes() */
-    public void listExperimentTypes(
-            final AsyncCallback<List<ExperimentType>> listExperimentTypesCallback);
-
-    /** @see ICommonClientService#listDataTypes() */
-    public void listDataTypes(final AsyncCallback<List<DataType>> asyncCallback);
-
-    /** @see ICommonClientService#assignPropertyType(EntityKind, String, String, boolean, String) */
-    public void assignPropertyType(EntityKind entityKind, String propertyTypeCode,
-            String entityTypeCode, boolean isMandatory, String defaultValue,
-            AsyncCallback<String> process);
-
-    /** @see ICommonClientService#registerPropertyType(PropertyType) */
-    public void registerPropertyType(final PropertyType propertyType,
-            final AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#registerVocabulary(Vocabulary) */
-    public void registerVocabulary(final Vocabulary vocabulary,
-            final AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#registerProject(Project) */
-    public void registerProject(Project project,
-            final AsyncCallback<Void> projectRegistrationCallback);
-
-    /**
-     * @see ICommonClientService#searchForDataSets(DataSetSearchCriteria, IResultSetConfig)
-     */
-    public void searchForDataSets(DataSetSearchCriteria criteria,
-            final IResultSetConfig<String, ExternalData> resultSetConfig,
-            final AsyncCallback<ResultSet<ExternalData>> callback);
-
-    /**
-     * @see ICommonClientService#listMaterialTypes()
-     */
-    public void listMaterialTypes(AsyncCallback<List<MaterialType>> callback);
-
-    /**
-     * @see ICommonClientService#listMaterials(ListMaterialCriteria)
-     */
-    public void listMaterials(ListMaterialCriteria criteria,
-            AsyncCallback<ResultSet<Material>> callback);
-
-    /** @see ICommonClientService#prepareExportMaterials(TableExportCriteria) */
-    public void prepareExportMaterials(TableExportCriteria<Material> exportCriteria,
-            AsyncCallback<String> callback);
-
-    /** @see ICommonClientService#registerMaterialType(MaterialType) */
-    public void registerMaterialType(MaterialType entityType,
-            final AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#registerSampleType(SampleType) */
-    public void registerSampleType(SampleType entityType, final AsyncCallback<Void> asyncCallback);
-
-    /** @see ICommonClientService#registerExperimentType(ExperimentType) */
-    public void registerExperimentType(ExperimentType entityType,
-            final AsyncCallback<Void> asyncCallback);
-
-    /**
-     * @see ICommonClientService#updateExperiment(String, String, List, String, Date)
-     */
-    public void updateExperiment(String attachmentSessionKey, final String experimentIdentifier,
-            List<ExperimentProperty> properties, String newProjectIdentifier, Date version,
-            final AsyncCallback<Void> asyncCallback) throws UserFailureException;
-
-    /**
-     * @see ICommonClientService#updateMaterial(String, List, Date)
-     */
-    public void updateMaterial(final String materialIdentifier, List<MaterialProperty> properties,
-            Date version, final AsyncCallback<Void> asyncCallback) throws UserFailureException;
-
-    /**
-     * @see ICommonClientService#updateSample(String, List, ExperimentIdentifier, Date)
-     */
-    public void updateSample(final String sampleIdentifier, List<SampleProperty> properties,
-            ExperimentIdentifier experimentIdentifierOrNull, Date version, final AsyncCallback<Void> asyncCallback) throws UserFailureException;
-
-    /** @see ICommonClientService#deleteDataSets(List, String) */
-    public void deleteDataSets(List<String> dataSetCodes, String reason,
-            AsyncCallback<Void> asyncCallback);
+public interface ICommonClientServiceAsync extends IClientServiceAsync {
+	/** @see ICommonClientService#listGroups(String) */
+	public void listGroups(String databaseInstanceCode,
+			AsyncCallback<List<Group>> callback);
+
+	/** @see ICommonClientService#registerGroup(String, String, String) */
+	public void registerGroup(String groupCode, String descriptionOrNull,
+			String groupLeaderOrNull, AsyncCallback<Void> callback);
+
+	/** @see ICommonClientService#listPersons() */
+	public void listPersons(AsyncCallback<List<Person>> asyncCallback);
+
+	/** @see ICommonClientService#registerPerson(String) */
+	public void registerPerson(String code, AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#listRoles() */
+	public void listRoles(AsyncCallback<List<RoleAssignment>> asyncCallback);
+
+	/** @see ICommonClientService#registerGroupRole(RoleSetCode, String, String) */
+	public void registerGroupRole(RoleSetCode roleSetCode, String group,
+			String person, AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#deleteGroupRole(RoleSetCode, String, String) */
+	public void deleteGroupRole(RoleSetCode roleSetCode, String group,
+			String person, AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#registerInstanceRole(RoleSetCode, String) */
+	public void registerInstanceRole(RoleSetCode roleSetCode, String person,
+			AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#deleteInstanceRole(RoleSetCode, String) */
+	public void deleteInstanceRole(RoleSetCode roleSetCode, String person,
+			AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#listSampleTypes() */
+	public void listSampleTypes(AsyncCallback<List<SampleType>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listSamples(ListSampleCriteria)
+	 */
+	public void listSamples(final ListSampleCriteria criteria,
+			AsyncCallback<ResultSet<Sample>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#prepareExportSamples(TableExportCriteria)
+	 */
+	public void prepareExportSamples(
+			final TableExportCriteria<Sample> criteria,
+			AsyncCallback<String> asyncCallback);
+
+	/** @see ICommonClientService#listPropertyTypeAssignments(DefaultResultSetConfig) */
+	public void listPropertyTypeAssignments(
+			DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria,
+			final AsyncCallback<ResultSet<EntityTypePropertyType<?>>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#prepareExportPropertyTypeAssignments(TableExportCriteria)
+	 */
+	public void prepareExportPropertyTypeAssignments(
+			final TableExportCriteria<EntityTypePropertyType<?>> criteria,
+			AsyncCallback<String> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listExperiments(ListExperimentsCriteria)
+	 */
+	public void listExperiments(
+			final ListExperimentsCriteria criteria,
+			AsyncCallback<ResultSet<ch.systemsx.cisd.openbis.generic.client.web.client.dto.Experiment>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#prepareExportExperiments(TableExportCriteria)
+	 */
+	public void prepareExportExperiments(
+			TableExportCriteria<Experiment> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/**
+	 * @see ICommonClientService#prepareExportDataSetSearchHits(TableExportCriteria)
+	 */
+	public void prepareExportDataSetSearchHits(
+			TableExportCriteria<ExternalData> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#listPropertyTypes(DefaultResultSetConfig) */
+	public void listPropertyTypes(
+			DefaultResultSetConfig<String, PropertyType> criteria,
+			final AsyncCallback<ResultSet<PropertyType>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#prepareExportPropertyTypes(TableExportCriteria)
+	 */
+	public void prepareExportPropertyTypes(
+			final TableExportCriteria<PropertyType> criteria,
+			AsyncCallback<String> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listMatchingEntities(SearchableEntity, String,
+	 *      IResultSetConfig)
+	 */
+	public void listMatchingEntities(final SearchableEntity searchableEntity,
+			final String queryText,
+			final IResultSetConfig<String, MatchingEntity> resultSetConfig,
+			final AsyncCallback<ResultSet<MatchingEntity>> asyncCallback);
+
+	/** @see ICommonClientService#prepareExportMatchingEntities(TableExportCriteria) */
+	public void prepareExportMatchingEntities(
+			TableExportCriteria<MatchingEntity> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#listProjects(DefaultResultSetConfig) */
+	public void listProjects(DefaultResultSetConfig<String, Project> criteria,
+			final AsyncCallback<ResultSet<Project>> asyncCallback);
+
+	/** @see ICommonClientService#prepareExportProjects(TableExportCriteria) */
+	public void prepareExportProjects(
+			TableExportCriteria<Project> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/**
+	 * @see ICommonClientService#listVocabularies(boolean, boolean,
+	 *      DefaultResultSetConfig)
+	 */
+	public void listVocabularies(final boolean withTerms,
+			boolean excludeInternal,
+			DefaultResultSetConfig<String, Vocabulary> criteria,
+			final AsyncCallback<ResultSet<Vocabulary>> asyncCallback);
+
+	/** @see ICommonClientService#prepareExportVocabularies(TableExportCriteria) */
+	public void prepareExportVocabularies(
+			TableExportCriteria<Vocabulary> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/**
+	 * @see ICommonClientService#listVocabularyTerms(Vocabulary,
+	 *      DefaultResultSetConfig)
+	 */
+	public void listVocabularyTerms(
+			Vocabulary vocabulary,
+			DefaultResultSetConfig<String, VocabularyTermWithStats> resultSetConfig,
+			AsyncCallback<ResultSet<VocabularyTermWithStats>> callback);
+
+	/** @see ICommonClientService#prepareExportVocabularyTerms(TableExportCriteria) */
+	public void prepareExportVocabularyTerms(
+			TableExportCriteria<VocabularyTermWithStats> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#listMaterialTypes(DefaultResultSetConfig) */
+	public void listMaterialTypes(
+			DefaultResultSetConfig<String, EntityType> criteria,
+			final AsyncCallback<ResultSet<EntityType>> asyncCallback)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/** @see ICommonClientService#prepareExportMaterialTypes(TableExportCriteria) */
+	public void prepareExportMaterialTypes(
+			final TableExportCriteria<EntityType> criteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#listSampleTypes(DefaultResultSetConfig) */
+	public void listSampleTypes(
+			DefaultResultSetConfig<String, EntityType> criteria,
+			final AsyncCallback<ResultSet<EntityType>> asyncCallback)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/** @see ICommonClientService#prepareExportSampleTypes(TableExportCriteria) */
+	public void prepareExportSampleTypes(
+			final TableExportCriteria<EntityType> criteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#listExperimentTypes(DefaultResultSetConfig) */
+	public void listExperimentTypes(
+			DefaultResultSetConfig<String, EntityType> criteria,
+			final AsyncCallback<ResultSet<EntityType>> asyncCallback)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
+
+	/** @see ICommonClientService#prepareExportExperimentTypes(TableExportCriteria) */
+	public void prepareExportExperimentTypes(
+			final TableExportCriteria<EntityType> criteria,
+			AsyncCallback<String> callback);
+
+	/**
+	 * @see ICommonClientService#getExportTable(String, String)
+	 */
+	public void getExportTable(String exportDataKey, String lineSeparator,
+			AsyncCallback<String> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#removeResultSet(String)
+	 */
+	public void removeResultSet(final String resultSetKey,
+			final AsyncCallback<Void> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listSampleDataSets(String,
+	 *      DefaultResultSetConfig)
+	 */
+	public void listSampleDataSets(String sampleIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria,
+			AsyncCallback<ResultSet<ExternalData>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listExperimentDataSets(String,
+	 *      DefaultResultSetConfig)
+	 */
+	public void listExperimentDataSets(String experimentIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria,
+			AsyncCallback<ResultSet<ExternalData>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#listSearchableEntities()
+	 */
+	public void listSearchableEntities(
+			final AsyncCallback<List<SearchableEntity>> asyncCallback);
+
+	/** @see ICommonClientService#listExperimentTypes() */
+	public void listExperimentTypes(
+			final AsyncCallback<List<ExperimentType>> listExperimentTypesCallback);
+
+	/** @see ICommonClientService#listDataTypes() */
+	public void listDataTypes(final AsyncCallback<List<DataType>> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#assignPropertyType(EntityKind, String, String,
+	 *      boolean, String)
+	 */
+	public void assignPropertyType(EntityKind entityKind,
+			String propertyTypeCode, String entityTypeCode,
+			boolean isMandatory, String defaultValue,
+			AsyncCallback<String> process);
+
+	/** @see ICommonClientService#registerPropertyType(PropertyType) */
+	public void registerPropertyType(final PropertyType propertyType,
+			final AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#registerVocabulary(Vocabulary) */
+	public void registerVocabulary(final Vocabulary vocabulary,
+			final AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#registerProject(Project) */
+	public void registerProject(Project project,
+			final AsyncCallback<Void> projectRegistrationCallback);
+
+	/**
+	 * @see ICommonClientService#searchForDataSets(DataSetSearchCriteria,
+	 *      IResultSetConfig)
+	 */
+	public void searchForDataSets(DataSetSearchCriteria criteria,
+			final IResultSetConfig<String, ExternalData> resultSetConfig,
+			final AsyncCallback<ResultSet<ExternalData>> callback);
+
+	/**
+	 * @see ICommonClientService#listMaterialTypes()
+	 */
+	public void listMaterialTypes(AsyncCallback<List<MaterialType>> callback);
+
+	/**
+	 * @see ICommonClientService#listMaterials(ListMaterialCriteria)
+	 */
+	public void listMaterials(ListMaterialCriteria criteria,
+			AsyncCallback<ResultSet<Material>> callback);
+
+	/** @see ICommonClientService#prepareExportMaterials(TableExportCriteria) */
+	public void prepareExportMaterials(
+			TableExportCriteria<Material> exportCriteria,
+			AsyncCallback<String> callback);
+
+	/** @see ICommonClientService#registerMaterialType(MaterialType) */
+	public void registerMaterialType(MaterialType entityType,
+			final AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#registerSampleType(SampleType) */
+	public void registerSampleType(SampleType entityType,
+			final AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#registerExperimentType(ExperimentType) */
+	public void registerExperimentType(ExperimentType entityType,
+			final AsyncCallback<Void> asyncCallback);
+
+	/**
+	 * @see ICommonClientService#updateExperiment(String, String, List, String,
+	 *      Date)
+	 */
+	public void updateExperiment(String attachmentSessionKey,
+			final String experimentIdentifier,
+			List<ExperimentProperty> properties, String newProjectIdentifier,
+			Date version, final AsyncCallback<Void> asyncCallback)
+			throws UserFailureException;
+
+	/**
+	 * @see ICommonClientService#updateMaterial(String, List, Date)
+	 */
+	public void updateMaterial(final String materialIdentifier,
+			List<MaterialProperty> properties, Date version,
+			final AsyncCallback<Void> asyncCallback)
+			throws UserFailureException;
+
+	/**
+	 * @see ICommonClientService#updateSample(String, List,
+	 *      ExperimentIdentifier, Date)
+	 */
+	public void updateSample(final String sampleIdentifier,
+			List<SampleProperty> properties,
+			ExperimentIdentifier experimentIdentifierOrNull, Date version,
+			final AsyncCallback<Void> asyncCallback)
+			throws UserFailureException;
+
+	/** @see ICommonClientService#deleteDataSets(List, String) */
+	public void deleteDataSets(List<String> dataSetCodes, String reason,
+			AsyncCallback<Void> asyncCallback);
+
+	/** @see ICommonClientService#listDataSetTypes() */
+	public void listDataSetTypes(AsyncCallback<List<DataSetType>> callback);
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index 76802ff98516a99a1ebbbbb527d67daa7239fc2f..126b776587c9a7f457f45a217372a637359c5905 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -19,463 +19,464 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application;
 /**
  * Contains keys of the localized messages.
  * <p>
- * Use these constants instead of accessing messages with hard coded keys! Consider extending this
- * class for plugin specific keys. Currently this class contains message keys of the <i>common</i>
- * and <i>generic</i> technology.
+ * Use these constants instead of accessing messages with hard coded keys!
+ * Consider extending this class for plugin specific keys. Currently this class
+ * contains message keys of the <i>common</i> and <i>generic</i> technology.
  * </p>
  * 
  * @author Tomasz Pylak
  */
-public abstract class Dict
-{
+public abstract class Dict {
 
-    protected Dict()
-    {
-        // Can not be instantiated.
-    }
+	protected Dict() {
+		// Can not be instantiated.
+	}
 
-    public static final String APPLICATION_NAME = "applicationName";
+	public static final String APPLICATION_NAME = "applicationName";
 
-    public static final String WELCOME = "welcome";
+	public static final String WELCOME = "welcome";
 
-    public static final String FOOTER = "footer";
+	public static final String FOOTER = "footer";
 
-    //
-    // Common Labels
-    // 
+	//
+	// Common Labels
+	// 
 
-    public static final String CODE = "code";
+	public static final String CODE = "code";
 
-    public static final String REGISTRATOR = "registrator";
+	public static final String REGISTRATOR = "registrator";
 
-    public static final String REGISTRATION_DATE = "registration_date";
+	public static final String REGISTRATION_DATE = "registration_date";
 
-    public static final String NOT_IMPLEMENTED = "not_implemented";
+	public static final String NOT_IMPLEMENTED = "not_implemented";
 
-    //
-    // Field
-    //
+	//
+	// Field
+	//
 
-    public static final String COMBO_BOX_EMPTY = "combobox_empty";
+	public static final String COMBO_BOX_EMPTY = "combobox_empty";
 
-    public static final String COMBO_BOX_CHOOSE = "combobox_choose";
+	public static final String COMBO_BOX_CHOOSE = "combobox_choose";
 
-    public static final String INVALID_CODE_MESSAGE = "invalid_code_message";
+	public static final String INVALID_CODE_MESSAGE = "invalid_code_message";
 
-    //
-    // MessageBox
-    //
+	//
+	// MessageBox
+	//
 
-    public static final String MESSAGEBOX_ERROR = "messagebox_error";
+	public static final String MESSAGEBOX_ERROR = "messagebox_error";
 
-    public static final String MESSAGEBOX_WARNING = "messagebox_warning";
+	public static final String MESSAGEBOX_WARNING = "messagebox_warning";
 
-    public static final String MESSAGEBOX_INFO = "messagebox_info";
+	public static final String MESSAGEBOX_INFO = "messagebox_info";
 
-    //
-    // Buttons
-    //
+	//
+	// Buttons
+	//
 
-    public static final String TOOLTIP_REFRESH_ENABLED = "tooltip_refresh_enabled";
+	public static final String TOOLTIP_REFRESH_ENABLED = "tooltip_refresh_enabled";
 
-    public static final String TOOLTIP_REFRESH_DISABLED = "tooltip_refresh_disabled";
+	public static final String TOOLTIP_REFRESH_DISABLED = "tooltip_refresh_disabled";
 
-    public static final String TOOLTIP_EXPORT_ENABLED = "tooltip_export_enabled";
+	public static final String TOOLTIP_EXPORT_ENABLED = "tooltip_export_enabled";
 
-    public static final String TOOLTIP_EXPORT_DISABLED = "tooltip_export_disabled";
+	public static final String TOOLTIP_EXPORT_DISABLED = "tooltip_export_disabled";
 
-    public static final String BUTTON_SAVE = "button_save";
+	public static final String BUTTON_SAVE = "button_save";
 
-    public static final String BUTTON_CHOOSE = "button_choose";
+	public static final String BUTTON_CHOOSE = "button_choose";
 
-    public static final String BUTTON_CANCEL = "button_cancel";
+	public static final String BUTTON_CANCEL = "button_cancel";
 
-    public static final String BUTTON_RESET = "button_reset";
+	public static final String BUTTON_RESET = "button_reset";
 
-    public static final String BUTTON_SUBMIT = "button_submit";
+	public static final String BUTTON_SUBMIT = "button_submit";
 
-    public static final String BUTTON_REFRESH = "button_refresh";
+	public static final String BUTTON_REFRESH = "button_refresh";
 
-    public static final String BUTTON_SHOW = "button_show";
+	public static final String BUTTON_SHOW = "button_show";
 
-    public static final String BUTTON_BROWSE = "button_browse";
+	public static final String BUTTON_BROWSE = "button_browse";
 
-    public static final String BUTTON_SHOW_DETAILS = "button_show_details";
+	public static final String BUTTON_SHOW_DETAILS = "button_show_details";
 
-    public static final String BUTTON_EXPORT_DATA = "button_exportData";
+	public static final String BUTTON_EXPORT_DATA = "button_exportData";
 
-    public static final String BUTTON_ADD_GROUP = "button_add_group";
+	public static final String BUTTON_ADD_GROUP = "button_add_group";
 
-    //
-    // LoginWidget
-    //
+	//
+	// LoginWidget
+	//
 
-    public static final String LOGIN_INVITATION = "login_invitation";
+	public static final String LOGIN_INVITATION = "login_invitation";
 
-    public static final String LOGIN_USER_LABEL = "login_userLabel";
+	public static final String LOGIN_USER_LABEL = "login_userLabel";
 
-    public static final String LOGIN_PASSWORD_LABEL = "login_passwordLabel";
+	public static final String LOGIN_PASSWORD_LABEL = "login_passwordLabel";
 
-    public static final String LOGIN_BUTTON_LABEL = "login_buttonLabel";
+	public static final String LOGIN_BUTTON_LABEL = "login_buttonLabel";
 
-    public static final String LOGIN_FAILED = "login_failed";
+	public static final String LOGIN_FAILED = "login_failed";
 
-    //
-    // AbstractAsyncCallback
-    //
+	//
+	// AbstractAsyncCallback
+	//
 
-    public static final String EXCEPTION_INVOCATION_MESSAGE = "exception_invocationMessage";
+	public static final String EXCEPTION_INVOCATION_MESSAGE = "exception_invocationMessage";
 
-    public static final String EXCEPTION_WITHOUT_MESSAGE = "exception_withoutMessage";
+	public static final String EXCEPTION_WITHOUT_MESSAGE = "exception_withoutMessage";
 
-    //
-    // Header
-    //
+	//
+	// Header
+	//
 
-    public static final String HEADER_USER_WITHOUT_HOMEGROUP = "header_userWithoutHomegroup";
+	public static final String HEADER_USER_WITHOUT_HOMEGROUP = "header_userWithoutHomegroup";
 
-    public static final String HEADER_USER_WITH_HOMEGROUP = "header_userWithHomegroup";
+	public static final String HEADER_USER_WITH_HOMEGROUP = "header_userWithHomegroup";
 
-    public static final String HEADER_LOGOUT_BUTTON_LABEL = "header_logoutButtonLabel";
+	public static final String HEADER_LOGOUT_BUTTON_LABEL = "header_logoutButtonLabel";
 
-    //
-    // Authorization Management Console
-    // 
+	//
+	// Authorization Management Console
+	// 
 
-    public static final String PERSONS_VIEW_HEADING = "personsView_heading";
+	public static final String PERSONS_VIEW_HEADING = "personsView_heading";
 
-    public static final String GROUPS_VIEW_HEADING = "groupsView_heading";
+	public static final String GROUPS_VIEW_HEADING = "groupsView_heading";
 
-    public static final String ROLES_VIEW_HEADING = "rolesView_heading";
+	public static final String ROLES_VIEW_HEADING = "rolesView_heading";
 
-    //
-    // Search
-    //
+	//
+	// Search
+	//
 
-    public static final String SEARCH_BUTTON = "search_button";
+	public static final String SEARCH_BUTTON = "search_button";
 
-    public static final String GLOBAL_SEARCH = "global_search";
+	public static final String GLOBAL_SEARCH = "global_search";
 
-    public static final String IDENTIFIER = "identifier";
+	public static final String IDENTIFIER = "identifier";
 
-    public static final String NO_MATCH = "no_match";
+	public static final String NO_MATCH = "no_match";
 
-    public static final String ENTITY_TYPE = "entity_type";
+	public static final String ENTITY_TYPE = "entity_type";
 
-    public static final String ENTITY_KIND = "entity_kind";
+	public static final String ENTITY_KIND = "entity_kind";
 
-    public static final String MATCHING_TEXT = "matching_text";
+	public static final String MATCHING_TEXT = "matching_text";
 
-    public static final String MATCHING_FIELD = "matching_field";
+	public static final String MATCHING_FIELD = "matching_field";
 
-    public static final String TOO_GENERIC = "too_generic";
+	public static final String TOO_GENERIC = "too_generic";
 
-    //
-    // Sample Browser
-    //
+	//
+	// Sample Browser
+	//
 
-    public static final String SAMPLE = "sample";
+	public static final String SAMPLE = "sample";
 
-    public static final String SAMPLE_TYPE = "sample_type";
+	public static final String SAMPLE_TYPE = "sample_type";
 
-    public static final String DATABASE_INSTANCE = "database_instance";
+	public static final String DATABASE_INSTANCE = "database_instance";
 
-    public static final String SAMPLE_IDENTIFIER = "sample_identifier";
+	public static final String SAMPLE_IDENTIFIER = "sample_identifier";
 
-    public static final String IS_INSTANCE_SAMPLE = "is_instance_sample";
+	public static final String IS_INSTANCE_SAMPLE = "is_instance_sample";
 
-    public static final String IS_INVALID = "is_invalid";
+	public static final String IS_INVALID = "is_invalid";
 
-    public static final String GROUP = "group";
+	public static final String GROUP = "group";
 
-    public static final String PROJECT = "project";
+	public static final String PROJECT = "project";
 
-    public static final String EXPERIMENT = "experiment";
+	public static final String EXPERIMENT = "experiment";
 
-    public static final String EXPERIMENT_IDENTIFIER = "experiment_identifier";
+	public static final String EXPERIMENT_IDENTIFIER = "experiment_identifier";
 
-    public static final String GENERATED_SAMPLES = "generated_samples";
+	public static final String GENERATED_SAMPLES = "generated_samples";
 
-    public static final String GENERATED_FROM = "generated_from";
+	public static final String GENERATED_FROM = "generated_from";
 
-    public static final String PART_OF = "part_of";
+	public static final String PART_OF = "part_of";
 
-    //
-    // Experiment Browser
-    //
+	//
+	// Experiment Browser
+	//
 
-    public static final String EXPERIMENT_TYPE = "experiment_type";
+	public static final String EXPERIMENT_TYPE = "experiment_type";
 
-    //
-    // Property Type Browser
-    //
+	//
+	// Property Type Browser
+	//
 
-    public static final String LABEL = "label";
+	public static final String LABEL = "label";
 
-    public static final String DATA_TYPE = "data_type";
+	public static final String DATA_TYPE = "data_type";
 
-    public static final String DATA_TYPE_CODE = "data_type_code";
+	public static final String DATA_TYPE_CODE = "data_type_code";
 
-    public static final String DESCRIPTION = "description";
+	public static final String DESCRIPTION = "description";
 
-    public static final String SAMPLE_TYPES = "sample_types";
+	public static final String SAMPLE_TYPES = "sample_types";
 
-    public static final String MATERIAL_TYPES = "material_types";
+	public static final String MATERIAL_TYPES = "material_types";
 
-    public static final String EXPERIMENT_TYPES = "experiment_types";
+	public static final String EXPERIMENT_TYPES = "experiment_types";
 
-    public static final String IS_MANDATORY = "is_mandatory";
+	public static final String IS_MANDATORY = "is_mandatory";
 
-    public static final String PROPERTY_TYPE = "property_type";
+	public static final String PROPERTY_TYPE = "property_type";
 
-    public static final String PROPERTY_TYPE_CODE = "property_type_code";
+	public static final String PROPERTY_TYPE_CODE = "property_type_code";
 
-    public static final String ASSIGNED_TO = "assigned_to";
+	public static final String ASSIGNED_TO = "assigned_to";
 
-    public static final String TYPE_OF = "type_of";
+	public static final String TYPE_OF = "type_of";
 
-    public static final String VOCABULARY = "vocabulary";
+	public static final String VOCABULARY = "vocabulary";
 
-    public static final String VOCABULARY_TERMS = "vocabulary_terms";
+	public static final String VOCABULARY_TERMS = "vocabulary_terms";
 
-    public static final String VOCABULARY_TERMS_EMPTY = "vocabulary_terms_empty";
+	public static final String VOCABULARY_TERMS_EMPTY = "vocabulary_terms_empty";
 
-    public static final String MANDATORY = "mandatory";
+	public static final String MANDATORY = "mandatory";
 
-    public static final String DEFAULT_VALUE = "default_value";
+	public static final String DEFAULT_VALUE = "default_value";
 
-    public static final String DEFAULT_VALUE_TOOLTIP = "default_value_tooltip";
+	public static final String DEFAULT_VALUE_TOOLTIP = "default_value_tooltip";
 
-    // -------- generic plugin dictionary -------------------
+	// -------- generic plugin dictionary -------------------
 
-    //
-    // Experiment Viewer
-    //
+	//
+	// Experiment Viewer
+	//
 
-    public static final String FILE_NAME = "file_name";
+	public static final String FILE_NAME = "file_name";
 
-    public static final String VERSION_FILE_NAME = "version_file_name";
+	public static final String VERSION_FILE_NAME = "version_file_name";
 
-    public static final String VERSION = "version";
+	public static final String VERSION = "version";
 
-    public static final String VERSIONS = "versions";
+	public static final String VERSIONS = "versions";
 
-    public static final String VERSIONS_TEMPLATE = "versions_template";
+	public static final String VERSIONS_TEMPLATE = "versions_template";
 
-    public static final String NO_ATTACHMENTS_FOUND = "no_attachments_found";
+	public static final String NO_ATTACHMENTS_FOUND = "no_attachments_found";
 
-    public static final String NO_SAMPLES_FOUND = "no_samples_found";
+	public static final String NO_SAMPLES_FOUND = "no_samples_found";
 
-    public static final String PROCEDURE = "procedure";
+	public static final String PROCEDURE = "procedure";
 
-    //
-    // Sample Viewer
-    //
+	//
+	// Sample Viewer
+	//
 
-    public static final String SAMPLE_PROPERTIES_HEADING = "sample_properties_heading";
+	public static final String SAMPLE_PROPERTIES_HEADING = "sample_properties_heading";
 
-    public static final String PART_OF_HEADING = "part_of_heading";
+	public static final String PART_OF_HEADING = "part_of_heading";
 
-    public static final String EXTERNAL_DATA_HEADING = "external_data_heading";
+	public static final String EXTERNAL_DATA_HEADING = "external_data_heading";
 
-    public static final String INVALIDATION = "invalidation";
+	public static final String INVALIDATION = "invalidation";
 
-    public static final String INVALIDATION_TEMPLATE = "invalidation_template";
+	public static final String INVALIDATION_TEMPLATE = "invalidation_template";
 
-    //
-    // ExternalData Viewer
-    //
+	//
+	// ExternalData Viewer
+	//
 
-    public static final String PARENT_CODE = "parent_code";
+	public static final String PARENT_CODE = "parent_code";
 
-    public static final String LOCATION = "location";
+	public static final String LOCATION = "location";
 
-    public static final String FILE_FORMAT_TYPE = "file_format_type";
+	public static final String FILE_FORMAT_TYPE = "file_format_type";
 
-    public static final String DATA_SET_TYPE = "data_set_type";
+	public static final String DATA_SET_TYPE = "data_set_type";
 
-    public static final String PROCEDURE_TYPE = "procedure_type";
+	public static final String PROCEDURE_TYPE = "procedure_type";
 
-    public static final String EXTERNAL_DATA_SAMPLE = "external_data_sample";
+	public static final String EXTERNAL_DATA_SAMPLE = "external_data_sample";
 
-    public static final String IS_DERIVED = "is_derived";
+	public static final String IS_DERIVED = "is_derived";
 
-    public static final String IS_COMPLETE = "is_complete";
+	public static final String IS_COMPLETE = "is_complete";
 
-    public static final String PRODUCTION_DATE = "production_date";
+	public static final String PRODUCTION_DATE = "production_date";
 
-    public static final String DATA_PRODUCER_CODE = "data_producer_code";
+	public static final String DATA_PRODUCER_CODE = "data_producer_code";
 
-    public static final String BUTTON_DELETE_DATASETS = "button_delete_datasets";
+	public static final String BUTTON_DELETE_DATASETS = "button_delete_datasets";
 
-    public static final String CONFIRM_DATASET_DELETION_TITLE = "confirm_dataset_deletion_title";
+	public static final String CONFIRM_DATASET_DELETION_TITLE = "confirm_dataset_deletion_title";
 
-    public static final String CONFIRM_DATASET_DELETION_MSG = "confirm_dataset_deletion_msg";
+	public static final String CONFIRM_DATASET_DELETION_MSG = "confirm_dataset_deletion_msg";
 
-    //
-    // Sample Registration
-    //
+	//
+	// Sample Registration
+	//
 
-    public static final String INSTANCE_SAMPLE = "instance_sample";
+	public static final String INSTANCE_SAMPLE = "instance_sample";
 
-    public static final String GENERATED_FROM_SAMPLE = "generated_from_sample";
+	public static final String GENERATED_FROM_SAMPLE = "generated_from_sample";
 
-    public static final String PART_OF_SAMPLE = "part_of_sample";
+	public static final String PART_OF_SAMPLE = "part_of_sample";
 
-    //
-    // Menu Titles
-    //
+	//
+	// Menu Titles
+	//
 
-    public static final String MENU_ADMINISTRATION = "menu_administration";
+	public static final String MENU_ADMINISTRATION = "menu_administration";
 
-    public static final String MENU_AUTHORIZATION = "menu_authorization";
+	public static final String MENU_AUTHORIZATION = "menu_authorization";
 
-    public static final String MENU_PROJECT = "menu_project";
+	public static final String MENU_PROJECT = "menu_project";
 
-    public static final String MENU_PROPERTY_TYPES = "menu_property_types";
+	public static final String MENU_PROPERTY_TYPES = "menu_property_types";
 
-    public static final String MENU_VOCABULARY = "menu_vocabulary";
+	public static final String MENU_VOCABULARY = "menu_vocabulary";
 
-    public static final String MENU_DATA_SET = "menu_data_set";
+	public static final String MENU_DATA_SET = "menu_data_set";
 
-    public static final String MENU_EXPERIMENT = "menu_experiment";
+	public static final String MENU_EXPERIMENT = "menu_experiment";
 
-    public static final String MENU_MATERIAL = "menu_material";
+	public static final String MENU_MATERIAL = "menu_material";
 
-    public static final String MENU_SAMPLE = "menu_sample";
+	public static final String MENU_SAMPLE = "menu_sample";
 
-    //
-    // Tab Titles
-    //
+	//
+	// Tab Titles
+	//
 
-    public static final String ASSIGN_EXPERIMENT_PROPERTY_TYPE = "assign_experiment_property_type";
+	public static final String ASSIGN_EXPERIMENT_PROPERTY_TYPE = "assign_experiment_property_type";
 
-    public static final String ASSIGN_SAMPLE_PROPERTY_TYPE = "assign_sample_property_type";
+	public static final String ASSIGN_MATERIAL_PROPERTY_TYPE = "assign_material_property_type";
 
-    public static final String PROPERTY_TYPE_ASSIGNMENTS = "property_type_assignments";
+	public static final String ASSIGN_DATA_SET_PROPERTY_TYPE = "assign_data_set_property_type";
 
-    public static final String PROPERTY_TYPE_REGISTRATION = "property_type_registration";
+	public static final String ASSIGN_SAMPLE_PROPERTY_TYPE = "assign_sample_property_type";
 
-    public static final String PROPERTY_TYPES = "property_types";
+	public static final String PROPERTY_TYPE_ASSIGNMENTS = "property_type_assignments";
 
-    public static final String EXPERIMENT_BROWSER = "experiment_browser";
+	public static final String PROPERTY_TYPE_REGISTRATION = "property_type_registration";
 
-    public static final String VOCABULARY_REGISTRATION = "vocabulary_registration";
+	public static final String PROPERTY_TYPES = "property_types";
 
-    public static final String SAMPLE_BATCH_REGISTRATION = "sample_batch_registration";
+	public static final String EXPERIMENT_BROWSER = "experiment_browser";
 
-    public static final String SAMPLE_REGISTRATION = "sample_registration";
+	public static final String VOCABULARY_REGISTRATION = "vocabulary_registration";
 
-    public static final String SAMPLE_BROWSER = "sample_broser";
+	public static final String SAMPLE_BATCH_REGISTRATION = "sample_batch_registration";
 
-    public static final String LIST_GROUPS = "list_groups";
+	public static final String SAMPLE_REGISTRATION = "sample_registration";
 
-    public static final String CONFIRM_TITLE = "confirm_title";
+	public static final String SAMPLE_BROWSER = "sample_broser";
 
-    public static final String CONFIRM_CLOSE_MSG = "confirm_close_msg";
+	public static final String LIST_GROUPS = "list_groups";
 
-    //
-    // Role View
-    //
-    public static final String ROLE = "role";
+	public static final String CONFIRM_TITLE = "confirm_title";
 
-    public static final String CONFIRM_ROLE_REMOVAL_MSG = "confirm_role_removal_msg";
+	public static final String CONFIRM_CLOSE_MSG = "confirm_close_msg";
 
-    public static final String CONFIRM_ROLE_REMOVAL_TITLE = "confirm_role_removal_title";
+	//
+	// Role View
+	//
+	public static final String ROLE = "role";
 
-    //
-    // Experiment Registration
-    //
+	public static final String CONFIRM_ROLE_REMOVAL_MSG = "confirm_role_removal_msg";
 
-    public static final String EXPERIMENT_REGISTRATION = "experiment_registration";
+	public static final String CONFIRM_ROLE_REMOVAL_TITLE = "confirm_role_removal_title";
 
-    public static final String SAMPLES = "samples";
+	//
+	// Experiment Registration
+	//
 
-    public static final String SAMPLES_LIST = "samples_list";
+	public static final String EXPERIMENT_REGISTRATION = "experiment_registration";
 
-    //
-    // Vocabulary Browser
-    //
-    public static final String VOCABULARY_BROWSER = "vocabulary_browser";
+	public static final String SAMPLES = "samples";
 
-    public static final String IS_MANAGED_INTERNALLY = "is_managed_internally";
+	public static final String SAMPLES_LIST = "samples_list";
 
-    public static final String TERMS = "terms";
+	//
+	// Vocabulary Browser
+	//
+	public static final String VOCABULARY_BROWSER = "vocabulary_browser";
 
-    public static final String VOCABULARY_TERMS_BROWSER = "VOCABULARY_TERMS_BROWSER";
+	public static final String IS_MANAGED_INTERNALLY = "is_managed_internally";
 
-    public static final String TERM_FOR_SAMPLES_USAGE = "TERM_FOR_SAMPLES_USAGE";
+	public static final String TERMS = "terms";
 
-    public static final String TERM_FOR_EXPERIMENTS_USAGE = "TERM_FOR_EXPERIMENTS_USAGE";
+	public static final String VOCABULARY_TERMS_BROWSER = "VOCABULARY_TERMS_BROWSER";
 
-    public static final String TERM_FOR_MATERIALS_USAGE = "TERM_FOR_MATERIALS_USAGE";
+	public static final String TERM_FOR_SAMPLES_USAGE = "TERM_FOR_SAMPLES_USAGE";
 
-    public static final String TERM_TOTAL_USAGE = "TERM_TOTAL_USAGE";
+	public static final String TERM_FOR_EXPERIMENTS_USAGE = "TERM_FOR_EXPERIMENTS_USAGE";
 
-    //
-    // Project Browser
-    //
-    public static final String PROJECT_BROWSER = "project_browser";
+	public static final String TERM_FOR_MATERIALS_USAGE = "TERM_FOR_MATERIALS_USAGE";
 
-    //
-    // Project Registration
-    //
-    public static final String PROJECT_REGISTRATION = "project_registration";
+	public static final String TERM_TOTAL_USAGE = "TERM_TOTAL_USAGE";
 
-    //
-    // Data Set Search
-    //
-    public static final String DATA_SET_SEARCH = "data_set_search";
+	//
+	// Project Browser
+	//
+	public static final String PROJECT_BROWSER = "project_browser";
 
-    public static final String MATCH_ALL = "match_all";
+	//
+	// Project Registration
+	//
+	public static final String PROJECT_REGISTRATION = "project_registration";
 
-    public static final String MATCH_ANY = "match_any";
+	//
+	// Data Set Search
+	//
+	public static final String DATA_SET_SEARCH = "data_set_search";
 
-    public static final String BUTTON_CHANGE_QUERY = "button_change_query";
+	public static final String MATCH_ALL = "match_all";
 
-    //
-    // Material Browser
-    //
-    public static final String MATERIAL_TYPE = "material_type";
+	public static final String MATCH_ANY = "match_any";
 
-    public static final String MATERIAL_BROWSER = "material_browser";
+	public static final String BUTTON_CHANGE_QUERY = "button_change_query";
 
-    public static final String INHIBITOR_OF = "infibitor_of";
+	//
+	// Material Browser
+	//
+	public static final String MATERIAL_TYPE = "material_type";
 
-    public static final String ALLOW_ANY_TYPE = "allow_any_type";
+	public static final String MATERIAL_BROWSER = "material_browser";
 
-    // 
-    // Material Import
-    //
-    public static final String MATERIAL_IMPORT = "material_import";
+	public static final String INHIBITOR_OF = "infibitor_of";
 
-    // 
-    // Material Chooser
-    //
+	public static final String ALLOW_ANY_TYPE = "allow_any_type";
 
-    public static final String TITLE_CHOOSE_MATERIAL = "title_choose_material";
+	// 
+	// Material Import
+	//
+	public static final String MATERIAL_IMPORT = "material_import";
 
-    public static final String CHOOSE_ANY_MATERIAL = "choose_any_material";
+	// 
+	// Material Chooser
+	//
 
-    public static final String INCORRECT_MATERIAL_SYNTAX = "incorrect_material_syntax";
+	public static final String TITLE_CHOOSE_MATERIAL = "title_choose_material";
 
-    public static final String TITLE_CHOOSE_EXPERIMENT = "TITLE_CHOOSE_EXPERIMENT";
+	public static final String CHOOSE_ANY_MATERIAL = "choose_any_material";
 
-    //
-    // Unclassified
-    //
-    public static final String LEADER = "leader";
+	public static final String INCORRECT_MATERIAL_SYNTAX = "incorrect_material_syntax";
 
-    public static final String FILTER = "filter";
+	public static final String TITLE_CHOOSE_EXPERIMENT = "TITLE_CHOOSE_EXPERIMENT";
 
-    public static final String ENTITY_TYPE_ASSIGNMENTS = "entity_type_assignments";
+	//
+	// Unclassified
+	//
+	public static final String LEADER = "leader";
 
-    public static final String COMBO_BOX_EXPECTED_VALUE_FROM_THE_LIST =
-            "combo_box_expected_value_from_the_list";
+	public static final String FILTER = "filter";
 
-    public static final String EDIT_TITLE = "edit_title";
+	public static final String ENTITY_TYPE_ASSIGNMENTS = "entity_type_assignments";
 
-    public static final String BUTTON_EDIT = "edit";
+	public static final String COMBO_BOX_EXPECTED_VALUE_FROM_THE_LIST = "combo_box_expected_value_from_the_list";
 
-    // ----- end generic ------------------
+	public static final String EDIT_TITLE = "edit_title";
+
+	public static final String BUTTON_EDIT = "edit";
+
+	// ----- end generic ------------------
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
index 80ddb0233351993b28f94ea162d8b8533e4373f7..9bbe1715446526e0a1a661ef5c9092c3f44c0d03 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
@@ -16,8 +16,6 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.framework;
 
-import com.extjs.gxt.ui.client.widget.Component;
-
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.GroupsView;
@@ -45,6 +43,8 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.vocabul
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.vocabulary.VocabularyRegistrationForm;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 
+import com.extjs.gxt.ui.client.widget.Component;
+
 /**
  * Creates and provides GUI modules/components (such as sample browser).
  * <p>
@@ -53,424 +53,373 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
  * 
  * @author Izabela Adamczyk
  */
-public final class ComponentProvider
-{
-    private final CommonViewContext viewContext;
-
-    ComponentProvider(final CommonViewContext viewContext)
-    {
-        this.viewContext = viewContext;
-    }
-
-    private String getMessage(String key)
-    {
-        return viewContext.getMessage(key);
-    }
-
-    public final ITabItemFactory getSampleBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent browser = SampleBrowserGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.SAMPLE_BROWSER), browser);
-                }
-
-                public String getId()
-                {
-                    return SampleBrowserGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getMaterialBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent browser =
-                            MaterialBrowserGrid.createWithTypeChooser(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.MATERIAL_BROWSER), browser);
-                }
-
-                public String getId()
-                {
-                    return MaterialBrowserGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getDummyComponent()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    return new DefaultTabItem(getMessage(Dict.NOT_IMPLEMENTED),
-                            new DummyComponent(), false);
-                }
-
-                public String getId()
-                {
-                    return DummyComponent.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getGroupsView()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    return new ContentPanelAdapter(new GroupsView(viewContext), false);
-                }
-
-                public String getId()
-                {
-                    return GroupsView.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getRolesView()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    return new ContentPanelAdapter(new RolesView(viewContext), false);
-                }
-
-                public String getId()
-                {
-                    return RolesView.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getPersonsView()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    return new ContentPanelAdapter(new PersonsView(viewContext), false);
-                }
-
-                public String getId()
-                {
-                    return PersonsView.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getSampleRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new SampleRegistrationPanel(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.SAMPLE_REGISTRATION), component, true);
-                }
-
-                public String getId()
-                {
-                    return SampleRegistrationPanel.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getExperimentRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new ExperimentRegistrationPanel(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.EXPERIMENT_REGISTRATION), component,
-                            true);
-                }
-
-                public String getId()
-                {
-                    return ExperimentRegistrationPanel.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getSampleBatchRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new SampleBatchRegistrationPanel(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.SAMPLE_BATCH_REGISTRATION),
-                            component, true);
-                }
-
-                public String getId()
-                {
-                    return SampleBatchRegistrationPanel.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getMaterialBatchRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new MaterialBatchRegistrationPanel(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.MATERIAL_IMPORT), component, true);
-                }
-
-                public String getId()
-                {
-                    return MaterialBatchRegistrationPanel.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getVocabularyRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new VocabularyRegistrationForm(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.VOCABULARY_REGISTRATION), component,
-                            true);
-                }
-
-                public String getId()
-                {
-                    return VocabularyRegistrationForm.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getProjectRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new ProjectRegistrationForm(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.PROJECT_REGISTRATION), component,
-                            true);
-                }
-
-                public String getId()
-                {
-                    return ProjectRegistrationForm.ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getVocabularyBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = VocabularyGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.VOCABULARY_BROWSER), component);
-                }
-
-                public String getId()
-                {
-                    return VocabularyGrid.GRID_ID;
-                }
-            };
-    }
-
-    public final ITabItemFactory getProjectBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = ProjectGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.PROJECT_BROWSER), component);
-                }
-
-                public String getId()
-                {
-                    return ProjectGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getExperimentBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent browser = ExperimentBrowserGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.EXPERIMENT_BROWSER), browser);
-                }
-
-                public String getId()
-                {
-                    return ExperimentBrowserGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getPropertyTypeBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = PropertyTypeGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.PROPERTY_TYPES), component);
-                }
-
-                public String getId()
-                {
-                    return PropertyTypeGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getPropertyTypeRegistration()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new PropertyTypeRegistrationForm(viewContext);
-                    return new DefaultTabItem(getMessage(Dict.PROPERTY_TYPE_REGISTRATION),
-                            component, true);
-                }
-
-                public String getId()
-                {
-                    return PropertyTypeRegistrationForm.ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getPropertyTypeAssignmentBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = PropertyTypeAssignmentGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.PROPERTY_TYPE_ASSIGNMENTS),
-                            component);
-                }
-
-                public String getId()
-                {
-                    return PropertyTypeAssignmentGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getPropertyTypeExperimentTypeAssignmentForm()
-    {
-        return getPropertyTypeAssignmentForm(EntityKind.EXPERIMENT,
-                Dict.ASSIGN_EXPERIMENT_PROPERTY_TYPE);
-    }
-
-    public ITabItemFactory getPropertyTypeSampleTypeAssignmentForm()
-    {
-        return getPropertyTypeAssignmentForm(EntityKind.SAMPLE, Dict.ASSIGN_SAMPLE_PROPERTY_TYPE);
-    }
-
-    private ITabItemFactory getPropertyTypeAssignmentForm(final EntityKind entityKind,
-            final String messageKey)
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    Component component = new PropertyTypeAssignmentForm(viewContext, entityKind);
-                    return new DefaultTabItem(getMessage(messageKey), component, true);
-                }
-
-                public String getId()
-                {
-                    return PropertyTypeAssignmentForm.createId(entityKind);
-                }
-            };
-    }
-
-    public ITabItemFactory getDataSetSearch()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent browser = DataSetSearchHitGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.DATA_SET_SEARCH), browser);
-                }
-
-                public String getId()
-                {
-                    return DataSetSearchHitGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getSampleTypeBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = SampleTypeGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.SAMPLE_TYPES), component);
-                }
-
-                public String getId()
-                {
-                    return SampleTypeGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getMaterialTypeBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = MaterialTypeGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.MATERIAL_TYPES), component);
-                }
-
-                public String getId()
-                {
-                    return MaterialTypeGrid.BROWSER_ID;
-                }
-            };
-    }
-
-    public ITabItemFactory getExperimentTypeBrowser()
-    {
-        return new ITabItemFactory()
-            {
-                public ITabItem create()
-                {
-                    DisposableComponent component = ExperimentTypeGrid.create(viewContext);
-                    return DefaultTabItem.create(getMessage(Dict.EXPERIMENT_TYPES), component);
-                }
-
-                public String getId()
-                {
-                    return ExperimentTypeGrid.BROWSER_ID;
-                }
-            };
-    }
+public final class ComponentProvider {
+	private final CommonViewContext viewContext;
+
+	ComponentProvider(final CommonViewContext viewContext) {
+		this.viewContext = viewContext;
+	}
+
+	private String getMessage(String key) {
+		return viewContext.getMessage(key);
+	}
+
+	public final ITabItemFactory getSampleBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent browser = SampleBrowserGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.SAMPLE_BROWSER),
+						browser);
+			}
+
+			public String getId() {
+				return SampleBrowserGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getMaterialBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent browser = MaterialBrowserGrid
+						.createWithTypeChooser(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.MATERIAL_BROWSER),
+						browser);
+			}
+
+			public String getId() {
+				return MaterialBrowserGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getDummyComponent() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				return new DefaultTabItem(getMessage(Dict.NOT_IMPLEMENTED),
+						new DummyComponent(), false);
+			}
+
+			public String getId() {
+				return DummyComponent.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getGroupsView() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				return new ContentPanelAdapter(new GroupsView(viewContext),
+						false);
+			}
+
+			public String getId() {
+				return GroupsView.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getRolesView() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				return new ContentPanelAdapter(new RolesView(viewContext),
+						false);
+			}
+
+			public String getId() {
+				return RolesView.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getPersonsView() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				return new ContentPanelAdapter(new PersonsView(viewContext),
+						false);
+			}
+
+			public String getId() {
+				return PersonsView.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getSampleRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new SampleRegistrationPanel(viewContext);
+				return new DefaultTabItem(getMessage(Dict.SAMPLE_REGISTRATION),
+						component, true);
+			}
+
+			public String getId() {
+				return SampleRegistrationPanel.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getExperimentRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new ExperimentRegistrationPanel(
+						viewContext);
+				return new DefaultTabItem(
+						getMessage(Dict.EXPERIMENT_REGISTRATION), component,
+						true);
+			}
+
+			public String getId() {
+				return ExperimentRegistrationPanel.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getSampleBatchRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new SampleBatchRegistrationPanel(
+						viewContext);
+				return new DefaultTabItem(
+						getMessage(Dict.SAMPLE_BATCH_REGISTRATION), component,
+						true);
+			}
+
+			public String getId() {
+				return SampleBatchRegistrationPanel.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getMaterialBatchRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new MaterialBatchRegistrationPanel(
+						viewContext);
+				return new DefaultTabItem(getMessage(Dict.MATERIAL_IMPORT),
+						component, true);
+			}
+
+			public String getId() {
+				return MaterialBatchRegistrationPanel.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getVocabularyRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new VocabularyRegistrationForm(
+						viewContext);
+				return new DefaultTabItem(
+						getMessage(Dict.VOCABULARY_REGISTRATION), component,
+						true);
+			}
+
+			public String getId() {
+				return VocabularyRegistrationForm.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getProjectRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new ProjectRegistrationForm(viewContext);
+				return new DefaultTabItem(
+						getMessage(Dict.PROJECT_REGISTRATION), component, true);
+			}
+
+			public String getId() {
+				return ProjectRegistrationForm.ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getVocabularyBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = VocabularyGrid
+						.create(viewContext);
+				return DefaultTabItem.create(
+						getMessage(Dict.VOCABULARY_BROWSER), component);
+			}
+
+			public String getId() {
+				return VocabularyGrid.GRID_ID;
+			}
+		};
+	}
+
+	public final ITabItemFactory getProjectBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = ProjectGrid.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.PROJECT_BROWSER),
+						component);
+			}
+
+			public String getId() {
+				return ProjectGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getExperimentBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent browser = ExperimentBrowserGrid
+						.create(viewContext);
+				return DefaultTabItem.create(
+						getMessage(Dict.EXPERIMENT_BROWSER), browser);
+			}
+
+			public String getId() {
+				return ExperimentBrowserGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getPropertyTypeBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = PropertyTypeGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.PROPERTY_TYPES),
+						component);
+			}
+
+			public String getId() {
+				return PropertyTypeGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getPropertyTypeRegistration() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new PropertyTypeRegistrationForm(
+						viewContext);
+				return new DefaultTabItem(
+						getMessage(Dict.PROPERTY_TYPE_REGISTRATION), component,
+						true);
+			}
+
+			public String getId() {
+				return PropertyTypeRegistrationForm.ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getPropertyTypeAssignmentBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = PropertyTypeAssignmentGrid
+						.create(viewContext);
+				return DefaultTabItem.create(
+						getMessage(Dict.PROPERTY_TYPE_ASSIGNMENTS), component);
+			}
+
+			public String getId() {
+				return PropertyTypeAssignmentGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getPropertyTypeExperimentTypeAssignmentForm() {
+		return getPropertyTypeAssignmentForm(EntityKind.EXPERIMENT,
+				Dict.ASSIGN_EXPERIMENT_PROPERTY_TYPE);
+	}
+
+	public ITabItemFactory getPropertyTypeMaterialTypeAssignmentForm() {
+		return getPropertyTypeAssignmentForm(EntityKind.MATERIAL,
+				Dict.ASSIGN_MATERIAL_PROPERTY_TYPE);
+	}
+
+	public ITabItemFactory getPropertyTypeDataSetTypeAssignmentForm() {
+		return getPropertyTypeAssignmentForm(EntityKind.DATA_SET,
+				Dict.ASSIGN_DATA_SET_PROPERTY_TYPE);
+	}
+
+	public ITabItemFactory getPropertyTypeSampleTypeAssignmentForm() {
+		return getPropertyTypeAssignmentForm(EntityKind.SAMPLE,
+				Dict.ASSIGN_SAMPLE_PROPERTY_TYPE);
+	}
+
+	private ITabItemFactory getPropertyTypeAssignmentForm(
+			final EntityKind entityKind, final String messageKey) {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				Component component = new PropertyTypeAssignmentForm(
+						viewContext, entityKind);
+				return new DefaultTabItem(getMessage(messageKey), component,
+						true);
+			}
+
+			public String getId() {
+				return PropertyTypeAssignmentForm.createId(entityKind);
+			}
+		};
+	}
+
+	public ITabItemFactory getDataSetSearch() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent browser = DataSetSearchHitGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.DATA_SET_SEARCH),
+						browser);
+			}
+
+			public String getId() {
+				return DataSetSearchHitGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getSampleTypeBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = SampleTypeGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.SAMPLE_TYPES),
+						component);
+			}
+
+			public String getId() {
+				return SampleTypeGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getMaterialTypeBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = MaterialTypeGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.MATERIAL_TYPES),
+						component);
+			}
+
+			public String getId() {
+				return MaterialTypeGrid.BROWSER_ID;
+			}
+		};
+	}
+
+	public ITabItemFactory getExperimentTypeBrowser() {
+		return new ITabItemFactory() {
+			public ITabItem create() {
+				DisposableComponent component = ExperimentTypeGrid
+						.create(viewContext);
+				return DefaultTabItem.create(getMessage(Dict.EXPERIMENT_TYPES),
+						component);
+			}
+
+			public String getId() {
+				return ExperimentTypeGrid.BROWSER_ID;
+			}
+		};
+	}
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
index 2e77a6f83437e890eefafde58db4c38b35ff38ed..2ae4229efa8d5c58ee4dee7958a019f15a17b495 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
@@ -16,18 +16,6 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.menu;
 
-import com.extjs.gxt.ui.client.event.ComponentEvent;
-import com.extjs.gxt.ui.client.event.SelectionListener;
-import com.extjs.gxt.ui.client.widget.Html;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
-import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
-import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
-import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
-import com.extjs.gxt.ui.client.widget.toolbar.TextToolItem;
-import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
-import com.google.gwt.user.client.Element;
-
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.CommonViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
@@ -43,6 +31,18 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMess
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.User;
 
+import com.extjs.gxt.ui.client.event.ComponentEvent;
+import com.extjs.gxt.ui.client.event.SelectionListener;
+import com.extjs.gxt.ui.client.widget.Html;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
+import com.extjs.gxt.ui.client.widget.toolbar.AdapterToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.TextToolItem;
+import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
+import com.google.gwt.user.client.Element;
+
 /**
  * Implements functionality of the top menu.
  * 
@@ -76,7 +76,9 @@ public class TopMenu extends LayoutContainer
         PROJECT_MENU_BROWSE, PROJECT_MENU_NEW,
 
         PROPERTY_TYPES_MENU_BROWSE_PROPERTY_TYPES, PROPERTY_TYPES_MENU_BROWSE_ASSIGNMENTS,
-        PROPERTY_TYPES_MENU_NEW_PROPERTY_TYPES, PROPERTY_TYPES_MENU_ASSIGN_TO_EXPERIMENT_TYPE,
+        PROPERTY_TYPES_MENU_NEW_PROPERTY_TYPES, PROPERTY_TYPES_MENU_ASSIGN_TO_EXPERIMENT_TYPE, 
+        PROPERTY_TYPES_MENU_ASSIGN_TO_MATERIAL_TYPE,
+        PROPERTY_TYPES_MENU_ASSIGN_TO_DATA_SET_TYPE,
         PROPERTY_TYPES_MENU_ASSIGN_TO_SAMPLE_TYPE,
 
         VOCABULARY_MENU_BROWSE, VOCABULARY_MENU_NEW;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/administration/PropertyTypesMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/administration/PropertyTypesMenu.java
index e19c424edad1a9fa0c6020b19bfaca14a6437d25..ca22f406e3c392e5756d8a895da59b9c2d15dfe3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/administration/PropertyTypesMenu.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/administration/PropertyTypesMenu.java
@@ -48,6 +48,12 @@ public class PropertyTypesMenu extends MenuItem
         menu.add(new ActionMenu(
                 TopMenu.ActionMenuKind.PROPERTY_TYPES_MENU_ASSIGN_TO_EXPERIMENT_TYPE,
                 messageProvider, componentProvider.getPropertyTypeExperimentTypeAssignmentForm()));
+        menu.add(new ActionMenu(
+                TopMenu.ActionMenuKind.PROPERTY_TYPES_MENU_ASSIGN_TO_MATERIAL_TYPE,
+                messageProvider, componentProvider.getPropertyTypeMaterialTypeAssignmentForm()));
+        menu.add(new ActionMenu(
+                TopMenu.ActionMenuKind.PROPERTY_TYPES_MENU_ASSIGN_TO_DATA_SET_TYPE,
+                messageProvider, componentProvider.getPropertyTypeDataSetTypeAssignmentForm()));
         menu.add(new ActionMenu(TopMenu.ActionMenuKind.PROPERTY_TYPES_MENU_ASSIGN_TO_SAMPLE_TYPE,
                 messageProvider, componentProvider.getPropertyTypeSampleTypeAssignmentForm()));
         setSubMenu(menu);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/DataSetTypeModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/DataSetTypeModel.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee22e03243cb5ca0cb13533b6424f4f7db19de38
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/DataSetTypeModel.java
@@ -0,0 +1,53 @@
+/*
+ * 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.client.web.client.application.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.extjs.gxt.ui.client.data.BaseModelData;
+import com.extjs.gxt.ui.client.data.ModelData;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+
+/**
+ * {@link ModelData} for {@link DataSetType}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DataSetTypeModel extends BaseModelData
+{
+
+    private static final long serialVersionUID = 1L;
+
+    public DataSetTypeModel(final DataSetType dataSetType)
+    {
+        set(ModelDataPropertyNames.CODE, dataSetType.getCode());
+        set(ModelDataPropertyNames.OBJECT, dataSetType);
+    }
+
+    public final static List<DataSetTypeModel> convert(final List<DataSetType> dataSetTypes)
+    {
+        final List<DataSetTypeModel> result = new ArrayList<DataSetTypeModel>();
+        for (final DataSetType st : dataSetTypes)
+        {
+            result.add(new DataSetTypeModel(st));
+        }
+        return result;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..53cafc3c3b265a817996f6e1ec4347baef30b703
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetTypeSelectionWidget.java
@@ -0,0 +1,69 @@
+/*
+ * 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.client.web.client.application.ui.data;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.DataSetTypeModel;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.ModelDataPropertyNames;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.DropDownList;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+
+import com.extjs.gxt.ui.client.widget.form.ComboBox;
+
+/**
+ * {@link ComboBox} containing list of data set types loaded from the server.
+ * 
+ * @author Izabela Adamczyk
+ */
+public final class DataSetTypeSelectionWidget extends
+		DropDownList<DataSetTypeModel, DataSetType> {
+	public static final String SUFFIX = "data-set-type";
+
+	private final IViewContext<ICommonClientServiceAsync> viewContext;
+
+	public DataSetTypeSelectionWidget(
+			final IViewContext<ICommonClientServiceAsync> viewContext,
+			final String idSuffix) {
+		super(viewContext, SUFFIX + idSuffix, Dict.DATA_SET_TYPE,
+				ModelDataPropertyNames.CODE, "data set type", "data set types");
+		this.viewContext = viewContext;
+	}
+
+	/**
+	 * Returns the {@link DataSetType} currently selected.
+	 * 
+	 * @return <code>null</code> if nothing is selected yet.
+	 */
+	public final DataSetType tryGetSelectedDataSetType() {
+		return super.tryGetSelected();
+	}
+
+	@Override
+	protected List<DataSetTypeModel> convertItems(List<DataSetType> result) {
+		return DataSetTypeModel.convert(result);
+	}
+
+	@Override
+	protected void loadData(AbstractAsyncCallback<List<DataSetType>> callback) {
+		viewContext.getService().listDataSetTypes(callback);
+	}
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java
index b9b45284afecf396fdbfc05ca5cb309e6e8d5637..477b7f569bd0a4164a477ca4dc79cb90a3287336 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/property_type/PropertyTypeAssignmentForm.java
@@ -16,6 +16,23 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm.InfoBoxResetListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetTypeSelectionWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentTypeSelectionWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.PropertyFieldFactory;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialTypeSelectionWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleTypeSelectionWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.InfoBox;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+
 import com.extjs.gxt.ui.client.Events;
 import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
 import com.extjs.gxt.ui.client.Style.Scroll;
@@ -32,292 +49,289 @@ import com.extjs.gxt.ui.client.widget.form.FormPanel;
 import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
 import com.google.gwt.user.client.Element;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCallbackListener;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm.InfoBoxResetListener;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.ExperimentTypeSelectionWidget;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.PropertyFieldFactory;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.sample.SampleTypeSelectionWidget;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.InfoBox;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
-
 /**
  * The property type assignment panel.
  * 
  * @author Izabela Adamczyk
  */
-public final class PropertyTypeAssignmentForm extends LayoutContainer
-{
-    private static final String UNSUPPORTED_ENTITY_KIND = "Unsupported entity kind";
-
-    private static final int LABEL_WIDTH = 130;
-
-    private static final int FIELD_WIDTH = 400;
-
-    private static final String PREFIX = "property-type-assignment_";
-
-    public static final String ID_PREFIX = GenericConstants.ID_PREFIX + PREFIX;
-
-    public static final String PROPERTY_TYPE_ID_SUFFIX = "property_type";
-
-    public static final String SAMPLE_TYPE_ID_SUFFIX = ID_PREFIX + "sample_type";
-
-    public static final String EXPERIMENT_TYPE_ID_SUFFIX = ID_PREFIX + "experiment_type";
-
-    public static final String MANDATORY_CHECKBOX_ID_SUFFIX = "mandatory_checkbox";
-
-    public static final String SAVE_BUTTON_ID_SUFFIX = "save-button";
-
-    protected static final String DEFAULT_VALUE_ID_PART = "default_value";
-
-    private final IViewContext<ICommonClientServiceAsync> viewContext;
-
-    private SampleTypeSelectionWidget sampleTypeSelectionWidget;
-
-    private ExperimentTypeSelectionWidget experimentTypeSelectionWidget;
-
-    private PropertyTypeSelectionWidget propertyTypeSelectionWidget;
-
-    private Field<?> defaultValueField;
-
-    private CheckBox mandatoryCheckbox;
-
-    private final InfoBox infoBox;
-
-    private final FormPanel formPanel;
-
-    private final EntityKind entityKind;
-
-    public PropertyTypeAssignmentForm(final IViewContext<ICommonClientServiceAsync> viewContext,
-            EntityKind entityKind)
-    {
-        this.entityKind = entityKind;
-        setLayout(new FlowLayout(5));
-        setId(createId(entityKind));
-        this.viewContext = viewContext;
-        setScrollMode(Scroll.AUTO);
-        add(infoBox = createInfoBox());
-        add(formPanel = createFormPanel());
-    }
-
-    public static final String createId(EntityKind entityKind)
-    {
-        return ID_PREFIX + entityKind.name();
-    }
-
-    private String createChildId(String childSuffix)
-    {
-        return getId() + childSuffix;
-    }
-
-    private final static InfoBox createInfoBox()
-    {
-        final InfoBox infoBox = new InfoBox();
-        return infoBox;
-    }
-
-    private PropertyTypeSelectionWidget getPropertyTypeWidget()
-    {
-        if (propertyTypeSelectionWidget == null)
-        {
-            propertyTypeSelectionWidget =
-                    new PropertyTypeSelectionWidget(viewContext,
-                            createChildId(PROPERTY_TYPE_ID_SUFFIX));
-            propertyTypeSelectionWidget
-                    .addListener(Events.Focus, new InfoBoxResetListener(infoBox));
-            FieldUtil.markAsMandatory(propertyTypeSelectionWidget);
-            propertyTypeSelectionWidget.addListener(Events.SelectionChange,
-                    new Listener<BaseEvent>()
-                        {
-                            public void handleEvent(BaseEvent be)
-                            {
-                                updateDefaultField();
-                            }
-                        });
-        }
-        return propertyTypeSelectionWidget;
-    }
-
-    private ComboBox<?> getTypeSelectionWidget()
-    {
-        switch (entityKind)
-        {
-            case EXPERIMENT:
-                if (experimentTypeSelectionWidget == null)
-                {
-                    experimentTypeSelectionWidget =
-                            new ExperimentTypeSelectionWidget(viewContext,
-                                    EXPERIMENT_TYPE_ID_SUFFIX);
-                    experimentTypeSelectionWidget.addListener(Events.Focus,
-                            new InfoBoxResetListener(infoBox));
-                    FieldUtil.markAsMandatory(experimentTypeSelectionWidget);
-                }
-                return experimentTypeSelectionWidget;
-            case SAMPLE:
-                if (sampleTypeSelectionWidget == null)
-                {
-                    sampleTypeSelectionWidget =
-                            new SampleTypeSelectionWidget(viewContext, SAMPLE_TYPE_ID_SUFFIX, false);
-                    sampleTypeSelectionWidget.addListener(Events.Focus, new InfoBoxResetListener(
-                            infoBox));
-                    FieldUtil.markAsMandatory(sampleTypeSelectionWidget);
-                }
-                return sampleTypeSelectionWidget;
-            default:
-                throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND);
-        }
-    }
-
-    private CheckBox getMandatoryCheckbox()
-    {
-        if (mandatoryCheckbox == null)
-        {
-            mandatoryCheckbox = new CheckBox();
-            mandatoryCheckbox.setId(createChildId(MANDATORY_CHECKBOX_ID_SUFFIX));
-            mandatoryCheckbox.setFieldLabel(viewContext.getMessage(Dict.MANDATORY));
-            mandatoryCheckbox.setValue(false);
-            mandatoryCheckbox.addListener(Events.Change, new InfoBoxResetListener(infoBox));
-        }
-        return mandatoryCheckbox;
-    }
-
-    private final FormPanel createFormPanel()
-    {
-        final FormPanel panel = new FormPanel();
-        panel.setHeaderVisible(false);
-        panel.setBodyBorder(false);
-        panel.setWidth(LABEL_WIDTH + FIELD_WIDTH + 40);
-        panel.setLabelWidth(LABEL_WIDTH);
-        panel.setFieldWidth(FIELD_WIDTH);
-        panel.setButtonAlign(HorizontalAlignment.RIGHT);
-        final Button saveButton = new Button(viewContext.getMessage(Dict.BUTTON_SAVE));
-        saveButton.setStyleAttribute("marginRight", "20px");
-        saveButton.setId(createChildId(SAVE_BUTTON_ID_SUFFIX));
-        saveButton.addSelectionListener(new SelectionListener<ButtonEvent>()
-            {
-                @Override
-                public final void componentSelected(final ButtonEvent ce)
-                {
-                    submitForm();
-                }
-            });
-        final Button resetButton = new Button(viewContext.getMessage(Dict.BUTTON_RESET));
-        resetButton.addSelectionListener(new SelectionListener<ButtonEvent>()
-            {
-                @Override
-                public final void componentSelected(final ButtonEvent ce)
-                {
-                    resetForm();
-                }
-            });
-        panel.addButton(resetButton);
-        panel.addButton(saveButton);
-        return panel;
-    }
-
-    private String getDefaultValue()
-    {
-        if (defaultValueField != null)
-        {
-            return PropertyFieldFactory.valueToString(defaultValueField.getValue());
-        }
-        return null;
-    }
-
-    private String getSelectedEntityCode()
-    {
-        switch (entityKind)
-        {
-            case EXPERIMENT:
-                return experimentTypeSelectionWidget.tryGetSelectedExperimentType().getCode();
-            case SAMPLE:
-                return sampleTypeSelectionWidget.tryGetSelectedSampleType().getCode();
-            default:
-                throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND);
-        }
-    }
-
-    private final void addFormFields()
-    {
-        formPanel.add(getPropertyTypeWidget());
-        formPanel.add(getTypeSelectionWidget());
-        formPanel.add(getMandatoryCheckbox());
-        updateDefaultField();
-    }
-
-    @Override
-    protected final void onRender(final Element target, final int index)
-    {
-        super.onRender(target, index);
-        addFormFields();
-    }
-
-    public final class AssignPropertyTypeCallback extends AbstractAsyncCallback<String>
-    {
-        AssignPropertyTypeCallback(final IViewContext<?> viewContext)
-        {
-            super(viewContext, new InfoBoxCallbackListener<String>(infoBox));
-        }
-
-        @Override
-        protected final void process(final String result)
-        {
-            infoBox.displayInfo(result);
-            resetForm();
-        }
-    }
-
-    private void updateDefaultField()
-    {
-        hideDefaultField();
-        final PropertyType propertyType = propertyTypeSelectionWidget.tryGetSelectedPropertyType();
-        if (propertyType != null)
-        {
-            String fieldId =
-                    createChildId(DEFAULT_VALUE_ID_PART + propertyType.isInternalNamespace()
-                            + propertyType.getSimpleCode());
-            Field<?> field =
-                    PropertyFieldFactory.createField(propertyType, false, viewContext
-                            .getMessage(Dict.DEFAULT_VALUE), fieldId, null, viewContext);
-            field.setToolTip(viewContext.getMessage(Dict.DEFAULT_VALUE_TOOLTIP));
-            defaultValueField = field;
-            defaultValueField.show();
-            formPanel.add(defaultValueField);
-        }
-        layout();
-    }
-
-    private void hideDefaultField()
-    {
-        if (defaultValueField != null)
-        {
-            defaultValueField.hide();
-            formPanel.remove(defaultValueField);
-            defaultValueField = null;
-        }
-    }
-
-    private final void submitForm()
-    {
-        if (formPanel.isValid())
-        {
-            viewContext.getService().assignPropertyType(entityKind,
-                    propertyTypeSelectionWidget.tryGetSelectedPropertyTypeCode(),
-                    getSelectedEntityCode(), getMandatoryCheckbox().getValue(), getDefaultValue(),
-                    new AssignPropertyTypeCallback(viewContext));
-        }
-    }
-
-    private void resetForm()
-    {
-        formPanel.reset();
-        updateDefaultField();
-    }
+public final class PropertyTypeAssignmentForm extends LayoutContainer {
+	private static final String UNSUPPORTED_ENTITY_KIND = "Unsupported entity kind";
+
+	private static final int LABEL_WIDTH = 130;
+
+	private static final int FIELD_WIDTH = 400;
+
+	private static final String PREFIX = "property-type-assignment_";
+
+	public static final String ID_PREFIX = GenericConstants.ID_PREFIX + PREFIX;
+
+	public static final String PROPERTY_TYPE_ID_SUFFIX = "property_type";
+
+	public static final String SAMPLE_TYPE_ID_SUFFIX = ID_PREFIX
+			+ "sample_type";
+
+	public static final String EXPERIMENT_TYPE_ID_SUFFIX = ID_PREFIX
+			+ "experiment_type";
+
+	public static final String MATERIAL_TYPE_ID_SUFFIX = ID_PREFIX
+			+ "material_type";
+
+	public static final String DATA_SET_TYPE_ID_SUFFIX = ID_PREFIX
+			+ "data_set_type";
+
+	public static final String MANDATORY_CHECKBOX_ID_SUFFIX = "mandatory_checkbox";
+
+	public static final String SAVE_BUTTON_ID_SUFFIX = "save-button";
+
+	protected static final String DEFAULT_VALUE_ID_PART = "default_value";
+
+	private final IViewContext<ICommonClientServiceAsync> viewContext;
+
+	private SampleTypeSelectionWidget sampleTypeSelectionWidget;
+
+	private ExperimentTypeSelectionWidget experimentTypeSelectionWidget;
+
+	private MaterialTypeSelectionWidget materialTypeSelectionWidget;
+
+	private DataSetTypeSelectionWidget dataSetTypeSelectionWidget;
+
+	private PropertyTypeSelectionWidget propertyTypeSelectionWidget;
+
+	private Field<?> defaultValueField;
+
+	private CheckBox mandatoryCheckbox;
+
+	private final InfoBox infoBox;
+
+	private final FormPanel formPanel;
+
+	private final EntityKind entityKind;
+
+	public PropertyTypeAssignmentForm(
+			final IViewContext<ICommonClientServiceAsync> viewContext,
+			EntityKind entityKind) {
+		this.entityKind = entityKind;
+		setLayout(new FlowLayout(5));
+		setId(createId(entityKind));
+		this.viewContext = viewContext;
+		setScrollMode(Scroll.AUTO);
+		add(infoBox = createInfoBox());
+		add(formPanel = createFormPanel());
+	}
+
+	public static final String createId(EntityKind entityKind) {
+		return ID_PREFIX + entityKind.name();
+	}
+
+	private String createChildId(String childSuffix) {
+		return getId() + childSuffix;
+	}
+
+	private final static InfoBox createInfoBox() {
+		final InfoBox infoBox = new InfoBox();
+		return infoBox;
+	}
+
+	private PropertyTypeSelectionWidget getPropertyTypeWidget() {
+		if (propertyTypeSelectionWidget == null) {
+			propertyTypeSelectionWidget = new PropertyTypeSelectionWidget(
+					viewContext, createChildId(PROPERTY_TYPE_ID_SUFFIX));
+			propertyTypeSelectionWidget.addListener(Events.Focus,
+					new InfoBoxResetListener(infoBox));
+			FieldUtil.markAsMandatory(propertyTypeSelectionWidget);
+			propertyTypeSelectionWidget.addListener(Events.SelectionChange,
+					new Listener<BaseEvent>() {
+						public void handleEvent(BaseEvent be) {
+							updateDefaultField();
+						}
+					});
+		}
+		return propertyTypeSelectionWidget;
+	}
+
+	private ComboBox<?> getTypeSelectionWidget() {
+		switch (entityKind) {
+		case EXPERIMENT:
+			if (experimentTypeSelectionWidget == null) {
+				experimentTypeSelectionWidget = new ExperimentTypeSelectionWidget(
+						viewContext, EXPERIMENT_TYPE_ID_SUFFIX);
+				experimentTypeSelectionWidget.addListener(Events.Focus,
+						new InfoBoxResetListener(infoBox));
+				FieldUtil.markAsMandatory(experimentTypeSelectionWidget);
+			}
+			return experimentTypeSelectionWidget;
+		case SAMPLE:
+			if (sampleTypeSelectionWidget == null) {
+				sampleTypeSelectionWidget = new SampleTypeSelectionWidget(
+						viewContext, SAMPLE_TYPE_ID_SUFFIX, false);
+				sampleTypeSelectionWidget.addListener(Events.Focus,
+						new InfoBoxResetListener(infoBox));
+				FieldUtil.markAsMandatory(sampleTypeSelectionWidget);
+			}
+			return sampleTypeSelectionWidget;
+		case MATERIAL:
+			if (materialTypeSelectionWidget == null) {
+				materialTypeSelectionWidget = new MaterialTypeSelectionWidget(
+						viewContext, MATERIAL_TYPE_ID_SUFFIX);
+				materialTypeSelectionWidget.addListener(Events.Focus,
+						new InfoBoxResetListener(infoBox));
+				FieldUtil.markAsMandatory(materialTypeSelectionWidget);
+			}
+			return materialTypeSelectionWidget;
+		case DATA_SET:
+			if (dataSetTypeSelectionWidget == null) {
+				dataSetTypeSelectionWidget = new DataSetTypeSelectionWidget(
+						viewContext, DATA_SET_TYPE_ID_SUFFIX);
+				dataSetTypeSelectionWidget.addListener(Events.Focus,
+						new InfoBoxResetListener(infoBox));
+				FieldUtil.markAsMandatory(dataSetTypeSelectionWidget);
+			}
+			return dataSetTypeSelectionWidget;
+		}
+		throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND);
+	}
+
+	private CheckBox getMandatoryCheckbox() {
+		if (mandatoryCheckbox == null) {
+			mandatoryCheckbox = new CheckBox();
+			mandatoryCheckbox
+					.setId(createChildId(MANDATORY_CHECKBOX_ID_SUFFIX));
+			mandatoryCheckbox.setFieldLabel(viewContext
+					.getMessage(Dict.MANDATORY));
+			mandatoryCheckbox.setValue(false);
+			mandatoryCheckbox.addListener(Events.Change,
+					new InfoBoxResetListener(infoBox));
+		}
+		return mandatoryCheckbox;
+	}
+
+	private final FormPanel createFormPanel() {
+		final FormPanel panel = new FormPanel();
+		panel.setHeaderVisible(false);
+		panel.setBodyBorder(false);
+		panel.setWidth(LABEL_WIDTH + FIELD_WIDTH + 40);
+		panel.setLabelWidth(LABEL_WIDTH);
+		panel.setFieldWidth(FIELD_WIDTH);
+		panel.setButtonAlign(HorizontalAlignment.RIGHT);
+		final Button saveButton = new Button(viewContext
+				.getMessage(Dict.BUTTON_SAVE));
+		saveButton.setStyleAttribute("marginRight", "20px");
+		saveButton.setId(createChildId(SAVE_BUTTON_ID_SUFFIX));
+		saveButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
+			@Override
+			public final void componentSelected(final ButtonEvent ce) {
+				submitForm();
+			}
+		});
+		final Button resetButton = new Button(viewContext
+				.getMessage(Dict.BUTTON_RESET));
+		resetButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
+			@Override
+			public final void componentSelected(final ButtonEvent ce) {
+				resetForm();
+			}
+		});
+		panel.addButton(resetButton);
+		panel.addButton(saveButton);
+		return panel;
+	}
+
+	private String getDefaultValue() {
+		if (defaultValueField != null) {
+			return PropertyFieldFactory.valueToString(defaultValueField
+					.getValue());
+		}
+		return null;
+	}
+
+	private String getSelectedEntityCode() {
+		switch (entityKind) {
+		case EXPERIMENT:
+			return experimentTypeSelectionWidget.tryGetSelectedExperimentType()
+					.getCode();
+		case SAMPLE:
+			return sampleTypeSelectionWidget.tryGetSelectedSampleType()
+					.getCode();
+		case MATERIAL:
+			return materialTypeSelectionWidget.tryGetSelectedMaterialType()
+					.getCode();
+		case DATA_SET:
+			return dataSetTypeSelectionWidget.tryGetSelectedDataSetType()
+					.getCode();
+		}
+		throw new IllegalArgumentException(UNSUPPORTED_ENTITY_KIND);
+	}
+
+	private final void addFormFields() {
+		formPanel.add(getPropertyTypeWidget());
+		formPanel.add(getTypeSelectionWidget());
+		formPanel.add(getMandatoryCheckbox());
+		updateDefaultField();
+	}
+
+	@Override
+	protected final void onRender(final Element target, final int index) {
+		super.onRender(target, index);
+		addFormFields();
+	}
+
+	public final class AssignPropertyTypeCallback extends
+			AbstractAsyncCallback<String> {
+		AssignPropertyTypeCallback(final IViewContext<?> viewContext) {
+			super(viewContext, new InfoBoxCallbackListener<String>(infoBox));
+		}
+
+		@Override
+		protected final void process(final String result) {
+			infoBox.displayInfo(result);
+			resetForm();
+		}
+	}
+
+	private void updateDefaultField() {
+		hideDefaultField();
+		final PropertyType propertyType = propertyTypeSelectionWidget
+				.tryGetSelectedPropertyType();
+		if (propertyType != null) {
+			String fieldId = createChildId(DEFAULT_VALUE_ID_PART
+					+ propertyType.isInternalNamespace()
+					+ propertyType.getSimpleCode());
+			Field<?> field = PropertyFieldFactory.createField(propertyType,
+					false, viewContext.getMessage(Dict.DEFAULT_VALUE), fieldId,
+					null, viewContext);
+			field
+					.setToolTip(viewContext
+							.getMessage(Dict.DEFAULT_VALUE_TOOLTIP));
+			defaultValueField = field;
+			defaultValueField.show();
+			formPanel.add(defaultValueField);
+		}
+		layout();
+	}
+
+	private void hideDefaultField() {
+		if (defaultValueField != null) {
+			defaultValueField.hide();
+			formPanel.remove(defaultValueField);
+			defaultValueField = null;
+		}
+	}
+
+	private final void submitForm() {
+		if (formPanel.isValid()) {
+			viewContext.getService().assignPropertyType(
+					entityKind,
+					propertyTypeSelectionWidget
+							.tryGetSelectedPropertyTypeCode(),
+					getSelectedEntityCode(), getMandatoryCheckbox().getValue(),
+					getDefaultValue(),
+					new AssignPropertyTypeCallback(viewContext));
+		}
+	}
+
+	private void resetForm() {
+		formPanel.reset();
+		updateDefaultField();
+	}
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index fd152a2624914fae8f0ba4641f085976bc20c544..35bd0fe7844f4eb455a007dd06ff0d34c8278172 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -52,6 +52,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.CacheManager
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IResultSetManager;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.DataSetTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.DtoConverters;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExperimentTranslator;
 import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExternalDataTranslator;
@@ -72,6 +73,7 @@ import ch.systemsx.cisd.openbis.generic.server.SessionConstants;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
@@ -92,6 +94,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentContentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
@@ -119,957 +122,875 @@ import ch.systemsx.cisd.openbis.plugin.AbstractClientService;
  * @author Franz-Josef Elmer
  */
 public final class CommonClientService extends AbstractClientService implements
-        ICommonClientService
-{
-    private final ICommonServer commonServer;
-
-    private final String dataStoreBaseURL;
-
-    public CommonClientService(final ICommonServer commonServer,
-            final IRequestContextProvider requestContextProvider, String dataStoreBaseURL)
-    {
-        super(requestContextProvider);
-        this.commonServer = commonServer;
-        this.dataStoreBaseURL = dataStoreBaseURL + "/" + DATA_STORE_SERVER_WEB_APPLICATION_NAME;
-    }
-
-    @Override
-    protected final IServer getServer()
-    {
-        return commonServer;
-    }
-
-    // ----------- export and listing with cache generic functionality
-
-    @SuppressWarnings("unchecked")
-    private final <K> IResultSetManager<K> getResultSetManager()
-    {
-        return (IResultSetManager<K>) getHttpSession().getAttribute(
-                SessionConstants.OPENBIS_RESULT_SET_MANAGER);
-    }
-
-    @SuppressWarnings("unchecked")
-    private final <T> CacheManager<String, T> getExportManager()
-    {
-        return (CacheManager<String, T>) getHttpSession().getAttribute(
-                SessionConstants.OPENBIS_EXPORT_MANAGER);
-    }
-
-    /**
-     * Returns and removes cached export criteria.
-     */
-    private final <T> TableExportCriteria<T> getAndRemoveExportCriteria(final String exportDataKey)
-    {
-        final CacheManager<String, TableExportCriteria<T>> exportManager = getExportManager();
-        final TableExportCriteria<T> exportCriteria = exportManager.tryGetData(exportDataKey);
-        assert exportCriteria != null : "No export criteria found at key " + exportDataKey;
-        getExportManager().removeData(exportDataKey);
-        return exportCriteria;
-    }
-
-    private final <T> List<T> fetchCachedEntities(final TableExportCriteria<T> exportCriteria)
-    {
-        final IResultSetManager<String> resultSetManager = getResultSetManager();
-        IResultSetConfig<String, T> resultSetConfig = createExportListCriteria(exportCriteria);
-        IOriginalDataProvider<T> dummyDataProvider = createDummyDataProvider();
-        final IResultSet<String, T> result =
-                resultSetManager.getResultSet(resultSetConfig, dummyDataProvider);
-        final ResultSet<T> entities = ResultSetTranslator.translate(result);
-        return entities.getList();
-    }
-
-    private static <T> IOriginalDataProvider<T> createDummyDataProvider()
-    {
-        return new IOriginalDataProvider<T>()
-            {
-                public List<T> getOriginalData() throws UserFailureException
-                {
-                    throw new IllegalStateException("Data not found in the cache");
-                }
-            };
-    }
-
-    private static <T> IResultSetConfig<String, T> createExportListCriteria(
-            final TableExportCriteria<T> exportCriteria)
-    {
-        final DefaultResultSetConfig<String, T> criteria = DefaultResultSetConfig.createFetchAll();
-        criteria.setSortInfo(exportCriteria.getSortInfo());
-        criteria.setFilterInfos(exportCriteria.getFilterInfos());
-        criteria.setResultSetKey(exportCriteria.getResultSetKey());
-        return criteria;
-    }
-
-    private <T> ResultSet<T> listEntities(final IResultSetConfig<String, T> criteria,
-            IOriginalDataProvider<T> dataProvider)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final IResultSetManager<String> resultSetManager = getResultSetManager();
-            final IResultSet<String, T> result =
-                    resultSetManager.getResultSet(criteria, dataProvider);
-            return ResultSetTranslator.translate(result);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    /**
-     * Assumes that preparation of the export ({@link #prepareExportSamples(TableExportCriteria)}
-     * has been invoked before and returned with an exportDataKey passed here as a parameter.
-     */
-    public final String getExportTable(final String exportDataKey, final String lineSeparator)
-    {
-        // NOTE: no generics in GWT
-        return getGenericExportTable(exportDataKey, lineSeparator);
-    }
-
-    private final <T> String getGenericExportTable(final String exportDataKey,
-            final String lineSeparator)
-    {
-        try
-        {
-            // Not directly needed but this refreshes the session.
-            getSessionToken();
-            final TableExportCriteria<T> exportCriteria = getAndRemoveExportCriteria(exportDataKey);
-            final List<T> entities = fetchCachedEntities(exportCriteria);
-            return TSVRenderer.createTable(entities, exportCriteria.getColumnDefs(), lineSeparator);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    private <T> String prepareExportEntities(TableExportCriteria<T> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            // Not directly needed but this refreshes the session.
-            getSessionToken();
-            final CacheManager<String, TableExportCriteria<T>> exportManager = getExportManager();
-            return exportManager.saveData(criteria);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void removeResultSet(final String resultSetKey)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            // Not directly needed but this refreshes the session.
-            getSessionToken();
-            getResultSetManager().removeResultSet(resultSetKey);
-        } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    // --------------- end export & listing
-
-    //
-    // IGenericClientService
-    //
-
-    public final List<Group> listGroups(final String databaseInstanceCode)
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final DatabaseInstanceIdentifier identifier =
-                    new DatabaseInstanceIdentifier(databaseInstanceCode);
-            final List<Group> result = new ArrayList<Group>();
-            final List<GroupPE> groups = commonServer.listGroups(sessionToken, identifier);
-            for (final GroupPE group : groups)
-            {
-                result.add(GroupTranslator.translate(group));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerGroup(final String groupCode, final String descriptionOrNull,
-            final String groupLeaderOrNull)
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerGroup(sessionToken, groupCode, descriptionOrNull,
-                    groupLeaderOrNull);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final List<Person> listPersons()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<Person> result = new ArrayList<Person>();
-            final List<PersonPE> persons = commonServer.listPersons(sessionToken);
-            for (final PersonPE person : persons)
-            {
-                result.add(PersonTranslator.translate(person));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerPerson(final String code)
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerPerson(sessionToken, code);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final List<RoleAssignment> listRoles()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<RoleAssignment> result = new ArrayList<RoleAssignment>();
-            final List<RoleAssignmentPE> roles = commonServer.listRoles(sessionToken);
-            for (final RoleAssignmentPE role : roles)
-            {
-                result.add(RoleAssignmentTranslator.translate(role));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerGroupRole(final RoleSetCode roleSetCode, final String group,
-            final String person)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final GroupIdentifier groupIdentifier =
-                    new GroupIdentifier(DatabaseInstanceIdentifier.HOME, group);
-            commonServer.registerGroupRole(sessionToken, RoleCodeTranslator.translate(roleSetCode),
-                    groupIdentifier, person);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerInstanceRole(final RoleSetCode roleSetCode, final String person)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerInstanceRole(sessionToken, RoleCodeTranslator
-                    .translate(roleSetCode), person);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void deleteGroupRole(final RoleSetCode roleSetCode, final String group,
-            final String person)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final GroupIdentifier groupIdentifier =
-                    new GroupIdentifier(DatabaseInstanceIdentifier.HOME, group);
-            commonServer.deleteGroupRole(sessionToken, RoleCodeTranslator.translate(roleSetCode),
-                    groupIdentifier, person);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-
-    }
-
-    public final void deleteInstanceRole(final RoleSetCode roleSetCode, final String person)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.deleteInstanceRole(sessionToken,
-                    RoleCodeTranslator.translate(roleSetCode), person);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-
-    }
-
-    public final List<SampleType> listSampleTypes()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<SampleTypePE> sampleTypes = commonServer.listSampleTypes(sessionToken);
-            final List<SampleType> result = new ArrayList<SampleType>();
-            for (final SampleTypePE sampleTypePE : sampleTypes)
-            {
-                result.add(SampleTypeTranslator.translate(sampleTypePE));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    // --------- methods preparing exported content. Note: GWT does not support generic methods :(
-
-    public final String prepareExportSamples(final TableExportCriteria<Sample> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public final String prepareExportExperiments(final TableExportCriteria<Experiment> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public final String prepareExportMatchingEntities(
-            final TableExportCriteria<MatchingEntity> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportPropertyTypes(TableExportCriteria<PropertyType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportPropertyTypeAssignments(
-            TableExportCriteria<EntityTypePropertyType<?>> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportProjects(TableExportCriteria<Project> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportVocabularies(final TableExportCriteria<Vocabulary> criteria)
-            throws UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportVocabularyTerms(TableExportCriteria<VocabularyTermWithStats> criteria)
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportMaterialTypes(final TableExportCriteria<MaterialType> criteria)
-            throws UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportExperimentTypes(final TableExportCriteria<ExperimentType> criteria)
-            throws UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public String prepareExportSampleTypes(final TableExportCriteria<SampleType> criteria)
-            throws UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    // ---------------- methods which list entities using cache
-
-    public final ResultSet<Sample> listSamples(final ListSampleCriteria listCriteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        final String sessionToken = getSessionToken();
-        return listEntities(listCriteria, new ListSamplesOriginalDataProvider(commonServer,
-                sessionToken, listCriteria));
-    }
-
-    public ResultSet<ExternalData> searchForDataSets(DataSetSearchCriteria criteria,
-            final IResultSetConfig<String, ExternalData> resultSetConfig)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        final String sessionToken = getSessionToken();
-        return listEntities(resultSetConfig, new ListDataSetsOriginalDataProvider(commonServer,
-                sessionToken, criteria, dataStoreBaseURL));
-    }
-
-    public final ResultSet<Experiment> listExperiments(final ListExperimentsCriteria listCriteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        final String sessionToken = getSessionToken();
-        return listEntities(listCriteria, new ListExperimentsOriginalDataProvider(commonServer,
-                listCriteria, sessionToken));
-    }
-
-    public ResultSet<PropertyType> listPropertyTypes(
-            DefaultResultSetConfig<String, PropertyType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<PropertyType>()
-            {
-                public List<PropertyType> getOriginalData() throws UserFailureException
-                {
-                    return listPropertyTypes();
-                }
-            });
-    }
-
-    public final ResultSet<MatchingEntity> listMatchingEntities(
-            final SearchableEntity searchableEntityOrNull, final String queryText,
-            final IResultSetConfig<String, MatchingEntity> resultSetConfig)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        final String sessionToken = getSessionToken();
-        final ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity[] matchingEntities =
-                SearchableEntityTranslator.translate(searchableEntityOrNull);
-        return listEntities(resultSetConfig, new ListMatchingEntitiesOriginalDataProvider(
-                commonServer, sessionToken, matchingEntities, queryText));
-    }
-
-    public ResultSet<EntityTypePropertyType<?>> listPropertyTypeAssignments(
-            DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria)
-    {
-        return listEntities(criteria, new IOriginalDataProvider<EntityTypePropertyType<?>>()
-            {
-                public List<EntityTypePropertyType<?>> getOriginalData()
-                        throws UserFailureException
-                {
-                    return extractAssignments(listPropertyTypes());
-                }
-            });
-    }
-
-    private static List<EntityTypePropertyType<?>> extractAssignments(
-            List<PropertyType> listPropertyTypes)
-    {
-        List<EntityTypePropertyType<?>> result = new ArrayList<EntityTypePropertyType<?>>();
-        for (PropertyType propertyType : listPropertyTypes)
-        {
-            extractAssignments(result, propertyType);
-        }
-        return result;
-    }
-
-    private static void extractAssignments(List<EntityTypePropertyType<?>> result,
-            final PropertyType propertyType)
-    {
-        for (ExperimentTypePropertyType etpt : propertyType.getExperimentTypePropertyTypes())
-        {
-            result.add(etpt);
-        }
-        for (SampleTypePropertyType etpt : propertyType.getSampleTypePropertyTypes())
-        {
-            result.add(etpt);
-        }
-        for (MaterialTypePropertyType etpt : propertyType.getMaterialTypePropertyTypes())
-        {
-            result.add(etpt);
-        }
-    }
-
-    public ResultSet<Project> listProjects(DefaultResultSetConfig<String, Project> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<Project>()
-            {
-                public List<Project> getOriginalData() throws UserFailureException
-                {
-                    return listProjects();
-                }
-            });
-    }
-
-    private List<Project> listProjects()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<ProjectPE> projects = commonServer.listProjects(sessionToken);
-            return ProjectTranslator.translate(projects);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public ResultSet<Vocabulary> listVocabularies(final boolean withTerms,
-            final boolean excludeInternal, DefaultResultSetConfig<String, Vocabulary> criteria)
-            throws UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<Vocabulary>()
-            {
-                public List<Vocabulary> getOriginalData() throws UserFailureException
-                {
-                    return listVocabularies(withTerms, excludeInternal);
-                }
-            });
-    }
-
-    private List<Vocabulary> listVocabularies(final boolean withTerms, boolean excludeInternal)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<VocabularyPE> vocabularies =
-                    commonServer.listVocabularies(sessionToken, withTerms, excludeInternal);
-            return BeanUtils.createBeanList(Vocabulary.class, vocabularies, DtoConverters
-                    .getVocabularyConverter());
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public ResultSet<VocabularyTermWithStats> listVocabularyTerms(final Vocabulary vocabulary,
-            DefaultResultSetConfig<String, VocabularyTermWithStats> criteria)
-    {
-        return listEntities(criteria, new IOriginalDataProvider<VocabularyTermWithStats>()
-            {
-                public List<VocabularyTermWithStats> getOriginalData() throws UserFailureException
-                {
-                    List<ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats> terms =
-                            commonServer.listVocabularyTerms(getSessionToken(), vocabulary);
-                    return VocabularyTermTranslator.translate(terms);
-                }
-            });
-    }
-
-    public ResultSet<? extends EntityType> listMaterialTypes(
-            DefaultResultSetConfig<String, MaterialType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<MaterialType>()
-            {
-                public List<MaterialType> getOriginalData() throws UserFailureException
-                {
-                    return listMaterialTypes();
-                }
-            });
-    }
-
-    public ResultSet<? extends EntityType> listSampleTypes(
-            DefaultResultSetConfig<String, SampleType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<SampleType>()
-            {
-                public List<SampleType> getOriginalData() throws UserFailureException
-                {
-                    return listSampleTypes();
-                }
-            });
-    }
-
-    public ResultSet<? extends EntityType> listExperimentTypes(
-            DefaultResultSetConfig<String, ExperimentType> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<ExperimentType>()
-            {
-                public List<ExperimentType> getOriginalData() throws UserFailureException
-                {
-                    return listExperimentTypes();
-                }
-            });
-    }
-
-    public ResultSet<ExternalData> listSampleDataSets(final String sampleIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<ExternalData>()
-            {
-                public List<ExternalData> getOriginalData() throws UserFailureException
-                {
-                    final String sessionToken = getSessionToken();
-                    final SampleIdentifier identifier =
-                            SampleIdentifierFactory.parse(sampleIdentifier);
-                    final List<ExternalDataPE> externalData =
-                            commonServer.listExternalData(sessionToken, identifier);
-                    return ExternalDataTranslator.translate(externalData, dataStoreBaseURL);
-                }
-            });
-    }
-
-    public ResultSet<ExternalData> listExperimentDataSets(final String experimentIdentifier,
-            DefaultResultSetConfig<String, ExternalData> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return listEntities(criteria, new IOriginalDataProvider<ExternalData>()
-            {
-
-                public List<ExternalData> getOriginalData() throws UserFailureException
-                {
-                    final String sessionToken = getSessionToken();
-                    final ExperimentIdentifier identifier =
-                            new ExperimentIdentifierFactory(experimentIdentifier)
-                                    .createIdentifier();
-                    final List<ExternalDataPE> externalData =
-                            commonServer.listExternalData(sessionToken, identifier);
-                    return ExternalDataTranslator.translate(externalData, dataStoreBaseURL);
-                }
-
-            });
-    }
-
-    // ---------------- end list using cache ----------
-
-    public final List<SearchableEntity> listSearchableEntities()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            // Not directly needed but this refreshes the session.
-            getSessionToken();
-            final List<SearchableEntity> searchableEntities =
-                    BeanUtils.createBeanList(SearchableEntity.class, Arrays
-                            .asList(ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity
-                                    .values()));
-            Collections.sort(searchableEntities);
-            return searchableEntities;
-        } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public List<ExperimentType> listExperimentTypes()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<ExperimentType> result = new ArrayList<ExperimentType>();
-            final List<ExperimentTypePE> experiments =
-                    commonServer.listExperimentTypes(sessionToken);
-            for (final ExperimentTypePE expType : experiments)
-            {
-                result.add(ExperimentTranslator.translate(expType));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    private List<PropertyType> listPropertyTypes()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<PropertyTypePE> propertyTypes = commonServer.listPropertyTypes(sessionToken);
-            return PropertyTypeTranslator.translate(propertyTypes);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final List<DataType> listDataTypes()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<DataTypePE> dataTypes = commonServer.listDataTypes(sessionToken);
-            return BeanUtils.createBeanList(DataType.class, dataTypes, DtoConverters
-                    .getDataTypeConverter());
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public String assignPropertyType(final EntityKind entityKind, final String propertyTypeCode,
-            final String entityTypeCode, final boolean isMandatory, final String defaultValue)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            return commonServer.assignPropertyType(sessionToken, DtoConverters
-                    .convertEntityKind(entityKind), propertyTypeCode, entityTypeCode, isMandatory,
-                    defaultValue);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerPropertyType(final PropertyType propertyType)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        assert propertyType != null : "Unspecified property type.";
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerPropertyType(sessionToken, propertyType);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public final void registerVocabulary(final Vocabulary vocabulary)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        assert vocabulary != null : "Unspecified vocabulary.";
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerVocabulary(sessionToken, vocabulary);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public void registerProject(Project project)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        assert project != null : "Unspecified project.";
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final ProjectIdentifier projectIdentifier =
-                    new ProjectIdentifierFactory(project.getIdentifier()).createIdentifier();
-            Person leader = project.getProjectLeader();
-            final String leaderId = leader == null ? null : project.getProjectLeader().getUserId();
-            commonServer.registerProject(sessionToken, projectIdentifier, project.getDescription(),
-                    leaderId);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public String prepareExportDataSetSearchHits(TableExportCriteria<ExternalData> exportCriteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(exportCriteria);
-    }
-
-    public List<MaterialType> listMaterialTypes()
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final List<MaterialType> result = new ArrayList<MaterialType>();
-            final List<MaterialTypePE> projects = commonServer.listMaterialTypes(sessionToken);
-            for (final MaterialTypePE expType : projects)
-            {
-                result.add(MaterialTypeTranslator.translate(expType));
-            }
-            return result;
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public ResultSet<Material> listMaterials(ListMaterialCriteria criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        final String sessionToken = getSessionToken();
-        return listEntities(criteria, new ListMaterialOriginalDataProvider(commonServer,
-                sessionToken, criteria));
-    }
-
-    public String prepareExportMaterials(TableExportCriteria<Material> criteria)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        return prepareExportEntities(criteria);
-    }
-
-    public void registerMaterialType(MaterialType entityType)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerMaterialType(sessionToken, entityType);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public void registerExperimentType(ExperimentType entityType)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerExperimentType(sessionToken, entityType);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public void registerSampleType(SampleType entityType)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.registerSampleType(sessionToken, entityType);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    private final static AttachmentPE createAttachment(String fileName, final byte[] content)
-    {
-        final AttachmentPE attachment = new AttachmentPE();
-        attachment.setFileName(fileName);
-        final AttachmentContentPE attachmentContent = new AttachmentContentPE();
-        attachmentContent.setValue(content);
-        attachment.setAttachmentContent(attachmentContent);
-        return attachment;
-    }
-
-    public void updateExperiment(String sessionKey, String experimentIdentifier,
-            List<ExperimentProperty> properties, String newProjectIdentifier, Date version)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-
-        UploadedFilesBean uploadedFiles = null;
-        HttpSession session = null;
-        try
-        {
-            final String sessionToken = getSessionToken();
-            session = getHttpSession();
-            uploadedFiles = (UploadedFilesBean) session.getAttribute(sessionKey);
-            List<AttachmentPE> attachments = new ArrayList<AttachmentPE>();
-            if (uploadedFiles != null)
-            {
-                for (final IUncheckedMultipartFile multipartFile : uploadedFiles.iterable())
-                {
-                    String fileName = multipartFile.getOriginalFilename();
-                    byte[] content = multipartFile.getBytes();
-                    attachments.add(createAttachment(fileName, content));
-                }
-            }
-            final ExperimentIdentifier identifier =
-                    new ExperimentIdentifierFactory(experimentIdentifier).createIdentifier();
-            final ProjectIdentifier project =
-                    new ProjectIdentifierFactory(newProjectIdentifier).createIdentifier();
-            commonServer.editExperiment(sessionToken, identifier, properties, attachments, project,
-                    version);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        } finally
-        {
-            if (uploadedFiles != null)
-            {
-                uploadedFiles.deleteTransferredFiles();
-            }
-            if (session != null)
-            {
-                session.removeAttribute(sessionKey);
-            }
-        }
-
-    }
-
-    public void deleteDataSets(List<String> dataSetCodes, String reason)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            commonServer.deleteDataSets(sessionToken, dataSetCodes, reason);
-        } catch (final UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-    }
-
-    public void updateMaterial(String materialIdentifier, List<MaterialProperty> properties,
-            Date version)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final MaterialIdentifier identifier =
-                    MaterialIdentifier.tryParseIdentifier(materialIdentifier);
-            commonServer.editMaterial(sessionToken, identifier, properties, version);
-        } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-
-    }
-
-    public void updateSample(String sampleIdentifier, List<SampleProperty> properties,ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentIdentifier experimentIdentifierOrNull, Date  version)
-            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
-    {
-        try
-        {
-            final String sessionToken = getSessionToken();
-            final SampleIdentifier identifier =
-                    new SampleIdentifierFactory(sampleIdentifier).createIdentifier();
-            ExperimentIdentifier convExperimentIdentifierOrNull = null;
-            if (experimentIdentifierOrNull != null)
-            {
-                convExperimentIdentifierOrNull =
-                        BeanUtils
-                                .createBean(ExperimentIdentifier.class, experimentIdentifierOrNull);
-            }
-            commonServer.editSample(sessionToken, identifier, properties,
-                    convExperimentIdentifierOrNull,version);
-        } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e)
-        {
-            throw UserFailureExceptionTranslator.translate(e);
-        }
-
-    }
+		ICommonClientService {
+	private final ICommonServer commonServer;
+
+	private final String dataStoreBaseURL;
+
+	public CommonClientService(final ICommonServer commonServer,
+			final IRequestContextProvider requestContextProvider,
+			String dataStoreBaseURL) {
+		super(requestContextProvider);
+		this.commonServer = commonServer;
+		this.dataStoreBaseURL = dataStoreBaseURL + "/"
+				+ DATA_STORE_SERVER_WEB_APPLICATION_NAME;
+	}
+
+	@Override
+	protected final IServer getServer() {
+		return commonServer;
+	}
+
+	// ----------- export and listing with cache generic functionality
+
+	@SuppressWarnings("unchecked")
+	private final <K> IResultSetManager<K> getResultSetManager() {
+		return (IResultSetManager<K>) getHttpSession().getAttribute(
+				SessionConstants.OPENBIS_RESULT_SET_MANAGER);
+	}
+
+	@SuppressWarnings("unchecked")
+	private final <T> CacheManager<String, T> getExportManager() {
+		return (CacheManager<String, T>) getHttpSession().getAttribute(
+				SessionConstants.OPENBIS_EXPORT_MANAGER);
+	}
+
+	/**
+	 * Returns and removes cached export criteria.
+	 */
+	private final <T> TableExportCriteria<T> getAndRemoveExportCriteria(
+			final String exportDataKey) {
+		final CacheManager<String, TableExportCriteria<T>> exportManager = getExportManager();
+		final TableExportCriteria<T> exportCriteria = exportManager
+				.tryGetData(exportDataKey);
+		assert exportCriteria != null : "No export criteria found at key "
+				+ exportDataKey;
+		getExportManager().removeData(exportDataKey);
+		return exportCriteria;
+	}
+
+	private final <T> List<T> fetchCachedEntities(
+			final TableExportCriteria<T> exportCriteria) {
+		final IResultSetManager<String> resultSetManager = getResultSetManager();
+		IResultSetConfig<String, T> resultSetConfig = createExportListCriteria(exportCriteria);
+		IOriginalDataProvider<T> dummyDataProvider = createDummyDataProvider();
+		final IResultSet<String, T> result = resultSetManager.getResultSet(
+				resultSetConfig, dummyDataProvider);
+		final ResultSet<T> entities = ResultSetTranslator.translate(result);
+		return entities.getList();
+	}
+
+	private static <T> IOriginalDataProvider<T> createDummyDataProvider() {
+		return new IOriginalDataProvider<T>() {
+			public List<T> getOriginalData() throws UserFailureException {
+				throw new IllegalStateException("Data not found in the cache");
+			}
+		};
+	}
+
+	private static <T> IResultSetConfig<String, T> createExportListCriteria(
+			final TableExportCriteria<T> exportCriteria) {
+		final DefaultResultSetConfig<String, T> criteria = DefaultResultSetConfig
+				.createFetchAll();
+		criteria.setSortInfo(exportCriteria.getSortInfo());
+		criteria.setFilterInfos(exportCriteria.getFilterInfos());
+		criteria.setResultSetKey(exportCriteria.getResultSetKey());
+		return criteria;
+	}
+
+	private <T> ResultSet<T> listEntities(
+			final IResultSetConfig<String, T> criteria,
+			IOriginalDataProvider<T> dataProvider)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final IResultSetManager<String> resultSetManager = getResultSetManager();
+			final IResultSet<String, T> result = resultSetManager.getResultSet(
+					criteria, dataProvider);
+			return ResultSetTranslator.translate(result);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	/**
+	 * Assumes that preparation of the export (
+	 * {@link #prepareExportSamples(TableExportCriteria)} has been invoked
+	 * before and returned with an exportDataKey passed here as a parameter.
+	 */
+	public final String getExportTable(final String exportDataKey,
+			final String lineSeparator) {
+		// NOTE: no generics in GWT
+		return getGenericExportTable(exportDataKey, lineSeparator);
+	}
+
+	private final <T> String getGenericExportTable(final String exportDataKey,
+			final String lineSeparator) {
+		try {
+			// Not directly needed but this refreshes the session.
+			getSessionToken();
+			final TableExportCriteria<T> exportCriteria = getAndRemoveExportCriteria(exportDataKey);
+			final List<T> entities = fetchCachedEntities(exportCriteria);
+			return TSVRenderer.createTable(entities, exportCriteria
+					.getColumnDefs(), lineSeparator);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	private <T> String prepareExportEntities(TableExportCriteria<T> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			// Not directly needed but this refreshes the session.
+			getSessionToken();
+			final CacheManager<String, TableExportCriteria<T>> exportManager = getExportManager();
+			return exportManager.saveData(criteria);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void removeResultSet(final String resultSetKey)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			// Not directly needed but this refreshes the session.
+			getSessionToken();
+			getResultSetManager().removeResultSet(resultSetKey);
+		} catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	// --------------- end export & listing
+
+	//
+	// IGenericClientService
+	//
+
+	public final List<Group> listGroups(final String databaseInstanceCode) {
+		try {
+			final String sessionToken = getSessionToken();
+			final DatabaseInstanceIdentifier identifier = new DatabaseInstanceIdentifier(
+					databaseInstanceCode);
+			final List<Group> result = new ArrayList<Group>();
+			final List<GroupPE> groups = commonServer.listGroups(sessionToken,
+					identifier);
+			for (final GroupPE group : groups) {
+				result.add(GroupTranslator.translate(group));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerGroup(final String groupCode,
+			final String descriptionOrNull, final String groupLeaderOrNull) {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerGroup(sessionToken, groupCode,
+					descriptionOrNull, groupLeaderOrNull);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final List<Person> listPersons()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+
+		try {
+			final String sessionToken = getSessionToken();
+			final List<Person> result = new ArrayList<Person>();
+			final List<PersonPE> persons = commonServer
+					.listPersons(sessionToken);
+			for (final PersonPE person : persons) {
+				result.add(PersonTranslator.translate(person));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerPerson(final String code) {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerPerson(sessionToken, code);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final List<RoleAssignment> listRoles()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<RoleAssignment> result = new ArrayList<RoleAssignment>();
+			final List<RoleAssignmentPE> roles = commonServer
+					.listRoles(sessionToken);
+			for (final RoleAssignmentPE role : roles) {
+				result.add(RoleAssignmentTranslator.translate(role));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerGroupRole(final RoleSetCode roleSetCode,
+			final String group, final String person)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final GroupIdentifier groupIdentifier = new GroupIdentifier(
+					DatabaseInstanceIdentifier.HOME, group);
+			commonServer.registerGroupRole(sessionToken, RoleCodeTranslator
+					.translate(roleSetCode), groupIdentifier, person);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerInstanceRole(final RoleSetCode roleSetCode,
+			final String person)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerInstanceRole(sessionToken, RoleCodeTranslator
+					.translate(roleSetCode), person);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void deleteGroupRole(final RoleSetCode roleSetCode,
+			final String group, final String person)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final GroupIdentifier groupIdentifier = new GroupIdentifier(
+					DatabaseInstanceIdentifier.HOME, group);
+			commonServer.deleteGroupRole(sessionToken, RoleCodeTranslator
+					.translate(roleSetCode), groupIdentifier, person);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+
+	}
+
+	public final void deleteInstanceRole(final RoleSetCode roleSetCode,
+			final String person)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.deleteInstanceRole(sessionToken, RoleCodeTranslator
+					.translate(roleSetCode), person);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+
+	}
+
+	public final List<SampleType> listSampleTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<SampleTypePE> sampleTypes = commonServer
+					.listSampleTypes(sessionToken);
+			final List<SampleType> result = new ArrayList<SampleType>();
+			for (final SampleTypePE sampleTypePE : sampleTypes) {
+				result.add(SampleTypeTranslator.translate(sampleTypePE));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	// --------- methods preparing exported content. Note: GWT does not support
+	// generic methods :(
+
+	public final String prepareExportSamples(
+			final TableExportCriteria<Sample> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public final String prepareExportExperiments(
+			final TableExportCriteria<Experiment> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public final String prepareExportMatchingEntities(
+			final TableExportCriteria<MatchingEntity> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportPropertyTypes(
+			TableExportCriteria<PropertyType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportPropertyTypeAssignments(
+			TableExportCriteria<EntityTypePropertyType<?>> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportProjects(TableExportCriteria<Project> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportVocabularies(
+			final TableExportCriteria<Vocabulary> criteria)
+			throws UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportVocabularyTerms(
+			TableExportCriteria<VocabularyTermWithStats> criteria) {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportMaterialTypes(
+			final TableExportCriteria<MaterialType> criteria)
+			throws UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportExperimentTypes(
+			final TableExportCriteria<ExperimentType> criteria)
+			throws UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public String prepareExportSampleTypes(
+			final TableExportCriteria<SampleType> criteria)
+			throws UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	// ---------------- methods which list entities using cache
+
+	public final ResultSet<Sample> listSamples(
+			final ListSampleCriteria listCriteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		final String sessionToken = getSessionToken();
+		return listEntities(listCriteria, new ListSamplesOriginalDataProvider(
+				commonServer, sessionToken, listCriteria));
+	}
+
+	public ResultSet<ExternalData> searchForDataSets(
+			DataSetSearchCriteria criteria,
+			final IResultSetConfig<String, ExternalData> resultSetConfig)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		final String sessionToken = getSessionToken();
+		return listEntities(resultSetConfig,
+				new ListDataSetsOriginalDataProvider(commonServer,
+						sessionToken, criteria, dataStoreBaseURL));
+	}
+
+	public final ResultSet<Experiment> listExperiments(
+			final ListExperimentsCriteria listCriteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		final String sessionToken = getSessionToken();
+		return listEntities(listCriteria,
+				new ListExperimentsOriginalDataProvider(commonServer,
+						listCriteria, sessionToken));
+	}
+
+	public ResultSet<PropertyType> listPropertyTypes(
+			DefaultResultSetConfig<String, PropertyType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria,
+				new IOriginalDataProvider<PropertyType>() {
+					public List<PropertyType> getOriginalData()
+							throws UserFailureException {
+						return listPropertyTypes();
+					}
+				});
+	}
+
+	public final ResultSet<MatchingEntity> listMatchingEntities(
+			final SearchableEntity searchableEntityOrNull,
+			final String queryText,
+			final IResultSetConfig<String, MatchingEntity> resultSetConfig)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		final String sessionToken = getSessionToken();
+		final ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity[] matchingEntities = SearchableEntityTranslator
+				.translate(searchableEntityOrNull);
+		return listEntities(resultSetConfig,
+				new ListMatchingEntitiesOriginalDataProvider(commonServer,
+						sessionToken, matchingEntities, queryText));
+	}
+
+	public ResultSet<EntityTypePropertyType<?>> listPropertyTypeAssignments(
+			DefaultResultSetConfig<String, EntityTypePropertyType<?>> criteria) {
+		return listEntities(criteria,
+				new IOriginalDataProvider<EntityTypePropertyType<?>>() {
+					public List<EntityTypePropertyType<?>> getOriginalData()
+							throws UserFailureException {
+						return extractAssignments(listPropertyTypes());
+					}
+				});
+	}
+
+	private static List<EntityTypePropertyType<?>> extractAssignments(
+			List<PropertyType> listPropertyTypes) {
+		List<EntityTypePropertyType<?>> result = new ArrayList<EntityTypePropertyType<?>>();
+		for (PropertyType propertyType : listPropertyTypes) {
+			extractAssignments(result, propertyType);
+		}
+		return result;
+	}
+
+	private static void extractAssignments(
+			List<EntityTypePropertyType<?>> result,
+			final PropertyType propertyType) {
+		for (ExperimentTypePropertyType etpt : propertyType
+				.getExperimentTypePropertyTypes()) {
+			result.add(etpt);
+		}
+		for (SampleTypePropertyType etpt : propertyType
+				.getSampleTypePropertyTypes()) {
+			result.add(etpt);
+		}
+		for (MaterialTypePropertyType etpt : propertyType
+				.getMaterialTypePropertyTypes()) {
+			result.add(etpt);
+		}
+	}
+
+	public ResultSet<Project> listProjects(
+			DefaultResultSetConfig<String, Project> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria, new IOriginalDataProvider<Project>() {
+			public List<Project> getOriginalData() throws UserFailureException {
+				return listProjects();
+			}
+		});
+	}
+
+	private List<Project> listProjects()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<ProjectPE> projects = commonServer
+					.listProjects(sessionToken);
+			return ProjectTranslator.translate(projects);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public ResultSet<Vocabulary> listVocabularies(final boolean withTerms,
+			final boolean excludeInternal,
+			DefaultResultSetConfig<String, Vocabulary> criteria)
+			throws UserFailureException {
+		return listEntities(criteria, new IOriginalDataProvider<Vocabulary>() {
+			public List<Vocabulary> getOriginalData()
+					throws UserFailureException {
+				return listVocabularies(withTerms, excludeInternal);
+			}
+		});
+	}
+
+	private List<Vocabulary> listVocabularies(final boolean withTerms,
+			boolean excludeInternal)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<VocabularyPE> vocabularies = commonServer
+					.listVocabularies(sessionToken, withTerms, excludeInternal);
+			return BeanUtils.createBeanList(Vocabulary.class, vocabularies,
+					DtoConverters.getVocabularyConverter());
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public ResultSet<VocabularyTermWithStats> listVocabularyTerms(
+			final Vocabulary vocabulary,
+			DefaultResultSetConfig<String, VocabularyTermWithStats> criteria) {
+		return listEntities(criteria,
+				new IOriginalDataProvider<VocabularyTermWithStats>() {
+					public List<VocabularyTermWithStats> getOriginalData()
+							throws UserFailureException {
+						List<ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats> terms = commonServer
+								.listVocabularyTerms(getSessionToken(),
+										vocabulary);
+						return VocabularyTermTranslator.translate(terms);
+					}
+				});
+	}
+
+	public ResultSet<? extends EntityType> listMaterialTypes(
+			DefaultResultSetConfig<String, MaterialType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria,
+				new IOriginalDataProvider<MaterialType>() {
+					public List<MaterialType> getOriginalData()
+							throws UserFailureException {
+						return listMaterialTypes();
+					}
+				});
+	}
+
+	public ResultSet<? extends EntityType> listSampleTypes(
+			DefaultResultSetConfig<String, SampleType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria, new IOriginalDataProvider<SampleType>() {
+			public List<SampleType> getOriginalData()
+					throws UserFailureException {
+				return listSampleTypes();
+			}
+		});
+	}
+
+	public ResultSet<? extends EntityType> listExperimentTypes(
+			DefaultResultSetConfig<String, ExperimentType> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria,
+				new IOriginalDataProvider<ExperimentType>() {
+					public List<ExperimentType> getOriginalData()
+							throws UserFailureException {
+						return listExperimentTypes();
+					}
+				});
+	}
+
+	public ResultSet<ExternalData> listSampleDataSets(
+			final String sampleIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria,
+				new IOriginalDataProvider<ExternalData>() {
+					public List<ExternalData> getOriginalData()
+							throws UserFailureException {
+						final String sessionToken = getSessionToken();
+						final SampleIdentifier identifier = SampleIdentifierFactory
+								.parse(sampleIdentifier);
+						final List<ExternalDataPE> externalData = commonServer
+								.listExternalData(sessionToken, identifier);
+						return ExternalDataTranslator.translate(externalData,
+								dataStoreBaseURL);
+					}
+				});
+	}
+
+	public ResultSet<ExternalData> listExperimentDataSets(
+			final String experimentIdentifier,
+			DefaultResultSetConfig<String, ExternalData> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return listEntities(criteria,
+				new IOriginalDataProvider<ExternalData>() {
+
+					public List<ExternalData> getOriginalData()
+							throws UserFailureException {
+						final String sessionToken = getSessionToken();
+						final ExperimentIdentifier identifier = new ExperimentIdentifierFactory(
+								experimentIdentifier).createIdentifier();
+						final List<ExternalDataPE> externalData = commonServer
+								.listExternalData(sessionToken, identifier);
+						return ExternalDataTranslator.translate(externalData,
+								dataStoreBaseURL);
+					}
+
+				});
+	}
+
+	// ---------------- end list using cache ----------
+
+	public final List<SearchableEntity> listSearchableEntities()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			// Not directly needed but this refreshes the session.
+			getSessionToken();
+			final List<SearchableEntity> searchableEntities = BeanUtils
+					.createBeanList(
+							SearchableEntity.class,
+							Arrays
+									.asList(ch.systemsx.cisd.openbis.generic.shared.dto.SearchableEntity
+											.values()));
+			Collections.sort(searchableEntities);
+			return searchableEntities;
+		} catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public List<ExperimentType> listExperimentTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<ExperimentType> result = new ArrayList<ExperimentType>();
+			final List<ExperimentTypePE> experiments = commonServer
+					.listExperimentTypes(sessionToken);
+			for (final ExperimentTypePE expType : experiments) {
+				result.add(ExperimentTranslator.translate(expType));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	private List<PropertyType> listPropertyTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<PropertyTypePE> propertyTypes = commonServer
+					.listPropertyTypes(sessionToken);
+			return PropertyTypeTranslator.translate(propertyTypes);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final List<DataType> listDataTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<DataTypePE> dataTypes = commonServer
+					.listDataTypes(sessionToken);
+			return BeanUtils.createBeanList(DataType.class, dataTypes,
+					DtoConverters.getDataTypeConverter());
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public String assignPropertyType(final EntityKind entityKind,
+			final String propertyTypeCode, final String entityTypeCode,
+			final boolean isMandatory, final String defaultValue)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			return commonServer.assignPropertyType(sessionToken, DtoConverters
+					.convertEntityKind(entityKind), propertyTypeCode,
+					entityTypeCode, isMandatory, defaultValue);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerPropertyType(final PropertyType propertyType)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		assert propertyType != null : "Unspecified property type.";
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerPropertyType(sessionToken, propertyType);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public final void registerVocabulary(final Vocabulary vocabulary)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		assert vocabulary != null : "Unspecified vocabulary.";
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerVocabulary(sessionToken, vocabulary);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public void registerProject(Project project)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		assert project != null : "Unspecified project.";
+		try {
+			final String sessionToken = getSessionToken();
+			final ProjectIdentifier projectIdentifier = new ProjectIdentifierFactory(
+					project.getIdentifier()).createIdentifier();
+			Person leader = project.getProjectLeader();
+			final String leaderId = leader == null ? null : project
+					.getProjectLeader().getUserId();
+			commonServer.registerProject(sessionToken, projectIdentifier,
+					project.getDescription(), leaderId);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public String prepareExportDataSetSearchHits(
+			TableExportCriteria<ExternalData> exportCriteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(exportCriteria);
+	}
+
+	public List<MaterialType> listMaterialTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<MaterialType> result = new ArrayList<MaterialType>();
+			final List<MaterialTypePE> projects = commonServer
+					.listMaterialTypes(sessionToken);
+			for (final MaterialTypePE expType : projects) {
+				result.add(MaterialTypeTranslator.translate(expType));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public List<DataSetType> listDataSetTypes()
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final List<DataSetType> result = new ArrayList<DataSetType>();
+			final List<DataSetTypePE> types = commonServer
+					.listDataSetTypes(sessionToken);
+			for (final DataSetTypePE type : types) {
+				result.add(DataSetTypeTranslator.translate(type));
+			}
+			return result;
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public ResultSet<Material> listMaterials(ListMaterialCriteria criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		final String sessionToken = getSessionToken();
+		return listEntities(criteria, new ListMaterialOriginalDataProvider(
+				commonServer, sessionToken, criteria));
+	}
+
+	public String prepareExportMaterials(TableExportCriteria<Material> criteria)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		return prepareExportEntities(criteria);
+	}
+
+	public void registerMaterialType(MaterialType entityType)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerMaterialType(sessionToken, entityType);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public void registerExperimentType(ExperimentType entityType)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerExperimentType(sessionToken, entityType);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public void registerSampleType(SampleType entityType)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.registerSampleType(sessionToken, entityType);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	private final static AttachmentPE createAttachment(String fileName,
+			final byte[] content) {
+		final AttachmentPE attachment = new AttachmentPE();
+		attachment.setFileName(fileName);
+		final AttachmentContentPE attachmentContent = new AttachmentContentPE();
+		attachmentContent.setValue(content);
+		attachment.setAttachmentContent(attachmentContent);
+		return attachment;
+	}
+
+	public void updateExperiment(String sessionKey,
+			String experimentIdentifier, List<ExperimentProperty> properties,
+			String newProjectIdentifier, Date version)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+
+		UploadedFilesBean uploadedFiles = null;
+		HttpSession session = null;
+		try {
+			final String sessionToken = getSessionToken();
+			session = getHttpSession();
+			uploadedFiles = (UploadedFilesBean) session
+					.getAttribute(sessionKey);
+			List<AttachmentPE> attachments = new ArrayList<AttachmentPE>();
+			if (uploadedFiles != null) {
+				for (final IUncheckedMultipartFile multipartFile : uploadedFiles
+						.iterable()) {
+					String fileName = multipartFile.getOriginalFilename();
+					byte[] content = multipartFile.getBytes();
+					attachments.add(createAttachment(fileName, content));
+				}
+			}
+			final ExperimentIdentifier identifier = new ExperimentIdentifierFactory(
+					experimentIdentifier).createIdentifier();
+			final ProjectIdentifier project = new ProjectIdentifierFactory(
+					newProjectIdentifier).createIdentifier();
+			commonServer.editExperiment(sessionToken, identifier, properties,
+					attachments, project, version);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		} finally {
+			if (uploadedFiles != null) {
+				uploadedFiles.deleteTransferredFiles();
+			}
+			if (session != null) {
+				session.removeAttribute(sessionKey);
+			}
+		}
+
+	}
+
+	public void deleteDataSets(List<String> dataSetCodes, String reason)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			commonServer.deleteDataSets(sessionToken, dataSetCodes, reason);
+		} catch (final UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+	}
+
+	public void updateMaterial(String materialIdentifier,
+			List<MaterialProperty> properties, Date version)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final MaterialIdentifier identifier = MaterialIdentifier
+					.tryParseIdentifier(materialIdentifier);
+			commonServer.editMaterial(sessionToken, identifier, properties,
+					version);
+		} catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+
+	}
+
+	public void updateSample(
+			String sampleIdentifier,
+			List<SampleProperty> properties,
+			ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExperimentIdentifier experimentIdentifierOrNull,
+			Date version)
+			throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException {
+		try {
+			final String sessionToken = getSessionToken();
+			final SampleIdentifier identifier = new SampleIdentifierFactory(
+					sampleIdentifier).createIdentifier();
+			ExperimentIdentifier convExperimentIdentifierOrNull = null;
+			if (experimentIdentifierOrNull != null) {
+				convExperimentIdentifierOrNull = BeanUtils.createBean(
+						ExperimentIdentifier.class, experimentIdentifierOrNull);
+			}
+			commonServer.editSample(sessionToken, identifier, properties,
+					convExperimentIdentifierOrNull, version);
+		} catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e) {
+			throw UserFailureExceptionTranslator.translate(e);
+		}
+
+	}
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListDataSetsOriginalDataProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListDataSetsOriginalDataProvider.java
index e41bbcf8725ad6b3d2e465f8c364900252c9d5b0..c1c55ae85bc253cb49f7fa232ccec31874daf4b5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListDataSetsOriginalDataProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/ListDataSetsOriginalDataProvider.java
@@ -5,10 +5,11 @@ import java.util.List;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.IOriginalDataProvider;
-import ch.systemsx.cisd.openbis.generic.client.web.server.translator.DataSetSearchHitTranslator;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExternalDataTranslator;
+import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExperimentTranslator.LoadableFields;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 
 /**
  * A {@link IOriginalDataProvider} implementation for search data sets.
@@ -35,12 +36,13 @@ final class ListDataSetsOriginalDataProvider extends AbstractOriginalDataProvide
 
     public final List<ExternalData> getOriginalData()
     {
-        final List<DataSetSearchHitDTO> hits =
+        final List<ExternalDataPE> hits =
                 commonServer.searchForDataSets(sessionToken, criteria);
         final List<ExternalData> list = new ArrayList<ExternalData>(hits.size());
-        for (final DataSetSearchHitDTO hit : hits)
+        for (final ExternalDataPE hit : hits)
         {
-            list.add(DataSetSearchHitTranslator.translate(hit, dataStoreBaseURL));
+            list.add(ExternalDataTranslator.translate(hit, dataStoreBaseURL,true,
+                    LoadableFields.PROPERTIES));
         }
         return list;
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/AbstractEntityTypePropertyTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/AbstractEntityTypePropertyTypeTranslator.java
index 900d5d36ad75fe41660aec3c517bbaa283abf233..d893aa314f8f16f2848fbd04af730506b0b45212 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/AbstractEntityTypePropertyTypeTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/AbstractEntityTypePropertyTypeTranslator.java
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityTypePropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePropertyTypePE;
@@ -65,7 +66,11 @@ abstract public class AbstractEntityTypePropertyTypeTranslator<ET extends Entity
             result.setPropertyType(propertyType);
         } else
         {
-            result.setPropertyType(PropertyTypeTranslator.translate(etptPE.getPropertyType()));
+        	if(entityType != null && (entityType instanceof MaterialType)){
+        		result.setPropertyType(PropertyTypeTranslator.translate(etptPE.getPropertyType(), (MaterialType)entityType));
+            }else{
+            	result.setPropertyType(PropertyTypeTranslator.translate(etptPE.getPropertyType()));
+            }
         }
         if (entityType != null)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetSearchHitTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetSearchHitTranslator.java
deleted file mode 100644
index b53838bf963dd006e74bfce504fb4ed003c790b1..0000000000000000000000000000000000000000
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetSearchHitTranslator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2009 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.client.web.server.translator;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ExternalData;
-import ch.systemsx.cisd.openbis.generic.client.web.server.translator.ExperimentTranslator.LoadableFields;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
-
-/**
- * Converts {@link DataSetSearchHitDTO}s to {@link ExternalData}s.
- * 
- * @author Izabela Adamczyk
- */
-public class DataSetSearchHitTranslator
-{
-    private DataSetSearchHitTranslator()
-    {
-    }
-
-    public static List<ExternalData> translate(List<DataSetSearchHitDTO> list,
-            String dataStoreBaseURL)
-    {
-        ArrayList<ExternalData> result = new ArrayList<ExternalData>(list.size());
-        for (DataSetSearchHitDTO item : list)
-        {
-            result.add(translate(item, dataStoreBaseURL));
-        }
-        return result;
-    }
-
-    public static ExternalData translate(DataSetSearchHitDTO hit, String dataStoreBaseURL)
-    {
-        return ExternalDataTranslator.translate(hit.getDataSet(), dataStoreBaseURL, true,
-                LoadableFields.PROPERTIES);
-    }
-
-}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypePropertyTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypePropertyTypeTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7211fcaee6b2235335b7e8d307d22798ebc9e54a
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypePropertyTypeTranslator.java
@@ -0,0 +1,77 @@
+/*
+ * 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.client.web.server.translator;
+
+import java.util.List;
+import java.util.Set;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypePropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
+
+/**
+ * Translates {@link DataSetTypePropertyTypePE} to
+ * {@link DataSetTypePropertyType}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DataSetTypePropertyTypeTranslator {
+
+	static private class DataSetTypePropertyTypeTranslatorHelper
+			extends
+			AbstractEntityTypePropertyTypeTranslator<DataSetType, DataSetTypePropertyType, DataSetTypePropertyTypePE> {
+		@Override
+		void setSpecificFields(DataSetTypePropertyType result,
+				DataSetTypePropertyTypePE etptPE) {
+		}
+
+		@Override
+		DataSetType translate(EntityTypePE entityTypePE) {
+			return DataSetTypeTranslator
+					.translate((DataSetTypePE) entityTypePE);
+		}
+
+		@Override
+		DataSetTypePropertyType create() {
+			return new DataSetTypePropertyType();
+		}
+	}
+
+	public static List<DataSetTypePropertyType> translate(
+			Set<DataSetTypePropertyTypePE> DataSetTypePropertyTypes,
+			PropertyType result) {
+		return new DataSetTypePropertyTypeTranslatorHelper().translate(
+				DataSetTypePropertyTypes, result);
+	}
+
+	public static DataSetTypePropertyType translate(
+			DataSetTypePropertyTypePE entityTypePropertyType) {
+		return new DataSetTypePropertyTypeTranslatorHelper()
+				.translate(entityTypePropertyType);
+	}
+
+	public static List<DataSetTypePropertyType> translate(
+			Set<DataSetTypePropertyTypePE> DataSetTypePropertyTypes,
+			DataSetType result) {
+		return new DataSetTypePropertyTypeTranslatorHelper().translate(
+				DataSetTypePropertyTypes, result);
+	}
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypeTranslator.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b42a1b95dfa042bd081eaf70e5c5ee0c7992a51
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/DataSetTypeTranslator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.client.web.server.translator;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+
+/**
+ * Translates {@link DataSetTypePE} to {@link DataSetType}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DataSetTypeTranslator {
+
+	private DataSetTypeTranslator() {
+	}
+
+	public static DataSetType translate(DataSetTypePE entityTypeOrNull) {
+		if (entityTypeOrNull == null) {
+			return null;
+		}
+		final DataSetType result = new DataSetType();
+		result
+				.setCode(StringEscapeUtils.escapeHtml(entityTypeOrNull
+						.getCode()));
+		result.setDescription(StringEscapeUtils.escapeHtml(entityTypeOrNull
+				.getDescription()));
+		result.setDatabaseInstance(DatabaseInstanceTranslator
+				.translate(entityTypeOrNull.getDatabaseInstance()));
+		result.setDataSetTypePropertyTypes(DataSetTypePropertyTypeTranslator
+				.translate(entityTypeOrNull.getDataSetTypePropertyTypes(),
+						result));
+		return result;
+	}
+
+	public static DataSetTypePE translate(DataSetType type) {
+		final DataSetTypePE result = new DataSetTypePE();
+		result.setCode(type.getCode());
+		return result;
+	}
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/PropertyTypeTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/PropertyTypeTranslator.java
index cae7c1d7dd81b8e380d8c7f3b97a56a44bfee58b..3f5c1f15c89d85f18e2a0beb381368a6d6d6ef81 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/PropertyTypeTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/translator/PropertyTypeTranslator.java
@@ -21,6 +21,7 @@ import java.util.List;
 
 import org.apache.commons.lang.StringEscapeUtils;
 
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
 
@@ -47,9 +48,8 @@ public final class PropertyTypeTranslator
         return result;
     }
 
-    public final static PropertyType translate(final PropertyTypePE propertyType)
-    {
-        final PropertyType result = new PropertyType();
+    public final static PropertyType translate(final PropertyTypePE propertyType, MaterialType materialType){
+    	final PropertyType result = new PropertyType();
         result.setCode(StringEscapeUtils.escapeHtml(propertyType.getCode()));
         result.setSimpleCode(StringEscapeUtils.escapeHtml(propertyType.getSimpleCode()));
         result.setInternalNamespace(propertyType.isInternalNamespace());
@@ -57,7 +57,11 @@ public final class PropertyTypeTranslator
         result.setLabel(StringEscapeUtils.escapeHtml(propertyType.getLabel()));
         result.setDataType(DataTypeTranslator.translate(propertyType.getType()));
         result.setVocabulary(VocabularyTranslator.translate(propertyType.getVocabulary()));
-        result.setMaterialType(MaterialTypeTranslator.translate(propertyType.getMaterialType()));
+        if(materialType == null){
+        	result.setMaterialType(MaterialTypeTranslator.translate(propertyType.getMaterialType()));
+        }else{
+        	result.setMaterialType(materialType);
+        }
         result.setDescription(StringEscapeUtils.escapeHtml(propertyType.getDescription()));
         result.setSampleTypePropertyTypes(SampleTypePropertyTypeTranslator.translate(propertyType
                 .getSampleTypePropertyTypes(), result));
@@ -67,4 +71,9 @@ public final class PropertyTypeTranslator
                 propertyType.getExperimentTypePropertyTypes(), result));
         return result;
     }
-}
+    
+    public final static PropertyType translate(final PropertyTypePE propertyType)
+    {
+        return translate(propertyType, null);
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 0c38637d53ab84b5d6dc9e2ed88ffa48c6c1ee01..01fcb06ebe57e72252ef29e8a8e76a89539c3511 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -66,7 +66,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerSession;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
@@ -104,640 +104,630 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
  * 
  * @author Franz-Josef Elmer
  */
-public final class CommonServer extends AbstractServer<ICommonServer> implements ICommonServer
-{
-    @Private static final String DELETION_DESCRIPTION = "single deletion";
-
-    private final IAuthenticationService authenticationService;
-
-    private final ICommonBusinessObjectFactory businessObjectFactory;
-
-    private final DataStoreServerSessionManager dssSessionManager;
-
-    public CommonServer(final IAuthenticationService authenticationService,
-            final ISessionManager<Session> sessionManager,
-            DataStoreServerSessionManager dssSessionManager, final IDAOFactory daoFactory,
-            final ICommonBusinessObjectFactory businessObjectFactory)
-    {
-        super(sessionManager, daoFactory);
-        this.authenticationService = authenticationService;
-        this.dssSessionManager = dssSessionManager;
-        this.businessObjectFactory = businessObjectFactory;
-    }
-
-    ICommonBusinessObjectFactory getBusinessObjectFactory()
-    {
-        return businessObjectFactory;
-    }
-
-    // Call this when session object is not needed but you want just to refresh/check the session.
-    private void checkSession(final String sessionToken)
-    {
-        getSessionManager().getSession(sessionToken);
-    }
-
-    private static UserFailureException createUserFailureException(final DataAccessException ex)
-    {
-        return new UserFailureException(ex.getMostSpecificCause().getMessage(), ex);
-    }
-
-    //
-    // AbstractServerWithLogger
-    //
-
-    @Override
-    protected final Class<ICommonServer> getProxyInterface()
-    {
-        return ICommonServer.class;
-    }
-
-    //
-    // IInvocationLoggerFactory
-    //
-
-    /**
-     * Creates a logger used to log invocations of objects of this class.
-     */
-    public final ICommonServer createLogger(final boolean invocationSuccessful)
-    {
-        return new CommonServerLogger(getSessionManager(), invocationSuccessful);
-    }
-
-    //
-    // IGenericServer
-    //
-
-    public final List<GroupPE> listGroups(final String sessionToken,
-            final DatabaseInstanceIdentifier identifier)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final DatabaseInstancePE databaseInstance =
-                GroupIdentifierHelper.getDatabaseInstance(identifier, getDAOFactory());
-        final List<GroupPE> groups = getDAOFactory().getGroupDAO().listGroups(databaseInstance);
-        final Long homeGroupID = session.tryGetHomeGroupId();
-        for (final GroupPE group : groups)
-        {
-            group.setHome(homeGroupID != null && homeGroupID.equals(group.getId()));
-        }
-        Collections.sort(groups);
-        return groups;
-    }
-
-    public final void registerGroup(final String sessionToken, final String groupCode,
-            final String descriptionOrNull, final String groupLeaderOrNull)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IGroupBO groupBO = businessObjectFactory.createGroupBO(session);
-        groupBO.define(groupCode, descriptionOrNull, groupLeaderOrNull);
-        groupBO.save();
-    }
-
-    public final void registerPerson(final String sessionToken, final String userID)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final PersonPE person = getDAOFactory().getPersonDAO().tryFindPersonByUserId(userID);
-        if (person != null)
-        {
-            throw UserFailureException.fromTemplate("Person '%s' already exists.", userID);
-        }
-        final String applicationToken = authenticationService.authenticateApplication();
-        if (applicationToken == null)
-        {
-            throw new EnvironmentFailureException("Authentication service cannot be accessed.");
-        }
-        try
-        {
-            final Principal principal =
-                    authenticationService.getPrincipal(applicationToken, userID);
-            createPerson(principal, session.tryGetPerson());
-        } catch (final IllegalArgumentException e)
-        {
-            throw new UserFailureException("Person '" + userID
-                    + "' unknown by the authentication service.");
-        }
-    }
-
-    public final List<RoleAssignmentPE> listRoles(final String sessionToken)
-    {
-        checkSession(sessionToken);
-        return getDAOFactory().getRoleAssignmentDAO().listRoleAssignments();
-    }
-
-    public final void registerGroupRole(final String sessionToken, final RoleCode roleCode,
-            final GroupIdentifier groupIdentifier, final String person)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-
-        final NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
-        newRoleAssignment.setUserId(person);
-        newRoleAssignment.setGroupIdentifier(groupIdentifier);
-        newRoleAssignment.setRole(roleCode);
-
-        final IRoleAssignmentTable table = businessObjectFactory.createRoleAssignmentTable(session);
-        table.add(newRoleAssignment);
-        table.save();
-
-    }
-
-    public final void registerInstanceRole(final String sessionToken, final RoleCode roleCode,
-            final String person)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-
-        final NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
-        newRoleAssignment.setUserId(person);
-        newRoleAssignment.setDatabaseInstanceIdentifier(new DatabaseInstanceIdentifier(
-                DatabaseInstanceIdentifier.HOME));
-        newRoleAssignment.setRole(roleCode);
-
-        final IRoleAssignmentTable table = businessObjectFactory.createRoleAssignmentTable(session);
-        table.add(newRoleAssignment);
-        table.save();
-
-    }
-
-    public final void deleteGroupRole(final String sessionToken, final RoleCode roleCode,
-            final GroupIdentifier groupIdentifier, final String person)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-
-        final RoleAssignmentPE roleAssignment =
-                getDAOFactory().getRoleAssignmentDAO().tryFindGroupRoleAssignment(roleCode,
-                        groupIdentifier.getGroupCode(), person);
-        if (roleAssignment == null)
-        {
-            throw new UserFailureException("Given group role does not exist.");
-        }
-        final PersonPE personPE = session.tryGetPerson();
-        if (roleAssignment.getPerson().equals(personPE)
-                && roleAssignment.getRole().equals(RoleCode.ADMIN))
-        {
-            boolean isInstanceAdmin = false;
-            for (final RoleAssignmentPE roleAssigment : personPE.getRoleAssignments())
-            {
-                if (roleAssigment.getDatabaseInstance() != null
-                        && roleAssigment.getRole().equals(RoleCode.ADMIN))
-                {
-                    isInstanceAdmin = true;
-                }
-            }
-            if (isInstanceAdmin == false)
-            {
-                throw new UserFailureException(
-                        "For safety reason you cannot give away your own group admin power. "
-                                + "Ask instance admin to do that for you.");
-            }
-        }
-        getDAOFactory().getRoleAssignmentDAO().deleteRoleAssignment(roleAssignment);
-    }
-
-    public final void deleteInstanceRole(final String sessionToken, final RoleCode roleCode,
-            final String person)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IRoleAssignmentDAO roleAssignmentDAO = getDAOFactory().getRoleAssignmentDAO();
-        final RoleAssignmentPE roleAssignment =
-                roleAssignmentDAO.tryFindInstanceRoleAssignment(roleCode, person);
-        if (roleAssignment == null)
-        {
-            throw new UserFailureException("Given database instance role does not exist.");
-        }
-        if (roleAssignment.getPerson().equals(session.tryGetPerson())
-                && roleAssignment.getRole().equals(RoleCode.ADMIN)
-                && roleAssignment.getDatabaseInstance() != null)
-        {
-            throw new UserFailureException(
-                    "For safety reason you cannot give away your own omnipotence. "
-                            + "Ask another instance admin to do that for you.");
-        }
-        roleAssignmentDAO.deleteRoleAssignment(roleAssignment);
-    }
-
-    public final List<PersonPE> listPersons(final String sessionToken)
-    {
-        checkSession(sessionToken);
-        final List<PersonPE> persons = getDAOFactory().getPersonDAO().listPersons();
-        Collections.sort(persons);
-        return persons;
-    }
-
-    public final List<ProjectPE> listProjects(final String sessionToken)
-    {
-        checkSession(sessionToken);
-        final List<ProjectPE> projects = getDAOFactory().getProjectDAO().listProjects();
-        Collections.sort(projects);
-        return projects;
-    }
-
-    public final List<SampleTypePE> listSampleTypes(final String sessionToken)
-    {
-        checkSession(sessionToken);
-        final List<SampleTypePE> sampleTypes = getDAOFactory().getSampleTypeDAO().listSampleTypes();
-        Collections.sort(sampleTypes);
-        return sampleTypes;
-    }
-
-    public final List<SamplePE> listSamples(final String sessionToken,
-            final ListSampleCriteriaDTO criteria)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final ISampleTable sampleTable = businessObjectFactory.createSampleTable(session);
-        sampleTable.loadSamplesByCriteria(criteria);
-        sampleTable.enrichWithValidProcedure();
-        sampleTable.enrichWithProperties();
-        final List<SamplePE> samples = sampleTable.getSamples();
-        Collections.sort(samples);
-        return samples;
-    }
-
-    public final List<ExternalDataPE> listExternalData(final String sessionToken,
-            final SampleIdentifier identifier)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IExternalDataTable externalDataTable =
-                businessObjectFactory.createExternalDataTable(session);
-        externalDataTable.loadBySampleIdentifier(identifier);
-        return getSortedExternalDataFrom(externalDataTable);
-    }
-
-    public List<ExternalDataPE> listExternalData(String sessionToken,
-            ExperimentIdentifier identifier)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IExternalDataTable externalDataTable =
-                businessObjectFactory.createExternalDataTable(session);
-        externalDataTable.loadByExperimentIdentifier(identifier);
-        return getSortedExternalDataFrom(externalDataTable);
-    }
-
-    private List<ExternalDataPE> getSortedExternalDataFrom(
-            final IExternalDataTable externalDataTable)
-    {
-        final List<ExternalDataPE> externalData = externalDataTable.getExternalData();
-        Collections.sort(externalData);
-        return externalData;
-    }
-
-    public final List<PropertyTypePE> listPropertyTypes(final String sessionToken)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IPropertyTypeTable propertyTypeTable =
-                businessObjectFactory.createPropertyTypeTable(session);
-        propertyTypeTable.load();
-        propertyTypeTable.enrichWithRelations();
-        final List<PropertyTypePE> propertyTypes = propertyTypeTable.getPropertyTypes();
-        Collections.sort(propertyTypes);
-        return propertyTypes;
-    }
-
-    public final List<SearchHit> listMatchingEntities(final String sessionToken,
-            final SearchableEntity[] searchableEntities, final String queryText)
-    {
-        checkSession(sessionToken);
-        final List<SearchHit> list = new ArrayList<SearchHit>();
-        try
-        {
-            for (final SearchableEntity searchableEntity : searchableEntities)
-            {
-                final List<SearchHit> entities =
-                        getDAOFactory().getHibernateSearchDAO().searchEntitiesByTerm(
-                                searchableEntity.getMatchingEntityClass(), queryText);
-                list.addAll(entities);
-            }
-        } catch (final DataAccessException ex)
-        {
-            throw createUserFailureException(ex);
-        }
-        return list;
-    }
-
-    public final List<ExperimentPE> listExperiments(final String sessionToken,
-            final ExperimentTypePE experimentType, final ProjectIdentifier projectIdentifier)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IExperimentTable experimentTable =
-                businessObjectFactory.createExperimentTable(session);
-        experimentTable.load(experimentType.getCode(), projectIdentifier);
-        experimentTable.enrichWithProperties();
-        final List<ExperimentPE> experiments = experimentTable.getExperiments();
-        Collections.sort(experiments);
-        return experiments;
-    }
-
-    public final List<ExperimentTypePE> listExperimentTypes(final String sessionToken)
-    {
-        return listEntityTypes(sessionToken, EntityKind.EXPERIMENT);
-    }
-
-    public List<MaterialTypePE> listMaterialTypes(String sessionToken)
-    {
-        return listEntityTypes(sessionToken, EntityKind.MATERIAL);
-    }
-
-    private <T extends EntityTypePE> List<T> listEntityTypes(String sessionToken,
-            EntityKind entityKind)
-    {
-        checkSession(sessionToken);
-        final List<T> types = getDAOFactory().getEntityTypeDAO(entityKind).listEntityTypes();
-        Collections.sort(types);
-        return types;
-    }
-
-    public final List<DataTypePE> listDataTypes(final String sessionToken)
-    {
-        assert sessionToken != null : "Unspecified session token";
-        checkSession(sessionToken);
-        final List<DataTypePE> dataTypes = getDAOFactory().getPropertyTypeDAO().listDataTypes();
-        Collections.sort(dataTypes);
-        return dataTypes;
-    }
-
-    public final List<VocabularyPE> listVocabularies(final String sessionToken,
-            final boolean withTerms, boolean excludeInternal)
-    {
-        assert sessionToken != null : "Unspecified session token";
-        checkSession(sessionToken);
-        final List<VocabularyPE> vocabularies =
-                getDAOFactory().getVocabularyDAO().listVocabularies(excludeInternal);
-        if (withTerms)
-        {
-            for (final VocabularyPE vocabularyPE : vocabularies)
-            {
-                enrichWithTerms(vocabularyPE);
-            }
-        }
-        Collections.sort(vocabularies);
-        return vocabularies;
-    }
-
-    private void enrichWithTerms(final VocabularyPE vocabularyPE)
-    {
-        HibernateUtils.initialize(vocabularyPE.getTerms());
-    }
-
-    public String assignPropertyType(final String sessionToken, final EntityKind entityKind,
-            final String propertyTypeCode, final String entityTypeCode, final boolean isMandatory,
-            final String defaultValue)
-    {
-        assert sessionToken != null : "Unspecified session token";
-        Session session = getSessionManager().getSession(sessionToken);
-
-        IEntityTypePropertyTypeBO etptBO =
-                businessObjectFactory.createEntityTypePropertyTypeBO(session, entityKind);
-        etptBO.createAssignment(propertyTypeCode, entityTypeCode, isMandatory, defaultValue);
-        return String.format("%s property type '%s' successfully assigned to %s type '%s'",
-                isMandatory ? "Mandatory" : "Optional", propertyTypeCode, entityKind.getLabel(),
-                entityTypeCode);
-
-    }
-
-    public final void registerPropertyType(final String sessionToken,
-            final PropertyType propertyType)
-    {
-        assert sessionToken != null : "Unspecified session token";
-        assert propertyType != null : "Unspecified property type";
-
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IPropertyTypeBO propertyTypeBO = businessObjectFactory.createPropertyTypeBO(session);
-        propertyTypeBO.define(propertyType);
-        propertyTypeBO.save();
-    }
-
-    public final void registerVocabulary(final String sessionToken, final Vocabulary vocabulary)
-    {
-        assert sessionToken != null : "Unspecified session token";
-        assert vocabulary != null : "Unspecified vocabulary";
-
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IVocabularyBO vocabularyBO = businessObjectFactory.createVocabularyBO(session);
-        vocabularyBO.define(vocabulary);
-        vocabularyBO.save();
-    }
-
-    public void registerProject(String sessionToken, ProjectIdentifier projectIdentifier,
-            String description, String leaderId)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IProjectBO projectBO = businessObjectFactory.createProjectBO(session);
-        projectBO.define(projectIdentifier, description, leaderId);
-        projectBO.save();
-
-    }
-
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
-            DataSetSearchCriteria criteria)
-    {
-        checkSession(sessionToken);
-        try
-        {
-            IHibernateSearchDAO searchDAO = getDAOFactory().getHibernateSearchDAO();
-            return searchDAO.searchForDataSets(criteria);
-        } catch (final DataAccessException ex)
-        {
-            throw createUserFailureException(ex);
-        }
-    }
-
-    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IMaterialTable materialTable = businessObjectFactory.createMaterialTable(session);
-        materialTable.load(materialType.getCode());
-        final List<MaterialPE> materials = materialTable.getMaterials();
-        Collections.sort(materials);
-        return materials;
-    }
-
-    public void registerSampleType(String sessionToken, SampleType entityType)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        try
-        {
-            IEntityTypeBO entityTypeBO = businessObjectFactory.createEntityTypeBO(session);
-            entityTypeBO.define(entityType);
-            entityTypeBO.save();
-        } catch (final DataAccessException ex)
-        {
-            throw createUserFailureException(ex);
-        }
-    }
-
-    public void registerMaterialType(String sessionToken, MaterialType entityType)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        try
-        {
-            IEntityTypeBO entityTypeBO = businessObjectFactory.createEntityTypeBO(session);
-            entityTypeBO.define(entityType);
-            entityTypeBO.save();
-        } catch (final DataAccessException ex)
-        {
-            throw createUserFailureException(ex);
-        }
-    }
-
-    public void registerExperimentType(String sessionToken, ExperimentType entityType)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        try
-        {
-            IEntityTypeBO entityTypeBO = businessObjectFactory.createEntityTypeBO(session);
-            entityTypeBO.define(entityType);
-            entityTypeBO.save();
-        } catch (final DataAccessException ex)
-        {
-            throw createUserFailureException(ex);
-        }
-    }
-
-    public void deleteDataSets(String sessionToken, List<String> dataSetCodes, String reason)
-    {
-        Session session = getSessionManager().getSession(sessionToken);
-        IExternalDataDAO externalDataDAO = getDAOFactory().getExternalDataDAO();
-        List<ExternalDataPE> dataSets = new ArrayList<ExternalDataPE>();
-        List<String> locations = new ArrayList<String>();
-        for (String dataSetCode : dataSetCodes)
-        {
-            ExternalDataPE dataSet = externalDataDAO.tryToFindFullDataSetByCode(dataSetCode);
-            if (dataSet != null)
-            {
-                dataSets.add(dataSet);
-                locations.add(dataSet.getLocation());
-            }
-        }
-        assertDataSetsAreKnown(dataSets, locations);
-
-        for (ExternalDataPE dataSet : dataSets)
-        {
-            externalDataDAO.markAsDeleted(dataSet, session.tryGetPerson(), DELETION_DESCRIPTION, reason);
-        }
-        Collection<DataStoreServerSession> sessions = dssSessionManager.getSessions();
-        for (DataStoreServerSession dssSession : sessions)
-        {
-            dssSession.getService().deleteDataSets(dssSession.getSessionToken(), locations);
-        }
-    }
-
-    private void assertDataSetsAreKnown(List<ExternalDataPE> dataSets, List<String> locations)
-    {
-        Set<String> knownLocations = new LinkedHashSet<String>();
-        Collection<DataStoreServerSession> sessions = dssSessionManager.getSessions();
-        for (DataStoreServerSession session : sessions)
-        {
-            IDataStoreService service = session.getService();
-            String dssSessionToken = session.getSessionToken();
-            knownLocations.addAll(service.getKnownDataSets(dssSessionToken, locations));
-        }
-        List<String> unknownDataSets = new ArrayList<String>();
-        for (ExternalDataPE dataSet : dataSets)
-        {
-            if (knownLocations.contains(dataSet.getLocation()) == false)
-            {
-                unknownDataSets.add(dataSet.getCode());
-            }
-        }
-        if (unknownDataSets.isEmpty() == false)
-        {
-            throw new UserFailureException(
-                    "The following data sets are unknown by any registered Data Store Server. "
-                            + "May be the responsible Data Store Server is not running.\n"
-                            + unknownDataSets);
-        }
-    }
-
-    public void editExperiment(String sessionToken, ExperimentIdentifier identifier,
-            List<ExperimentProperty> properties, List<AttachmentPE> attachments,
-            ProjectIdentifier newProjectIdentifier, Date version)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        if (newProjectIdentifier.equals(identifier) == false)
-        {
-            checkExternalData(identifier, session);
-            checkSampleConsistency(identifier, newProjectIdentifier, session);
-        }
-
-        final IExperimentBO experimentBO = businessObjectFactory.createExperimentBO(session);
-        experimentBO.edit(identifier, properties, attachments, newProjectIdentifier, version);
-        experimentBO.save();
-    }
-
-    private void checkExternalData(ExperimentIdentifier identifier, final Session session)
-    {
-        final IExternalDataTable externalDataTable =
-                businessObjectFactory.createExternalDataTable(session);
-        externalDataTable.loadByExperimentIdentifier(identifier);
-        if (externalDataTable.getExternalData().size() > 0)
-        {
-            throw new UserFailureException(
-                    "Changing the project of experiment containing data sets is not allowed.");
-        }
-    }
-
-    private void checkSampleConsistency(ExperimentIdentifier identifier,
-            ProjectIdentifier newProjectIdentifier, final Session session)
-    {
-        ListSampleCriteriaDTO criteria =
-                ListSampleCriteriaDTO.createExperimentIdentifier(identifier);
-        final ISampleTable sampleTable = businessObjectFactory.createSampleTable(session);
-        sampleTable.loadSamplesByCriteria(criteria);
-        final List<SamplePE> samples = sampleTable.getSamples();
-        if (samples.size() > 0)
-        {
-            checkExperimentGroupMatches(samples.get(0).getSampleIdentifier(), newProjectIdentifier);
-        }
-    }
-
-    private void checkExperimentGroupMatches(SampleIdentifier sampleIdentifier,
-            ProjectIdentifier newProjectIdentifier)
-    {
-        assert sampleIdentifier != null : "Sample identifier not specified";
-        assert newProjectIdentifier != null : "Project identifier not specified";
-        final GroupIdentifier sampleGroup = sampleIdentifier.getGroupLevel();
-        if (sampleGroup == null)
-        {
-            throw new UserFailureException(
-                    "Inconsistency detected: shared sample found in experiment.");
-        }
-        if (sampleGroup.getDatabaseInstanceCode().equals(
-                newProjectIdentifier.getDatabaseInstanceCode()) == false
-                || sampleGroup.getGroupCode().equals(newProjectIdentifier.getGroupCode()) == false)
-        {
-            throw new UserFailureException(
-                    String
-                            .format(
-                                    "Project cannot be changed to '%s' because experiment containes samples from group '%s'.",
-                                    newProjectIdentifier, sampleGroup));
-        }
-    }
-
-    public void editMaterial(String sessionToken, MaterialIdentifier identifier,
-            List<MaterialProperty> properties, Date version)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IMaterialBO materialBO = businessObjectFactory.createMaterialBO(session);
-        materialBO.edit(identifier, properties, version);
-        materialBO.save();
-
-    }
-
-    public void editSample(String sessionToken, SampleIdentifier identifier,
-            List<SampleProperty> properties, ExperimentIdentifier experimentIdentifierOrNull,
-            Date version)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final ISampleBO sampleBO = businessObjectFactory.createSampleBO(session);
-        sampleBO.edit(identifier, properties, experimentIdentifierOrNull, version);
-        sampleBO.save();
-
-    }
-
-    public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken,
-            Vocabulary vocabulary)
-    {
-        final Session session = getSessionManager().getSession(sessionToken);
-        final IVocabularyBO vocabularyBO = businessObjectFactory.createVocabularyBO(session);
-        vocabularyBO.load(vocabulary);
-        return vocabularyBO.countTermsUsageStatistics();
-    }
+public final class CommonServer extends AbstractServer<ICommonServer> implements
+		ICommonServer {
+	@Private
+	static final String DELETION_DESCRIPTION = "single deletion";
+
+	private final IAuthenticationService authenticationService;
+
+	private final ICommonBusinessObjectFactory businessObjectFactory;
+
+	private final DataStoreServerSessionManager dssSessionManager;
+
+	public CommonServer(final IAuthenticationService authenticationService,
+			final ISessionManager<Session> sessionManager,
+			DataStoreServerSessionManager dssSessionManager,
+			final IDAOFactory daoFactory,
+			final ICommonBusinessObjectFactory businessObjectFactory) {
+		super(sessionManager, daoFactory);
+		this.authenticationService = authenticationService;
+		this.dssSessionManager = dssSessionManager;
+		this.businessObjectFactory = businessObjectFactory;
+	}
+
+	ICommonBusinessObjectFactory getBusinessObjectFactory() {
+		return businessObjectFactory;
+	}
+
+	// Call this when session object is not needed but you want just to
+	// refresh/check the session.
+	private void checkSession(final String sessionToken) {
+		getSessionManager().getSession(sessionToken);
+	}
+
+	private static UserFailureException createUserFailureException(
+			final DataAccessException ex) {
+		return new UserFailureException(ex.getMostSpecificCause().getMessage(),
+				ex);
+	}
+
+	//
+	// AbstractServerWithLogger
+	//
+
+	@Override
+	protected final Class<ICommonServer> getProxyInterface() {
+		return ICommonServer.class;
+	}
+
+	//
+	// IInvocationLoggerFactory
+	//
+
+	/**
+	 * Creates a logger used to log invocations of objects of this class.
+	 */
+	public final ICommonServer createLogger(final boolean invocationSuccessful) {
+		return new CommonServerLogger(getSessionManager(), invocationSuccessful);
+	}
+
+	//
+	// IGenericServer
+	//
+
+	public final List<GroupPE> listGroups(final String sessionToken,
+			final DatabaseInstanceIdentifier identifier) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final DatabaseInstancePE databaseInstance = GroupIdentifierHelper
+				.getDatabaseInstance(identifier, getDAOFactory());
+		final List<GroupPE> groups = getDAOFactory().getGroupDAO().listGroups(
+				databaseInstance);
+		final Long homeGroupID = session.tryGetHomeGroupId();
+		for (final GroupPE group : groups) {
+			group.setHome(homeGroupID != null
+					&& homeGroupID.equals(group.getId()));
+		}
+		Collections.sort(groups);
+		return groups;
+	}
+
+	public final void registerGroup(final String sessionToken,
+			final String groupCode, final String descriptionOrNull,
+			final String groupLeaderOrNull) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IGroupBO groupBO = businessObjectFactory.createGroupBO(session);
+		groupBO.define(groupCode, descriptionOrNull, groupLeaderOrNull);
+		groupBO.save();
+	}
+
+	public final void registerPerson(final String sessionToken,
+			final String userID) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final PersonPE person = getDAOFactory().getPersonDAO()
+				.tryFindPersonByUserId(userID);
+		if (person != null) {
+			throw UserFailureException.fromTemplate(
+					"Person '%s' already exists.", userID);
+		}
+		final String applicationToken = authenticationService
+				.authenticateApplication();
+		if (applicationToken == null) {
+			throw new EnvironmentFailureException(
+					"Authentication service cannot be accessed.");
+		}
+		try {
+			final Principal principal = authenticationService.getPrincipal(
+					applicationToken, userID);
+			createPerson(principal, session.tryGetPerson());
+		} catch (final IllegalArgumentException e) {
+			throw new UserFailureException("Person '" + userID
+					+ "' unknown by the authentication service.");
+		}
+	}
+
+	public final List<RoleAssignmentPE> listRoles(final String sessionToken) {
+		checkSession(sessionToken);
+		return getDAOFactory().getRoleAssignmentDAO().listRoleAssignments();
+	}
+
+	public final void registerGroupRole(final String sessionToken,
+			final RoleCode roleCode, final GroupIdentifier groupIdentifier,
+			final String person) {
+		final Session session = getSessionManager().getSession(sessionToken);
+
+		final NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
+		newRoleAssignment.setUserId(person);
+		newRoleAssignment.setGroupIdentifier(groupIdentifier);
+		newRoleAssignment.setRole(roleCode);
+
+		final IRoleAssignmentTable table = businessObjectFactory
+				.createRoleAssignmentTable(session);
+		table.add(newRoleAssignment);
+		table.save();
+
+	}
+
+	public final void registerInstanceRole(final String sessionToken,
+			final RoleCode roleCode, final String person) {
+		final Session session = getSessionManager().getSession(sessionToken);
+
+		final NewRoleAssignment newRoleAssignment = new NewRoleAssignment();
+		newRoleAssignment.setUserId(person);
+		newRoleAssignment
+				.setDatabaseInstanceIdentifier(new DatabaseInstanceIdentifier(
+						DatabaseInstanceIdentifier.HOME));
+		newRoleAssignment.setRole(roleCode);
+
+		final IRoleAssignmentTable table = businessObjectFactory
+				.createRoleAssignmentTable(session);
+		table.add(newRoleAssignment);
+		table.save();
+
+	}
+
+	public final void deleteGroupRole(final String sessionToken,
+			final RoleCode roleCode, final GroupIdentifier groupIdentifier,
+			final String person) {
+		final Session session = getSessionManager().getSession(sessionToken);
+
+		final RoleAssignmentPE roleAssignment = getDAOFactory()
+				.getRoleAssignmentDAO().tryFindGroupRoleAssignment(roleCode,
+						groupIdentifier.getGroupCode(), person);
+		if (roleAssignment == null) {
+			throw new UserFailureException("Given group role does not exist.");
+		}
+		final PersonPE personPE = session.tryGetPerson();
+		if (roleAssignment.getPerson().equals(personPE)
+				&& roleAssignment.getRole().equals(RoleCode.ADMIN)) {
+			boolean isInstanceAdmin = false;
+			for (final RoleAssignmentPE roleAssigment : personPE
+					.getRoleAssignments()) {
+				if (roleAssigment.getDatabaseInstance() != null
+						&& roleAssigment.getRole().equals(RoleCode.ADMIN)) {
+					isInstanceAdmin = true;
+				}
+			}
+			if (isInstanceAdmin == false) {
+				throw new UserFailureException(
+						"For safety reason you cannot give away your own group admin power. "
+								+ "Ask instance admin to do that for you.");
+			}
+		}
+		getDAOFactory().getRoleAssignmentDAO().deleteRoleAssignment(
+				roleAssignment);
+	}
+
+	public final void deleteInstanceRole(final String sessionToken,
+			final RoleCode roleCode, final String person) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IRoleAssignmentDAO roleAssignmentDAO = getDAOFactory()
+				.getRoleAssignmentDAO();
+		final RoleAssignmentPE roleAssignment = roleAssignmentDAO
+				.tryFindInstanceRoleAssignment(roleCode, person);
+		if (roleAssignment == null) {
+			throw new UserFailureException(
+					"Given database instance role does not exist.");
+		}
+		if (roleAssignment.getPerson().equals(session.tryGetPerson())
+				&& roleAssignment.getRole().equals(RoleCode.ADMIN)
+				&& roleAssignment.getDatabaseInstance() != null) {
+			throw new UserFailureException(
+					"For safety reason you cannot give away your own omnipotence. "
+							+ "Ask another instance admin to do that for you.");
+		}
+		roleAssignmentDAO.deleteRoleAssignment(roleAssignment);
+	}
+
+	public final List<PersonPE> listPersons(final String sessionToken) {
+		checkSession(sessionToken);
+		final List<PersonPE> persons = getDAOFactory().getPersonDAO()
+				.listPersons();
+		Collections.sort(persons);
+		return persons;
+	}
+
+	public final List<ProjectPE> listProjects(final String sessionToken) {
+		checkSession(sessionToken);
+		final List<ProjectPE> projects = getDAOFactory().getProjectDAO()
+				.listProjects();
+		Collections.sort(projects);
+		return projects;
+	}
+
+	public final List<SampleTypePE> listSampleTypes(final String sessionToken) {
+		checkSession(sessionToken);
+		final List<SampleTypePE> sampleTypes = getDAOFactory()
+				.getSampleTypeDAO().listSampleTypes();
+		Collections.sort(sampleTypes);
+		return sampleTypes;
+	}
+
+	public final List<SamplePE> listSamples(final String sessionToken,
+			final ListSampleCriteriaDTO criteria) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final ISampleTable sampleTable = businessObjectFactory
+				.createSampleTable(session);
+		sampleTable.loadSamplesByCriteria(criteria);
+		sampleTable.enrichWithValidProcedure();
+		sampleTable.enrichWithProperties();
+		final List<SamplePE> samples = sampleTable.getSamples();
+		Collections.sort(samples);
+		return samples;
+	}
+
+	public final List<ExternalDataPE> listExternalData(
+			final String sessionToken, final SampleIdentifier identifier) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IExternalDataTable externalDataTable = businessObjectFactory
+				.createExternalDataTable(session);
+		externalDataTable.loadBySampleIdentifier(identifier);
+		return getSortedExternalDataFrom(externalDataTable);
+	}
+
+	public List<ExternalDataPE> listExternalData(String sessionToken,
+			ExperimentIdentifier identifier) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IExternalDataTable externalDataTable = businessObjectFactory
+				.createExternalDataTable(session);
+		externalDataTable.loadByExperimentIdentifier(identifier);
+		return getSortedExternalDataFrom(externalDataTable);
+	}
+
+	private List<ExternalDataPE> getSortedExternalDataFrom(
+			final IExternalDataTable externalDataTable) {
+		final List<ExternalDataPE> externalData = externalDataTable
+				.getExternalData();
+		Collections.sort(externalData);
+		return externalData;
+	}
+
+	public final List<PropertyTypePE> listPropertyTypes(
+			final String sessionToken) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IPropertyTypeTable propertyTypeTable = businessObjectFactory
+				.createPropertyTypeTable(session);
+		propertyTypeTable.load();
+		propertyTypeTable.enrichWithRelations();
+		final List<PropertyTypePE> propertyTypes = propertyTypeTable
+				.getPropertyTypes();
+		Collections.sort(propertyTypes);
+		return propertyTypes;
+	}
+
+	public final List<SearchHit> listMatchingEntities(
+			final String sessionToken,
+			final SearchableEntity[] searchableEntities, final String queryText) {
+		checkSession(sessionToken);
+		final List<SearchHit> list = new ArrayList<SearchHit>();
+		try {
+			for (final SearchableEntity searchableEntity : searchableEntities) {
+				final List<SearchHit> entities = getDAOFactory()
+						.getHibernateSearchDAO().searchEntitiesByTerm(
+								searchableEntity.getMatchingEntityClass(),
+								queryText);
+				list.addAll(entities);
+			}
+		} catch (final DataAccessException ex) {
+			throw createUserFailureException(ex);
+		}
+		return list;
+	}
+
+	public final List<ExperimentPE> listExperiments(final String sessionToken,
+			final ExperimentTypePE experimentType,
+			final ProjectIdentifier projectIdentifier) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IExperimentTable experimentTable = businessObjectFactory
+				.createExperimentTable(session);
+		experimentTable.load(experimentType.getCode(), projectIdentifier);
+		experimentTable.enrichWithProperties();
+		final List<ExperimentPE> experiments = experimentTable.getExperiments();
+		Collections.sort(experiments);
+		return experiments;
+	}
+
+	public final List<ExperimentTypePE> listExperimentTypes(
+			final String sessionToken) {
+		return listEntityTypes(sessionToken, EntityKind.EXPERIMENT);
+	}
+
+	public List<MaterialTypePE> listMaterialTypes(String sessionToken) {
+		return listEntityTypes(sessionToken, EntityKind.MATERIAL);
+	}
+
+	private <T extends EntityTypePE> List<T> listEntityTypes(
+			String sessionToken, EntityKind entityKind) {
+		checkSession(sessionToken);
+		final List<T> types = getDAOFactory().getEntityTypeDAO(entityKind)
+				.listEntityTypes();
+		Collections.sort(types);
+		return types;
+	}
+
+	public final List<DataTypePE> listDataTypes(final String sessionToken) {
+		assert sessionToken != null : "Unspecified session token";
+		checkSession(sessionToken);
+		final List<DataTypePE> dataTypes = getDAOFactory().getPropertyTypeDAO()
+				.listDataTypes();
+		Collections.sort(dataTypes);
+		return dataTypes;
+	}
+
+	public final List<VocabularyPE> listVocabularies(final String sessionToken,
+			final boolean withTerms, boolean excludeInternal) {
+		assert sessionToken != null : "Unspecified session token";
+		checkSession(sessionToken);
+		final List<VocabularyPE> vocabularies = getDAOFactory()
+				.getVocabularyDAO().listVocabularies(excludeInternal);
+		if (withTerms) {
+			for (final VocabularyPE vocabularyPE : vocabularies) {
+				enrichWithTerms(vocabularyPE);
+			}
+		}
+		Collections.sort(vocabularies);
+		return vocabularies;
+	}
+
+	private void enrichWithTerms(final VocabularyPE vocabularyPE) {
+		HibernateUtils.initialize(vocabularyPE.getTerms());
+	}
+
+	public String assignPropertyType(final String sessionToken,
+			final EntityKind entityKind, final String propertyTypeCode,
+			final String entityTypeCode, final boolean isMandatory,
+			final String defaultValue) {
+		assert sessionToken != null : "Unspecified session token";
+		Session session = getSessionManager().getSession(sessionToken);
+
+		IEntityTypePropertyTypeBO etptBO = businessObjectFactory
+				.createEntityTypePropertyTypeBO(session, entityKind);
+		etptBO.createAssignment(propertyTypeCode, entityTypeCode, isMandatory,
+				defaultValue);
+		return String.format(
+				"%s property type '%s' successfully assigned to %s type '%s'",
+				isMandatory ? "Mandatory" : "Optional", propertyTypeCode,
+				entityKind.getLabel(), entityTypeCode);
+
+	}
+
+	public final void registerPropertyType(final String sessionToken,
+			final PropertyType propertyType) {
+		assert sessionToken != null : "Unspecified session token";
+		assert propertyType != null : "Unspecified property type";
+
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IPropertyTypeBO propertyTypeBO = businessObjectFactory
+				.createPropertyTypeBO(session);
+		propertyTypeBO.define(propertyType);
+		propertyTypeBO.save();
+	}
+
+	public final void registerVocabulary(final String sessionToken,
+			final Vocabulary vocabulary) {
+		assert sessionToken != null : "Unspecified session token";
+		assert vocabulary != null : "Unspecified vocabulary";
+
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IVocabularyBO vocabularyBO = businessObjectFactory
+				.createVocabularyBO(session);
+		vocabularyBO.define(vocabulary);
+		vocabularyBO.save();
+	}
+
+	public void registerProject(String sessionToken,
+			ProjectIdentifier projectIdentifier, String description,
+			String leaderId) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IProjectBO projectBO = businessObjectFactory
+				.createProjectBO(session);
+		projectBO.define(projectIdentifier, description, leaderId);
+		projectBO.save();
+
+	}
+
+	public List<ExternalDataPE> searchForDataSets(String sessionToken,
+			DataSetSearchCriteria criteria) {
+		checkSession(sessionToken);
+		try {
+			IHibernateSearchDAO searchDAO = getDAOFactory()
+					.getHibernateSearchDAO();
+			return searchDAO.searchForDataSets(criteria);
+		} catch (final DataAccessException ex) {
+			throw createUserFailureException(ex);
+		}
+	}
+
+	public List<MaterialPE> listMaterials(String sessionToken,
+			MaterialTypePE materialType) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IMaterialTable materialTable = businessObjectFactory
+				.createMaterialTable(session);
+		materialTable.load(materialType.getCode());
+		final List<MaterialPE> materials = materialTable.getMaterials();
+		Collections.sort(materials);
+		return materials;
+	}
+
+	public void registerSampleType(String sessionToken, SampleType entityType) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		try {
+			IEntityTypeBO entityTypeBO = businessObjectFactory
+					.createEntityTypeBO(session);
+			entityTypeBO.define(entityType);
+			entityTypeBO.save();
+		} catch (final DataAccessException ex) {
+			throw createUserFailureException(ex);
+		}
+	}
+
+	public void registerMaterialType(String sessionToken,
+			MaterialType entityType) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		try {
+			IEntityTypeBO entityTypeBO = businessObjectFactory
+					.createEntityTypeBO(session);
+			entityTypeBO.define(entityType);
+			entityTypeBO.save();
+		} catch (final DataAccessException ex) {
+			throw createUserFailureException(ex);
+		}
+	}
+
+	public void registerExperimentType(String sessionToken,
+			ExperimentType entityType) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		try {
+			IEntityTypeBO entityTypeBO = businessObjectFactory
+					.createEntityTypeBO(session);
+			entityTypeBO.define(entityType);
+			entityTypeBO.save();
+		} catch (final DataAccessException ex) {
+			throw createUserFailureException(ex);
+		}
+	}
+
+	public void deleteDataSets(String sessionToken, List<String> dataSetCodes,
+			String reason) {
+		Session session = getSessionManager().getSession(sessionToken);
+		IExternalDataDAO externalDataDAO = getDAOFactory().getExternalDataDAO();
+		List<ExternalDataPE> dataSets = new ArrayList<ExternalDataPE>();
+		List<String> locations = new ArrayList<String>();
+		for (String dataSetCode : dataSetCodes) {
+			ExternalDataPE dataSet = externalDataDAO
+					.tryToFindFullDataSetByCode(dataSetCode);
+			if (dataSet != null) {
+				dataSets.add(dataSet);
+				locations.add(dataSet.getLocation());
+			}
+		}
+		assertDataSetsAreKnown(dataSets, locations);
+
+		for (ExternalDataPE dataSet : dataSets) {
+			externalDataDAO.markAsDeleted(dataSet, session.tryGetPerson(),
+					DELETION_DESCRIPTION, reason);
+		}
+		Collection<DataStoreServerSession> sessions = dssSessionManager
+				.getSessions();
+		for (DataStoreServerSession dssSession : sessions) {
+			dssSession.getService().deleteDataSets(
+					dssSession.getSessionToken(), locations);
+		}
+	}
+
+	private void assertDataSetsAreKnown(List<ExternalDataPE> dataSets,
+			List<String> locations) {
+		Set<String> knownLocations = new LinkedHashSet<String>();
+		Collection<DataStoreServerSession> sessions = dssSessionManager
+				.getSessions();
+		for (DataStoreServerSession session : sessions) {
+			IDataStoreService service = session.getService();
+			String dssSessionToken = session.getSessionToken();
+			knownLocations.addAll(service.getKnownDataSets(dssSessionToken,
+					locations));
+		}
+		List<String> unknownDataSets = new ArrayList<String>();
+		for (ExternalDataPE dataSet : dataSets) {
+			if (knownLocations.contains(dataSet.getLocation()) == false) {
+				unknownDataSets.add(dataSet.getCode());
+			}
+		}
+		if (unknownDataSets.isEmpty() == false) {
+			throw new UserFailureException(
+					"The following data sets are unknown by any registered Data Store Server. "
+							+ "May be the responsible Data Store Server is not running.\n"
+							+ unknownDataSets);
+		}
+	}
+
+	public void editExperiment(String sessionToken,
+			ExperimentIdentifier identifier,
+			List<ExperimentProperty> properties,
+			List<AttachmentPE> attachments,
+			ProjectIdentifier newProjectIdentifier, Date version) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		if (newProjectIdentifier.equals(identifier) == false) {
+			checkExternalData(identifier, session);
+			checkSampleConsistency(identifier, newProjectIdentifier, session);
+		}
+
+		final IExperimentBO experimentBO = businessObjectFactory
+				.createExperimentBO(session);
+		experimentBO.edit(identifier, properties, attachments,
+				newProjectIdentifier, version);
+		experimentBO.save();
+	}
+
+	private void checkExternalData(ExperimentIdentifier identifier,
+			final Session session) {
+		final IExternalDataTable externalDataTable = businessObjectFactory
+				.createExternalDataTable(session);
+		externalDataTable.loadByExperimentIdentifier(identifier);
+		if (externalDataTable.getExternalData().size() > 0) {
+			throw new UserFailureException(
+					"Changing the project of experiment containing data sets is not allowed.");
+		}
+	}
+
+	private void checkSampleConsistency(ExperimentIdentifier identifier,
+			ProjectIdentifier newProjectIdentifier, final Session session) {
+		ListSampleCriteriaDTO criteria = ListSampleCriteriaDTO
+				.createExperimentIdentifier(identifier);
+		final ISampleTable sampleTable = businessObjectFactory
+				.createSampleTable(session);
+		sampleTable.loadSamplesByCriteria(criteria);
+		final List<SamplePE> samples = sampleTable.getSamples();
+		if (samples.size() > 0) {
+			checkExperimentGroupMatches(samples.get(0).getSampleIdentifier(),
+					newProjectIdentifier);
+		}
+	}
+
+	private void checkExperimentGroupMatches(SampleIdentifier sampleIdentifier,
+			ProjectIdentifier newProjectIdentifier) {
+		assert sampleIdentifier != null : "Sample identifier not specified";
+		assert newProjectIdentifier != null : "Project identifier not specified";
+		final GroupIdentifier sampleGroup = sampleIdentifier.getGroupLevel();
+		if (sampleGroup == null) {
+			throw new UserFailureException(
+					"Inconsistency detected: shared sample found in experiment.");
+		}
+		if (sampleGroup.getDatabaseInstanceCode().equals(
+				newProjectIdentifier.getDatabaseInstanceCode()) == false
+				|| sampleGroup.getGroupCode().equals(
+						newProjectIdentifier.getGroupCode()) == false) {
+			throw new UserFailureException(
+					String
+							.format(
+									"Project cannot be changed to '%s' because experiment containes samples from group '%s'.",
+									newProjectIdentifier, sampleGroup));
+		}
+	}
+
+	public void editMaterial(String sessionToken,
+			MaterialIdentifier identifier, List<MaterialProperty> properties,
+			Date version) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IMaterialBO materialBO = businessObjectFactory
+				.createMaterialBO(session);
+		materialBO.edit(identifier, properties, version);
+		materialBO.save();
+
+	}
+
+	public void editSample(String sessionToken, SampleIdentifier identifier,
+			List<SampleProperty> properties,
+			ExperimentIdentifier experimentIdentifierOrNull, Date version) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final ISampleBO sampleBO = businessObjectFactory
+				.createSampleBO(session);
+		sampleBO.edit(identifier, properties, experimentIdentifierOrNull,
+				version);
+		sampleBO.save();
+
+	}
+
+	public List<VocabularyTermWithStats> listVocabularyTerms(
+			String sessionToken, Vocabulary vocabulary) {
+		final Session session = getSessionManager().getSession(sessionToken);
+		final IVocabularyBO vocabularyBO = businessObjectFactory
+				.createVocabularyBO(session);
+		vocabularyBO.load(vocabulary);
+		return vocabularyBO.countTermsUsageStatistics();
+	}
+
+	public List<DataSetTypePE> listDataSetTypes(String sessionToken) {
+		return listEntityTypes(sessionToken, EntityKind.DATA_SET);
+	}
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index df7dca9dacd7a22b519a4d98b69924cbccbb8484..915965eb48eb9cf835bdc14dc58aaf3f23eda8d6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -34,7 +34,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
@@ -65,287 +65,291 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 
 /**
- * Logger class for {@link CommonServer} which creates readable logs of method invocations.
+ * Logger class for {@link CommonServer} which creates readable logs of method
+ * invocations.
  * 
  * @author Franz-Josef Elmer
  */
-final class CommonServerLogger extends AbstractServerLogger implements ICommonServer
-{
-    /**
-     * Creates an instance for the specified session manager and invocation status. The session
-     * manager is used to retrieve user information which will be a part of the log message.
-     */
-    CommonServerLogger(final ISessionManager<Session> sessionManager,
-            final boolean invocationSuccessful)
-    {
-        super(sessionManager, invocationSuccessful);
-    }
-
-    //
-    // IGenericServer
-    //
-
-    public List<GroupPE> listGroups(final String sessionToken,
-            final DatabaseInstanceIdentifier identifier)
-    {
-        final String command = "list_groups";
-        if (identifier == null || identifier.getDatabaseInstanceCode() == null)
-        {
-            logAccess(sessionToken, command);
-        } else
-        {
-            logAccess(sessionToken, command, "DATABASE-INSTANCE(%s)", identifier);
-        }
-        return null;
-    }
-
-    public void registerGroup(final String sessionToken, final String groupCode,
-            final String descriptionOrNull, final String groupLeaderOrNull)
-    {
-        logTracking(sessionToken, "register_group", "CODE(%s)", groupCode);
-    }
-
-    public List<PersonPE> listPersons(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_persons");
-        return null;
-    }
-
-    public void registerPerson(final String sessionToken, final String userID)
-    {
-        logTracking(sessionToken, "register_person", "CODE(%s)", userID);
-
-    }
-
-    public List<RoleAssignmentPE> listRoles(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_roles");
-        return null;
-    }
-
-    public void registerGroupRole(final String sessionToken, final RoleCode roleCode,
-            final GroupIdentifier groupIdentifier, final String person)
-    {
-        logTracking(sessionToken, "register_role", "ROLE(%s) GROUP(%s) PERSON(%s)", roleCode,
-                groupIdentifier, person);
-
-    }
-
-    public void registerInstanceRole(final String sessionToken, final RoleCode roleCode,
-            final String person)
-    {
-        logTracking(sessionToken, "register_role", "ROLE(%s)  PERSON(%s)", roleCode, person);
-
-    }
-
-    public void deleteGroupRole(final String sessionToken, final RoleCode roleCode,
-            final GroupIdentifier groupIdentifier, final String person)
-    {
-        logTracking(sessionToken, "delete_role", "ROLE(%s) GROUP(%s) PERSON(%s)", roleCode,
-                groupIdentifier, person);
-
-    }
-
-    public void deleteInstanceRole(final String sessionToken, final RoleCode roleCode,
-            final String person)
-    {
-        logTracking(sessionToken, "delete_role", "ROLE(%s) PERSON(%s)", roleCode, person);
-
-    }
-
-    public final List<SampleTypePE> listSampleTypes(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_sample_types");
-        return null;
-    }
-
-    public final List<SamplePE> listSamples(final String sessionToken,
-            final ListSampleCriteriaDTO criteria)
-    {
-        logAccess(sessionToken, "list_samples", "TYPE(%s) OWNERS(%s) CONTAINER(%s) EXPERIMENT(%s)",
-                criteria.getSampleType(), criteria.getOwnerIdentifiers(), criteria
-                        .getContainerIdentifier(), criteria.getExperimentIdentifier());
-        return null;
-    }
-
-    public final List<SamplePropertyPE> listSamplesProperties(final String sessionToken,
-            final ListSampleCriteriaDTO criteria, final List<PropertyTypePE> propertyCodes)
-    {
-        logAccess(sessionToken, "list_samples_properties", "CRITERIA(%s) PROPERTIES(%s)", criteria,
-                propertyCodes.size());
-        return null;
-    }
-
-    public final SampleGenerationDTO getSampleInfo(final String sessionToken,
-            final SampleIdentifier identifier)
-    {
-        logAccess(sessionToken, "get_sample_info", "IDENTIFIER(%s)", identifier);
-        return null;
-    }
-
-    public final List<ExternalDataPE> listExternalData(final String sessionToken,
-            final SampleIdentifier identifier)
-    {
-        logAccess(sessionToken, "list_external_data", "IDENTIFIER(%s)", identifier);
-        return null;
-    }
-
-    public List<ExternalDataPE> listExternalData(String sessionToken,
-            ExperimentIdentifier identifier)
-    {
-        logAccess(sessionToken, "list_external_data", "IDENTIFIER(%s)", identifier);
-        return null;
-    }
-
-    public final List<SearchHit> listMatchingEntities(final String sessionToken,
-            final SearchableEntity[] searchableEntities, final String queryText)
-    {
-        logAccess(sessionToken, "list_matching_entities", "SEARCHABLE-ENTITIES(%s) QUERY-TEXT(%s)",
-                Arrays.toString(searchableEntities), queryText);
-        return null;
-    }
-
-    public void registerSample(final String sessionToken, final NewSample newSample)
-    {
-        logTracking(sessionToken, "register_sample", "SAMPLE_TYPE(%s) SAMPLE(%S)", newSample
-                .getSampleType(), newSample.getIdentifier());
-    }
-
-    public List<ExperimentPE> listExperiments(final String sessionToken,
-            final ExperimentTypePE experimentType, final ProjectIdentifier project)
-    {
-        logAccess(sessionToken, "list_experiments", "TYPE(%s) PROJECT(%s)", experimentType, project);
-        return null;
-    }
-
-    public List<ProjectPE> listProjects(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_projects");
-        return null;
-    }
-
-    public List<ExperimentTypePE> listExperimentTypes(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_experiment_types");
-        return null;
-    }
-
-    public List<PropertyTypePE> listPropertyTypes(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_property_types");
-        return null;
-    }
-
-    public final List<DataTypePE> listDataTypes(final String sessionToken)
-    {
-        logAccess(sessionToken, "list_data_types");
-        return null;
-    }
-
-    public final List<VocabularyPE> listVocabularies(final String sessionToken, boolean withTerms,
-            boolean excludeInternal)
-    {
-        logAccess(sessionToken, "list_vocabularies");
-        return null;
-    }
-
-    public String assignPropertyType(final String sessionToken, final EntityKind entityKind,
-            final String propertyTypeCode, final String entityTypeCode, final boolean isMandatory,
-            final String defaultValue)
-    {
-        final String entityTypeFormat = entityKind.name() + "_TYPE(%S)";
-        logTracking(sessionToken, "assign_property_type", " PROPERTY_TYPE(%S) " + entityTypeFormat
-                + " MANDATORY(%S) DEFAULT(%S)", propertyTypeCode, entityTypeCode, isMandatory,
-                defaultValue);
-        return null;
-    }
-
-    public final void registerPropertyType(final String sessionToken,
-            final PropertyType propertyType)
-    {
-        logTracking(sessionToken, "register_property_type", "PROPERTY_TYPE(%s)", propertyType
-                .getCode());
-    }
-
-    public final void registerVocabulary(final String sessionToken, final Vocabulary vocabulary)
-    {
-        logTracking(sessionToken, "register_vocabulary", "VOCABULARY(%s)", vocabulary.getCode());
-    }
-
-    public void registerProject(String sessionToken, ProjectIdentifier projectIdentifier,
-            String description, String leaderId)
-    {
-        logTracking(sessionToken, "register_project", "PROJECT(%s)", projectIdentifier);
-    }
-
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
-            DataSetSearchCriteria criteria)
-    {
-        logAccess(sessionToken, "search_for_datasets");
-        return null;
-    }
-
-    public List<MaterialTypePE> listMaterialTypes(String sessionToken)
-    {
-        logAccess(sessionToken, "list_material_types");
-        return null;
-    }
-
-    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType)
-    {
-        logAccess(sessionToken, "list_materials", "TYPE(%s)", materialType);
-        return null;
-    }
-
-    public void registerMaterialType(String sessionToken, MaterialType entityType)
-    {
-        logTracking(sessionToken, "register_material_type", "CODE(%s)", entityType.getCode());
-    }
-
-    public void registerSampleType(String sessionToken, SampleType entityType)
-    {
-        logTracking(sessionToken, "register_sample_type", "CODE(%s)", entityType.getCode());
-    }
-
-    public void registerExperimentType(String sessionToken, ExperimentType entityType)
-    {
-        logTracking(sessionToken, "register_experiment_type", "CODE(%s)", entityType.getCode());
-    }
-
-    public void editExperiment(String sessionToken, ExperimentIdentifier experimentIdentifier,
-            List<ExperimentProperty> properties, List<AttachmentPE> attachments,
-            ProjectIdentifier newProjectIdentifierOrNull, Date version)
-    {
-        logTracking(sessionToken, "edit_experiment",
-                "EXPERIMENT(%s) ATTACHMENTS_ADDED(%s) NEW_PROJECT(%s)", experimentIdentifier,
-                attachments.size(), newProjectIdentifierOrNull);
-    }
-
-    public void deleteDataSets(String sessionToken, List<String> dataSetCodes, String reason)
-    {
-        logTracking(sessionToken, "delete_data_sets", "CODES(%s) REASON(%s)", dataSetCodes, reason);
-    }
-
-    public void editMaterial(String sessionToken, MaterialIdentifier identifier,
-            List<MaterialProperty> properties, Date version)
-    {
-        logTracking(sessionToken, "edit_material", "MATERIAL(%s)", identifier);
-
-    }
-
-    public void editSample(String sessionToken, SampleIdentifier identifier,
-            List<SampleProperty> properties, ExperimentIdentifier experimentIdentifierOrNull,
-            Date version)
-    {
-        logTracking(sessionToken, "edit_sample", "SAMPLE(%s), CHANGE_TO_EXPERIMENT(%S)",
-                identifier, experimentIdentifierOrNull);
-
-    }
-
-    public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken,
-            Vocabulary vocabulary)
-    {
-        logAccess(sessionToken, "list_vocabulary_terms", "VOCABULARY(%s)", vocabulary.getCode());
-        return null;
-    }
+final class CommonServerLogger extends AbstractServerLogger implements
+		ICommonServer {
+	/**
+	 * Creates an instance for the specified session manager and invocation
+	 * status. The session manager is used to retrieve user information which
+	 * will be a part of the log message.
+	 */
+	CommonServerLogger(final ISessionManager<Session> sessionManager,
+			final boolean invocationSuccessful) {
+		super(sessionManager, invocationSuccessful);
+	}
+
+	//
+	// IGenericServer
+	//
+
+	public List<GroupPE> listGroups(final String sessionToken,
+			final DatabaseInstanceIdentifier identifier) {
+		final String command = "list_groups";
+		if (identifier == null || identifier.getDatabaseInstanceCode() == null) {
+			logAccess(sessionToken, command);
+		} else {
+			logAccess(sessionToken, command, "DATABASE-INSTANCE(%s)",
+					identifier);
+		}
+		return null;
+	}
+
+	public void registerGroup(final String sessionToken,
+			final String groupCode, final String descriptionOrNull,
+			final String groupLeaderOrNull) {
+		logTracking(sessionToken, "register_group", "CODE(%s)", groupCode);
+	}
+
+	public List<PersonPE> listPersons(final String sessionToken) {
+		logAccess(sessionToken, "list_persons");
+		return null;
+	}
+
+	public void registerPerson(final String sessionToken, final String userID) {
+		logTracking(sessionToken, "register_person", "CODE(%s)", userID);
+
+	}
+
+	public List<RoleAssignmentPE> listRoles(final String sessionToken) {
+		logAccess(sessionToken, "list_roles");
+		return null;
+	}
+
+	public void registerGroupRole(final String sessionToken,
+			final RoleCode roleCode, final GroupIdentifier groupIdentifier,
+			final String person) {
+		logTracking(sessionToken, "register_role",
+				"ROLE(%s) GROUP(%s) PERSON(%s)", roleCode, groupIdentifier,
+				person);
+
+	}
+
+	public void registerInstanceRole(final String sessionToken,
+			final RoleCode roleCode, final String person) {
+		logTracking(sessionToken, "register_role", "ROLE(%s)  PERSON(%s)",
+				roleCode, person);
+
+	}
+
+	public void deleteGroupRole(final String sessionToken,
+			final RoleCode roleCode, final GroupIdentifier groupIdentifier,
+			final String person) {
+		logTracking(sessionToken, "delete_role",
+				"ROLE(%s) GROUP(%s) PERSON(%s)", roleCode, groupIdentifier,
+				person);
+
+	}
+
+	public void deleteInstanceRole(final String sessionToken,
+			final RoleCode roleCode, final String person) {
+		logTracking(sessionToken, "delete_role", "ROLE(%s) PERSON(%s)",
+				roleCode, person);
+
+	}
+
+	public final List<SampleTypePE> listSampleTypes(final String sessionToken) {
+		logAccess(sessionToken, "list_sample_types");
+		return null;
+	}
+
+	public final List<SamplePE> listSamples(final String sessionToken,
+			final ListSampleCriteriaDTO criteria) {
+		logAccess(sessionToken, "list_samples",
+				"TYPE(%s) OWNERS(%s) CONTAINER(%s) EXPERIMENT(%s)", criteria
+						.getSampleType(), criteria.getOwnerIdentifiers(),
+				criteria.getContainerIdentifier(), criteria
+						.getExperimentIdentifier());
+		return null;
+	}
+
+	public final List<SamplePropertyPE> listSamplesProperties(
+			final String sessionToken, final ListSampleCriteriaDTO criteria,
+			final List<PropertyTypePE> propertyCodes) {
+		logAccess(sessionToken, "list_samples_properties",
+				"CRITERIA(%s) PROPERTIES(%s)", criteria, propertyCodes.size());
+		return null;
+	}
+
+	public final SampleGenerationDTO getSampleInfo(final String sessionToken,
+			final SampleIdentifier identifier) {
+		logAccess(sessionToken, "get_sample_info", "IDENTIFIER(%s)", identifier);
+		return null;
+	}
+
+	public final List<ExternalDataPE> listExternalData(
+			final String sessionToken, final SampleIdentifier identifier) {
+		logAccess(sessionToken, "list_external_data", "IDENTIFIER(%s)",
+				identifier);
+		return null;
+	}
+
+	public List<ExternalDataPE> listExternalData(String sessionToken,
+			ExperimentIdentifier identifier) {
+		logAccess(sessionToken, "list_external_data", "IDENTIFIER(%s)",
+				identifier);
+		return null;
+	}
+
+	public final List<SearchHit> listMatchingEntities(
+			final String sessionToken,
+			final SearchableEntity[] searchableEntities, final String queryText) {
+		logAccess(sessionToken, "list_matching_entities",
+				"SEARCHABLE-ENTITIES(%s) QUERY-TEXT(%s)", Arrays
+						.toString(searchableEntities), queryText);
+		return null;
+	}
+
+	public void registerSample(final String sessionToken,
+			final NewSample newSample) {
+		logTracking(sessionToken, "register_sample",
+				"SAMPLE_TYPE(%s) SAMPLE(%S)", newSample.getSampleType(),
+				newSample.getIdentifier());
+	}
+
+	public List<ExperimentPE> listExperiments(final String sessionToken,
+			final ExperimentTypePE experimentType,
+			final ProjectIdentifier project) {
+		logAccess(sessionToken, "list_experiments", "TYPE(%s) PROJECT(%s)",
+				experimentType, project);
+		return null;
+	}
+
+	public List<ProjectPE> listProjects(final String sessionToken) {
+		logAccess(sessionToken, "list_projects");
+		return null;
+	}
+
+	public List<ExperimentTypePE> listExperimentTypes(final String sessionToken) {
+		logAccess(sessionToken, "list_experiment_types");
+		return null;
+	}
+
+	public List<PropertyTypePE> listPropertyTypes(final String sessionToken) {
+		logAccess(sessionToken, "list_property_types");
+		return null;
+	}
+
+	public final List<DataTypePE> listDataTypes(final String sessionToken) {
+		logAccess(sessionToken, "list_data_types");
+		return null;
+	}
+
+	public final List<VocabularyPE> listVocabularies(final String sessionToken,
+			boolean withTerms, boolean excludeInternal) {
+		logAccess(sessionToken, "list_vocabularies");
+		return null;
+	}
+
+	public String assignPropertyType(final String sessionToken,
+			final EntityKind entityKind, final String propertyTypeCode,
+			final String entityTypeCode, final boolean isMandatory,
+			final String defaultValue) {
+		final String entityTypeFormat = entityKind.name() + "_TYPE(%S)";
+		logTracking(sessionToken, "assign_property_type", " PROPERTY_TYPE(%S) "
+				+ entityTypeFormat + " MANDATORY(%S) DEFAULT(%S)",
+				propertyTypeCode, entityTypeCode, isMandatory, defaultValue);
+		return null;
+	}
+
+	public final void registerPropertyType(final String sessionToken,
+			final PropertyType propertyType) {
+		logTracking(sessionToken, "register_property_type",
+				"PROPERTY_TYPE(%s)", propertyType.getCode());
+	}
+
+	public final void registerVocabulary(final String sessionToken,
+			final Vocabulary vocabulary) {
+		logTracking(sessionToken, "register_vocabulary", "VOCABULARY(%s)",
+				vocabulary.getCode());
+	}
+
+	public void registerProject(String sessionToken,
+			ProjectIdentifier projectIdentifier, String description,
+			String leaderId) {
+		logTracking(sessionToken, "register_project", "PROJECT(%s)",
+				projectIdentifier);
+	}
+
+	public List<ExternalDataPE> searchForDataSets(String sessionToken,
+			DataSetSearchCriteria criteria) {
+		logAccess(sessionToken, "search_for_datasets");
+		return null;
+	}
+
+	public List<MaterialTypePE> listMaterialTypes(String sessionToken) {
+		logAccess(sessionToken, "list_material_types");
+		return null;
+	}
+
+	public List<MaterialPE> listMaterials(String sessionToken,
+			MaterialTypePE materialType) {
+		logAccess(sessionToken, "list_materials", "TYPE(%s)", materialType);
+		return null;
+	}
+
+	public void registerMaterialType(String sessionToken,
+			MaterialType entityType) {
+		logTracking(sessionToken, "register_material_type", "CODE(%s)",
+				entityType.getCode());
+	}
+
+	public void registerSampleType(String sessionToken, SampleType entityType) {
+		logTracking(sessionToken, "register_sample_type", "CODE(%s)",
+				entityType.getCode());
+	}
+
+	public void registerExperimentType(String sessionToken,
+			ExperimentType entityType) {
+		logTracking(sessionToken, "register_experiment_type", "CODE(%s)",
+				entityType.getCode());
+	}
+
+	public void editExperiment(String sessionToken,
+			ExperimentIdentifier experimentIdentifier,
+			List<ExperimentProperty> properties,
+			List<AttachmentPE> attachments,
+			ProjectIdentifier newProjectIdentifierOrNull, Date version) {
+		logTracking(sessionToken, "edit_experiment",
+				"EXPERIMENT(%s) ATTACHMENTS_ADDED(%s) NEW_PROJECT(%s)",
+				experimentIdentifier, attachments.size(),
+				newProjectIdentifierOrNull);
+	}
+
+	public void deleteDataSets(String sessionToken, List<String> dataSetCodes,
+			String reason) {
+		logTracking(sessionToken, "delete_data_sets", "CODES(%s) REASON(%s)",
+				dataSetCodes, reason);
+	}
+
+	public void editMaterial(String sessionToken,
+			MaterialIdentifier identifier, List<MaterialProperty> properties,
+			Date version) {
+		logTracking(sessionToken, "edit_material", "MATERIAL(%s)", identifier);
+
+	}
+
+	public void editSample(String sessionToken, SampleIdentifier identifier,
+			List<SampleProperty> properties,
+			ExperimentIdentifier experimentIdentifierOrNull, Date version) {
+		logTracking(sessionToken, "edit_sample",
+				"SAMPLE(%s), CHANGE_TO_EXPERIMENT(%S)", identifier,
+				experimentIdentifierOrNull);
+
+	}
+
+	public List<VocabularyTermWithStats> listVocabularyTerms(
+			String sessionToken, Vocabulary vocabulary) {
+		logAccess(sessionToken, "list_vocabulary_terms", "VOCABULARY(%s)",
+				vocabulary.getCode());
+		return null;
+	}
+
+	public List<DataSetTypePE> listDataSetTypes(String sessionToken) {
+		logAccess(sessionToken, "list_data_set_types");
+		return null;
+	}
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IHibernateSearchDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IHibernateSearchDAO.java
index 941a9b32a605d4b4ebe7b1b2494ffd84e6e762a4..15cfe02484066b5b9569b9224ee59d35b384559e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IHibernateSearchDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IHibernateSearchDAO.java
@@ -21,7 +21,7 @@ import java.util.List;
 import org.springframework.dao.DataAccessException;
 
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IMatchingEntity;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SearchHit;
 
@@ -42,5 +42,5 @@ public interface IHibernateSearchDAO
             final Class<T> entityClass, final String searchTerm) throws DataAccessException;
 
     /** search for datasets using the specified criteria */
-    public List<DataSetSearchHitDTO> searchForDataSets(DataSetSearchCriteria criteria);
+    public List<ExternalDataPE> searchForDataSets(DataSetSearchCriteria criteria);
 }
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java
index 771d5ec64b4755baadff15dc478ff9da8ff8aa16..a8e65037adaa7e2ab426886820ec5f8786ddf7e8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAO.java
@@ -62,7 +62,6 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.LuceneQueryBuilder;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.SearchAnalyzer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IMatchingEntity;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
@@ -328,9 +327,9 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate
         }
     }
 
-    public List<DataSetSearchHitDTO> searchForDataSets(final DataSetSearchCriteria criteria)
+    public List<ExternalDataPE> searchForDataSets(final DataSetSearchCriteria criteria)
     {
-        final List<DataSetSearchHitDTO> list =
+        final List<ExternalDataPE> list =
                 AbstractDAO.cast((List<?>) getHibernateTemplate().execute(new HibernateCallback()
                     {
                         public final Object doInHibernate(final Session session)
@@ -348,7 +347,7 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate
         return list;
     }
 
-    private List<DataSetSearchHitDTO> searchForDataSets(Session session,
+    private List<ExternalDataPE> searchForDataSets(Session session,
             DataSetSearchCriteria datasetSearchCriteria)
     {
         BooleanQuery query = new BooleanQuery();
@@ -372,7 +371,7 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate
         // NOTE: there is a limit on the number of JOINs, so we have to initialize sample properties
         // manually
         initSamplesWithProperties(datasets);
-        return asDataSetHits(datasets);
+        return datasets;
     }
 
     private void initSamplesWithProperties(List<ExternalDataPE> datasets)
@@ -394,13 +393,5 @@ final class HibernateSearchDAO extends HibernateDaoSupport implements IHibernate
         }
     }
 
-    private static List<DataSetSearchHitDTO> asDataSetHits(List<ExternalDataPE> datasets)
-    {
-        List<DataSetSearchHitDTO> result = new ArrayList<DataSetSearchHitDTO>();
-        for (ExternalDataPE dataset : datasets)
-        {
-            result.add(new DataSetSearchHitDTO(dataset));
-        }
-        return result;
-    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index ddc1db0ffef5f4ccf47d472b94f60000e99432b4..2f64236ae77a43fcc218ea71b93503d39b6aa47a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCo
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.GroupIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NullableGroupIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwnerIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ExternalDataValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.GroupValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.MatchingEntityValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
@@ -43,7 +44,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
@@ -75,315 +76,346 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
  * 
  * @author Franz-Josef Elmer
  */
-public interface ICommonServer extends IServer
-{
-    /**
-     * Returns all groups which belong to the specified database instance. *
-     * 
-     * @return a sorted list of {@link GroupPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = GroupValidator.class)
-    public List<GroupPE> listGroups(String sessionToken, DatabaseInstanceIdentifier identifier);
-
-    /**
-     * Registers a new group with specified code and optional description and group leader ID.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerGroup(String sessionToken, String groupCode, String descriptionOrNull,
-            String groupLeaderOrNull);
-
-    /**
-     * Returns all persons from current instance.
-     * 
-     * @return a sorted list of {@link PersonPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<PersonPE> listPersons(String sessionToken);
-
-    /**
-     * Returns all projects.
-     * 
-     * @return a sorted list of {@link ProjectPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = ProjectValidator.class)
-    public List<ProjectPE> listProjects(String sessionToken);
-
-    /**
-     * Registers a new person.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerPerson(String sessionToken, String userID);
-
-    /**
-     * Returns a list of all roles.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public List<RoleAssignmentPE> listRoles(String sessionToken);
-
-    /**
-     * Registers a new group role.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void registerGroupRole(String sessionToken, RoleCode roleCode,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            GroupIdentifier identifier, String person);
-
-    /**
-     * Registers a new instance role.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerInstanceRole(String sessionToken, RoleCode roleCode, String person);
-
-    /**
-     * Deletes role described by given role code, group identifier and user id.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void deleteGroupRole(String sessionToken, RoleCode roleCode,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            GroupIdentifier groupIdentifier, String person);
-
-    /**
-     * Deletes role described by given role code and user id.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void deleteInstanceRole(String sessionToken, RoleCode roleCode, String person);
-
-    /**
-     * Lists sample types which are appropriate for listing.
-     * 
-     * @return a sorted list of {@link SampleTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<SampleTypePE> listSampleTypes(String sessionToken);
-
-    /**
-     * Lists samples using given configuration.
-     * 
-     * @return a sorted list of {@link SamplePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<SamplePE> listSamples(final String sessionToken,
-            final ListSampleCriteriaDTO criteria);
-
-    /**
-     * Lists experiments.
-     * 
-     * @return a sorted list of {@link ExperimentPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExperimentPE> listExperiments(final String sessionToken,
-            ExperimentTypePE experimentType,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier project);
-
-    /**
-     * For given {@link SampleIdentifier} returns the corresponding list of {@link ExternalDataPE}.
-     * 
-     * @return a sorted list of {@link ExternalDataPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExternalDataPE> listExternalData(final String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
-            final SampleIdentifier identifier);
-
-    /**
-     * For given {@link ExperimentIdentifier} returns the corresponding list of
-     * {@link ExternalDataPE}.
-     * 
-     * @return a sorted list of {@link ExternalDataPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExternalDataPE> listExternalData(final String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            final ExperimentIdentifier identifier);
-
-    /**
-     * Performs an <i>Hibernate Search</i> based on given parameters.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = MatchingEntityValidator.class)
-    public List<SearchHit> listMatchingEntities(final String sessionToken,
-            final SearchableEntity[] searchableEntities, final String queryText);
-
-    /**
-     * List experiment types.
-     * 
-     * @return a sorted list of {@link ExperimentTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExperimentTypePE> listExperimentTypes(String sessionToken);
-
-    /**
-     * List property types.
-     * 
-     * @return a sorted list of {@link PropertyTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<PropertyTypePE> listPropertyTypes(final String sessionToken);
-
-    /**
-     * Lists data types.
-     * 
-     * @return a sorted list of {@link DataTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataTypePE> listDataTypes(final String sessionToken);
-
-    /**
-     * Lists vocabularies.
-     * 
-     * @return a sorted list of {@link VocabularyPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<VocabularyPE> listVocabularies(final String sessionToken, final boolean withTerms,
-            boolean excludeInternal);
-
-    /**
-     * Registers given {@link PropertyType}.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerPropertyType(final String sessionToken, final PropertyType propertyType);
-
-    /**
-     * Assigns property type to entity type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public String assignPropertyType(final String sessionToken, final EntityKind entityKind,
-            final String propertyTypeCode, final String entityTypeCode, final boolean isMandatory,
-            final String defaultValue);
-
-    /**
-     * Registers given {@link Vocabulary}.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerVocabulary(final String sessionToken, final Vocabulary vocabulary);
-
-    /**
-     * Registers new project.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void registerProject(String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier projectIdentifier, String description, String leaderId);
-
-    /**
-     * Performs an <i>Hibernate Search</i> based on given parameters.
-     */
-    // TODO 2009-03-16 FJE, @ReturnValueFilter missing
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
-            DataSetSearchCriteria criteria);
-
-    /**
-     * List material types.
-     * 
-     * @return a sorted list of {@link MaterialTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<MaterialTypePE> listMaterialTypes(String sessionToken);
-
-    /**
-     * Lists materials.
-     * 
-     * @return a sorted list of {@link MaterialPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType);
-
-    /**
-     * Creates a new material type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerMaterialType(String sessionToken, MaterialType entityType);
-
-    /**
-     * Creates a new sample type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerSampleType(String sessionToken, SampleType entityType);
-
-    /**
-     * Creates a new experiment type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerExperimentType(String sessionToken, ExperimentType entityType);
-
-    /**
-     * Deletes specified data sets.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void deleteDataSets(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
-            List<String> dataSetCodes, String reason);
-
-    /**
-     * Saves changed experiment.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public void editExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ExperimentIdentifier experimentIdentifier, List<ExperimentProperty> properties,
-            List<AttachmentPE> attachments,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier newProjectIdentifier, Date version);
-
-    /**
-     * Saves changed material.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void editMaterial(String sessionToken, MaterialIdentifier identifier,
-            List<MaterialProperty> properties, Date version);
-
-    /**
-     * Saves changed sample.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public void editSample(String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
-            SampleIdentifier identifier, List<SampleProperty> properties,
-            @AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class)
-            ExperimentIdentifier experimentIdentifierOrNull, Date version);
-
-    /** Lists vocabulary terms of a given vocabulary. Includes terms usage statistics. */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken,
-            Vocabulary vocabulary);
+public interface ICommonServer extends IServer {
+	/**
+	 * Returns all groups which belong to the specified database instance. *
+	 * 
+	 * @return a sorted list of {@link GroupPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = GroupValidator.class)
+	public List<GroupPE> listGroups(String sessionToken,
+			DatabaseInstanceIdentifier identifier);
+
+	/**
+	 * Registers a new group with specified code and optional description and
+	 * group leader ID.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerGroup(String sessionToken, String groupCode,
+			String descriptionOrNull, String groupLeaderOrNull);
+
+	/**
+	 * Returns all persons from current instance.
+	 * 
+	 * @return a sorted list of {@link PersonPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<PersonPE> listPersons(String sessionToken);
+
+	/**
+	 * Returns all projects.
+	 * 
+	 * @return a sorted list of {@link ProjectPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = ProjectValidator.class)
+	public List<ProjectPE> listProjects(String sessionToken);
+
+	/**
+	 * Registers a new person.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerPerson(String sessionToken, String userID);
+
+	/**
+	 * Returns a list of all roles.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public List<RoleAssignmentPE> listRoles(String sessionToken);
+
+	/**
+	 * Registers a new group role.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void registerGroupRole(
+			String sessionToken,
+			RoleCode roleCode,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier identifier,
+			String person);
+
+	/**
+	 * Registers a new instance role.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerInstanceRole(String sessionToken, RoleCode roleCode,
+			String person);
+
+	/**
+	 * Deletes role described by given role code, group identifier and user id.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void deleteGroupRole(
+			String sessionToken,
+			RoleCode roleCode,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier groupIdentifier,
+			String person);
+
+	/**
+	 * Deletes role described by given role code and user id.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void deleteInstanceRole(String sessionToken, RoleCode roleCode,
+			String person);
+
+	/**
+	 * Lists sample types which are appropriate for listing.
+	 * 
+	 * @return a sorted list of {@link SampleTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<SampleTypePE> listSampleTypes(String sessionToken);
+
+	/**
+	 * Lists samples using given configuration.
+	 * 
+	 * @return a sorted list of {@link SamplePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<SamplePE> listSamples(final String sessionToken,
+			final ListSampleCriteriaDTO criteria);
+
+	/**
+	 * Lists experiments.
+	 * 
+	 * @return a sorted list of {@link ExperimentPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExperimentPE> listExperiments(
+			final String sessionToken,
+			ExperimentTypePE experimentType,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier project);
+
+	/**
+	 * For given {@link SampleIdentifier} returns the corresponding list of
+	 * {@link ExternalDataPE}.
+	 * 
+	 * @return a sorted list of {@link ExternalDataPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExternalDataPE> listExternalData(
+			final String sessionToken,
+			@AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier identifier);
+
+	/**
+	 * For given {@link ExperimentIdentifier} returns the corresponding list of
+	 * {@link ExternalDataPE}.
+	 * 
+	 * @return a sorted list of {@link ExternalDataPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExternalDataPE> listExternalData(
+			final String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) final ExperimentIdentifier identifier);
+
+	/**
+	 * Performs an <i>Hibernate Search</i> based on given parameters.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = MatchingEntityValidator.class)
+	public List<SearchHit> listMatchingEntities(final String sessionToken,
+			final SearchableEntity[] searchableEntities, final String queryText);
+
+	/**
+	 * List experiment types.
+	 * 
+	 * @return a sorted list of {@link ExperimentTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExperimentTypePE> listExperimentTypes(String sessionToken);
+
+	/**
+	 * List property types.
+	 * 
+	 * @return a sorted list of {@link PropertyTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<PropertyTypePE> listPropertyTypes(final String sessionToken);
+
+	/**
+	 * Lists data types.
+	 * 
+	 * @return a sorted list of {@link DataTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<DataTypePE> listDataTypes(final String sessionToken);
+
+	/**
+	 * Lists vocabularies.
+	 * 
+	 * @return a sorted list of {@link VocabularyPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<VocabularyPE> listVocabularies(final String sessionToken,
+			final boolean withTerms, boolean excludeInternal);
+
+	/**
+	 * Registers given {@link PropertyType}.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerPropertyType(final String sessionToken,
+			final PropertyType propertyType);
+
+	/**
+	 * Assigns property type to entity type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public String assignPropertyType(final String sessionToken,
+			final EntityKind entityKind, final String propertyTypeCode,
+			final String entityTypeCode, final boolean isMandatory,
+			final String defaultValue);
+
+	/**
+	 * Registers given {@link Vocabulary}.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerVocabulary(final String sessionToken,
+			final Vocabulary vocabulary);
+
+	/**
+	 * Registers new project.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void registerProject(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier projectIdentifier,
+			String description, String leaderId);
+
+	/**
+	 * Performs an <i>Hibernate Search</i> based on given parameters.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = ExternalDataValidator.class)
+	public List<ExternalDataPE> searchForDataSets(String sessionToken,
+			DataSetSearchCriteria criteria);
+
+	/**
+	 * List material types.
+	 * 
+	 * @return a sorted list of {@link MaterialTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<MaterialTypePE> listMaterialTypes(String sessionToken);
+
+	/**
+	 * Lists materials.
+	 * 
+	 * @return a sorted list of {@link MaterialPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<MaterialPE> listMaterials(String sessionToken,
+			MaterialTypePE materialType);
+
+	/**
+	 * Creates a new material type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerMaterialType(String sessionToken,
+			MaterialType entityType);
+
+	/**
+	 * Creates a new sample type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerSampleType(String sessionToken, SampleType entityType);
+
+	/**
+	 * Creates a new experiment type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerExperimentType(String sessionToken,
+			ExperimentType entityType);
+
+	/**
+	 * Deletes specified data sets.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void deleteDataSets(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = DataSetCodePredicate.class) List<String> dataSetCodes,
+			String reason);
+
+	/**
+	 * Saves changed experiment.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public void editExperiment(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier,
+			List<ExperimentProperty> properties,
+			List<AttachmentPE> attachments,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier newProjectIdentifier,
+			Date version);
+
+	/**
+	 * Saves changed material.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void editMaterial(String sessionToken,
+			MaterialIdentifier identifier, List<MaterialProperty> properties,
+			Date version);
+
+	/**
+	 * Saves changed sample.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public void editSample(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) SampleIdentifier identifier,
+			List<SampleProperty> properties,
+			@AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifierOrNull,
+			Date version);
+
+	/**
+	 * Lists vocabulary terms of a given vocabulary. Includes terms usage
+	 * statistics.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public List<VocabularyTermWithStats> listVocabularyTerms(
+			String sessionToken, Vocabulary vocabulary);
+
+	/**
+	 * List data set types.
+	 * 
+	 * @return a sorted list of {@link DataSetTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<DataSetTypePE> listDataSetTypes(String sessionToken);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetType.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetType.java
new file mode 100644
index 0000000000000000000000000000000000000000..57ffddc0904d88bd030f22ecee07cccd22e7f0b7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetType.java
@@ -0,0 +1,42 @@
+/*
+ * 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.basic.dto;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+
+/**
+ * The <i>GWT</i> equivalent to {@link DataSetTypePE}.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DataSetType extends EntityType
+{
+    private List<DataSetTypePropertyType> dataSetTypePropertyTypes;
+
+    public List<DataSetTypePropertyType> getDataSetTypePropertyTypes()
+    {
+        return dataSetTypePropertyTypes;
+    }
+
+    public void setDataSetTypePropertyTypes(
+            List<DataSetTypePropertyType> dataSetTypePropertyTypes)
+    {
+        this.dataSetTypePropertyTypes = dataSetTypePropertyTypes;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetSearchHitDTO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetTypePropertyType.java
similarity index 63%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetSearchHitDTO.java
rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetTypePropertyType.java
index fa5e37fc470ae5b7a343b257bbcc538edc7530bb..3b8e5d8c7502ace7f20535079e3a0d3d89a3b105 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetSearchHitDTO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DataSetTypePropertyType.java
@@ -14,25 +14,21 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.shared.dto;
+package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
 
 /**
- * Single result of data set search.
+ * The {@link EntityTypePropertyType} extension for <i>Data Set Type</i>.
  * 
  * @author Izabela Adamczyk
  */
-public class DataSetSearchHitDTO
+public class DataSetTypePropertyType extends EntityTypePropertyType<DataSetType> implements
+        IsSerializable
 {
-    private final ExternalDataPE dataSet;
-
-    public DataSetSearchHitDTO(ExternalDataPE dataSet)
+    public DataSetTypePropertyType()
     {
-        this.dataSet = dataSet;
+        super(EntityKind.DATA_SET);
     }
-
-    public ExternalDataPE getDataSet()
-    {
-        return dataSet;
-    }
-
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/EntityKind.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/EntityKind.java
index 82cf07fcb0a495fca5a375cdb2445807d5630e09..27ae7bd42c34ea002fb257af7f719b2eb5d4d097 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/EntityKind.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/EntityKind.java
@@ -26,7 +26,7 @@ import com.google.gwt.user.client.rpc.IsSerializable;
  */
 public enum EntityKind implements IsSerializable
 {
-    MATERIAL("Material"), EXPERIMENT("Experiment"), SAMPLE("Sample");
+    MATERIAL("Material"), EXPERIMENT("Experiment"), SAMPLE("Sample"), DATA_SET("Data Set");
 
     private final String description;
 
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
index a7c1389b290203747a2a8fc64d0bf6574953605e..61df9c9a4fa15cb37b9bd645aeb6bebcea58d82c 100644
--- 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
@@ -21,164 +21,167 @@ package ch.systemsx.cisd.openbis.generic.shared.dto;
  * 
  * @author Christian Ribeaud
  */
-public final class ColumnNames
-{
+public final class ColumnNames {
 
-    public static final String AMOUNT_COLUMN = "amount";
+	public static final String AMOUNT_COLUMN = "amount";
 
-    public static final String CODE_COLUMN = "code";
+	public static final String CODE_COLUMN = "code";
 
-    public static final String CONTROL_LAYOUT_SAMPLE_COLUMN = "samp_id_control_layout";
+	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 CONTROLLED_VOCABULARY_COLUMN = "covo_id";
 
-    public static final String DATA_CHILD_COLUMN = "data_id_child";
+	public static final String DATA_CHILD_COLUMN = "data_id_child";
 
-    public static final String DATA_ID_COLUMN = "data_id";
+	public static final String DATA_ID_COLUMN = "data_id";
 
-    public static final String DATA_PARENT_COLUMN = "data_id_parent";
+	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_PRODUCER_CODE_COLUMN = "data_producer_code";
 
-    public static final String DATA_SET_TYPE_COLUMN = "dsty_id";
+	public static final String DATA_SET_TYPE_COLUMN = "dsty_id";
 
-    public static final String DATA_STORE_COLUMN = "dast_id";
+	public static final String DATA_STORE_COLUMN = "dast_id";
 
-    public static final String DATA_TYPE_COLUMN = "daty_id";
+	public static final String DATA_TYPE_COLUMN = "daty_id";
 
-    public final static String DATABASE_INSTANCE_COLUMN = "dbin_id";
+	public final static String DATABASE_INSTANCE_COLUMN = "dbin_id";
 
-    public static final String DESCRIPTION_COLUMN = "description";
+	public static final String DESCRIPTION_COLUMN = "description";
 
-    public static final String DOWNLOAD_URL_COLUMN = "download_url";
+	public static final String DOWNLOAD_URL_COLUMN = "download_url";
 
-    public static final String EXPERIMENT_ATTACHMENT_CONTENT_COLUMN = "exac_id";
+	public static final String EXPERIMENT_ATTACHMENT_CONTENT_COLUMN = "exac_id";
 
-    public static final String EXPERIMENT_COLUMN = "expe_id";
+	public static final String EXPERIMENT_COLUMN = "expe_id";
 
-    public static final String EXPERIMENT_TYPE_COLUMN = "exty_id";
+	public static final String DATA_SET_COLUMN = "ds_id";
 
-    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_COLUMN = "etpt_id";
+	public static final String EXPERIMENT_TYPE_COLUMN = "exty_id";
 
-    public static final String FILE_FORMAT_TYPE = "ffty_id";
+	public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_COLUMN = "etpt_id";
 
-    public static final String FILE_NAME_COLUMN = "file_name";
+	public static final String DATA_SET_TYPE_PROPERTY_TYPE_COLUMN = "dstpt_id";
 
-    public final static String FIRST_NAME_COLUMN = "first_name";
+	public static final String FILE_FORMAT_TYPE = "ffty_id";
 
-    public static final String GENERATED_FROM_DEPTH = "generated_from_depth";
+	public static final String FILE_NAME_COLUMN = "file_name";
 
-    public static final String GENERATED_FROM_SAMPLE_COLUMN = "samp_id_generated_from";
+	public final static String FIRST_NAME_COLUMN = "first_name";
 
-    public static final String GROUP_COLUMN = "grou_id";
+	public static final String GENERATED_FROM_DEPTH = "generated_from_depth";
 
-    public static final String GROUP_PARENT_COLUMN = "grou_id_parent";
+	public static final String GENERATED_FROM_SAMPLE_COLUMN = "samp_id_generated_from";
 
-    public static final String ID_COLUMN = "id";
+	public static final String GROUP_COLUMN = "grou_id";
 
-    public static final String INHIBITOR_OF_COLUMN = "mate_id_inhibitor_of";
+	public static final String GROUP_PARENT_COLUMN = "grou_id_parent";
 
-    public static final String INVALIDATION_COLUMN = "inva_id";
+	public static final String ID_COLUMN = "id";
 
-    public static final String IS_COMPLETE_COLUMN = "is_complete";
+	public static final String INHIBITOR_OF_COLUMN = "mate_id_inhibitor_of";
 
-    public static final String IS_DATA_ACQUSITION = "is_data_acquisition";
+	public static final String INVALIDATION_COLUMN = "inva_id";
 
-    public static final String IS_DISPLAYED = "is_displayed";
+	public static final String IS_COMPLETE_COLUMN = "is_complete";
 
-    public static final String IS_INTERNAL_NAMESPACE = "is_internal_namespace";
+	public static final String IS_DATA_ACQUSITION = "is_data_acquisition";
 
-    public static final String IS_LISTABLE = "IS_LISTABLE";
+	public static final String IS_DISPLAYED = "is_displayed";
 
-    public static final String IS_MANAGED_INTERNALLY = "is_managed_internally";
+	public static final String IS_INTERNAL_NAMESPACE = "is_internal_namespace";
 
-    public static final String IS_MANDATORY = "is_mandatory";
+	public static final String IS_LISTABLE = "IS_LISTABLE";
 
-    public static final String IS_ORIGINAL_SOURCE_COLUMN = "is_original_source";
+	public static final String IS_MANAGED_INTERNALLY = "is_managed_internally";
 
-    public static final String IS_PLACEHOLDER_COLUMN = "is_placeholder";
-    
-    public static final String IS_DELETED_COLUMN = "is_deleted";
+	public static final String IS_MANDATORY = "is_mandatory";
 
-    public static final String LABEL_COLUMN = "label";
+	public static final String IS_ORIGINAL_SOURCE_COLUMN = "is_original_source";
 
-    public final static String LAST_NAME_COLUMN = "last_name";
+	public static final String IS_PLACEHOLDER_COLUMN = "is_placeholder";
 
-    public static final String LOCATION_COLUMN = "location";
+	public static final String IS_DELETED_COLUMN = "is_deleted";
 
-    public static final String LOCATOR_TYPE_COLUMN = "loty_id";
+	public static final String LABEL_COLUMN = "label";
 
-    public static final String MATERIAL_BATCH_COLUMN = "maba_id";
+	public final static String LAST_NAME_COLUMN = "last_name";
 
-    public static final String MATERIAL_COLUMN = "mate_id";
+	public static final String LOCATION_COLUMN = "location";
 
-    public static final String MATERIAL_TYPE_COLUMN = "maty_id";
+	public static final String LOCATOR_TYPE_COLUMN = "loty_id";
 
-    public static final String MATERIAL_TYPE_PROPERTY_TYPE_COLUMN = "mtpt_id";
+	public static final String MATERIAL_BATCH_COLUMN = "maba_id";
 
-    public static final String PARENT_DATA_SET_CODE_COLUMN = "data_producer_code";
+	public static final String MATERIAL_COLUMN = "mate_id";
 
-    public static final String PART_OF_DEPTH = "part_of_depth";
+	public static final String MATERIAL_TYPE_COLUMN = "maty_id";
 
-    public static final String PART_OF_SAMPLE_COLUMN = "samp_id_part_of";
+	public static final String MATERIAL_TYPE_PROPERTY_TYPE_COLUMN = "mtpt_id";
 
-    public static final String PERSON_GRANTEE_COLUMN = "pers_id_grantee";
+	public static final String PARENT_DATA_SET_CODE_COLUMN = "data_producer_code";
 
-    public static final String PERSON_LEADER_COLUMN = "pers_id_leader";
+	public static final String PART_OF_DEPTH = "part_of_depth";
 
-    public static final String PERSON_REGISTERER_COLUMN = "pers_id_registerer";
+	public static final String PART_OF_SAMPLE_COLUMN = "samp_id_part_of";
 
-    public static final String PROCEDURE_COLUMN = "proc_id";
+	public static final String PERSON_GRANTEE_COLUMN = "pers_id_grantee";
 
-    public static final String PROCEDURE_PRODUCED_BY_COLUMN = "proc_id_produced_by";
+	public static final String PERSON_LEADER_COLUMN = "pers_id_leader";
 
-    public static final String PROCEDURE_TYPE_COLUMN = "pcty_id";
+	public static final String PERSON_REGISTERER_COLUMN = "pers_id_registerer";
 
-    public static final String PRODUCTION_TIMESTAMP_COLUMN = "production_timestamp";
+	public static final String PROCEDURE_COLUMN = "proc_id";
 
-    public static final String PROJECT_COLUMN = "proj_id";
+	public static final String PROCEDURE_PRODUCED_BY_COLUMN = "proc_id_produced_by";
 
-    public static final String PROPERTY_TYPE_COLUMN = "prty_id";
+	public static final String PROCEDURE_TYPE_COLUMN = "pcty_id";
 
-    public static final String REGISTRATION_TIMESTAMP_COLUMN = "registration_timestamp";
+	public static final String PRODUCTION_TIMESTAMP_COLUMN = "production_timestamp";
 
-    public final static String ROLE_COLUMN = "role_code";
+	public static final String PROJECT_COLUMN = "proj_id";
 
-    public static final String SAMPLE_ACQUIRED_FROM = "samp_id_acquired_from";
+	public static final String PROPERTY_TYPE_COLUMN = "prty_id";
 
-    public static final String SAMPLE_COLUMN = "samp_id";
+	public static final String REGISTRATION_TIMESTAMP_COLUMN = "registration_timestamp";
 
-    public static final String SAMPLE_DERIVED_FROM = "samp_id_derived_from";
+	public final static String ROLE_COLUMN = "role_code";
 
-    public static final String SAMPLE_TYPE_COLUMN = "saty_id";
+	public static final String SAMPLE_ACQUIRED_FROM = "samp_id_acquired_from";
 
-    public static final String SAMPLE_TYPE_PROPERTY_TYPE_COLUMN = "stpt_id";
+	public static final String SAMPLE_COLUMN = "samp_id";
 
-    public static final String STORAGE_FORMAT_COLUMN = "cvte_id_stor_fmt";
+	public static final String SAMPLE_DERIVED_FROM = "samp_id_derived_from";
 
-    public static final String STUDY_OBJECT_COLUMN = "mate_id_study_object";
+	public static final String SAMPLE_TYPE_COLUMN = "saty_id";
 
-    public static final String TOP_SAMPLE_COLUMN = "samp_id_top";
+	public static final String SAMPLE_TYPE_PROPERTY_TYPE_COLUMN = "stpt_id";
 
-    public final static String USER_COLUMN = "user_id";
+	public static final String STORAGE_FORMAT_COLUMN = "cvte_id_stor_fmt";
 
-    public static final String UUID_COLUMN = "uuid";
+	public static final String STUDY_OBJECT_COLUMN = "mate_id_study_object";
 
-    public static final String VALUE_COLUMN = "value";
+	public static final String TOP_SAMPLE_COLUMN = "samp_id_top";
 
-    public static final String VERSION_COLUMN = "version";
+	public final static String USER_COLUMN = "user_id";
 
-    public static final String VOCABULARY_TERM_COLUMN = "cvte_id";
+	public static final String UUID_COLUMN = "uuid";
 
-    public static final String MODIFICATION_TIMESTAMP_COLUMN = "modification_timestamp";
-    
-    public static final String EVENT_TYPE = "event_type";
-    
-    public static final String MATERIAL_PROP_COLUMN = "mate_prop_id";
-    
-        public static final String PROPERTY_MATERIAL_TYPE_COLUMN = "maty_prop_id";
-    private ColumnNames()
-    {
-        // Can not be instantiated.
-    }
+	public static final String VALUE_COLUMN = "value";
+
+	public static final String VERSION_COLUMN = "version";
+
+	public static final String VOCABULARY_TERM_COLUMN = "cvte_id";
+
+	public static final String MODIFICATION_TIMESTAMP_COLUMN = "modification_timestamp";
+
+	public static final String EVENT_TYPE = "event_type";
+
+	public static final String MATERIAL_PROP_COLUMN = "mate_prop_id";
+
+	public static final String PROPERTY_MATERIAL_TYPE_COLUMN = "maty_prop_id";
+
+	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
index b438501ce33a47724d56f032e9bc68959b3ecf50..944994f99e07ac1cec2e04620437d790c3eb5e19 100644
--- 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
@@ -39,6 +39,9 @@ import javax.persistence.Table;
 import javax.persistence.Transient;
 import javax.persistence.UniqueConstraint;
 
+import org.hibernate.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.Check;
 import org.hibernate.annotations.Generated;
 import org.hibernate.annotations.GenerationTime;
@@ -57,296 +60,310 @@ import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
 import ch.systemsx.cisd.openbis.generic.shared.dto.hibernate.SearchFieldConstants;
 
 /**
- * Kind of <i>Java Bean</i> or <i>Value Object</i> which contains any information we would like to
- * know about one DATA.
+ * 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.
+ * 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)")
+@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)
 @Friend(toClasses = EventPE.class)
-public class DataPE extends AbstractIdAndCodeHolder<DataPE>
+public class DataPE extends AbstractIdAndCodeHolder<DataPE> implements
+		IEntityPropertiesHolder<DataSetPropertyPE>
 {
-    private static final long serialVersionUID = GenericSharedConstants.VERSION;
-
-    public static final DataPE[] EMPTY_ARRAY = new DataPE[0];
-
-    private transient Long id;
-
-    private String code;
-
-    private boolean placeholder;
-
-    private boolean deleted;
-
-    /** 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 Set<DataPE> parents = new HashSet<DataPE>();
-
-    private Set<EventPE> events = new HashSet<EventPE>();
-
-    @Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false)
-    @Generated(GenerationTime.ALWAYS)
-    public Date getRegistrationDate()
-    {
-        return HibernateAbstractRegistrationHolder.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)
-    @IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_DATASET_TYPE)
-    /**  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;
-    }
-
-    @Column(name = ColumnNames.IS_DELETED_COLUMN)
-    @Field(index = Index.UN_TOKENIZED, store = Store.YES, name = SearchFieldConstants.DELETED)
-    public boolean isDeleted()
-    {
-        return deleted;
-    }
-
-    public void setDeleted(boolean deleted)
-    {
-        this.deleted = deleted;
-    }
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = ColumnNames.SAMPLE_ACQUIRED_FROM)
-    @IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_SAMPLE)
-    public SamplePE getSampleAcquiredFrom()
-    {
-        return sampleAcquiredFrom;
-    }
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = ColumnNames.SAMPLE_DERIVED_FROM)
-    @IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_SAMPLE)
-    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)
-    public Date getProductionDate()
-    {
-        return HibernateAbstractRegistrationHolder.getDate(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>.
-     * </p>
-     */
-    @Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
-    @Column(name = ColumnNames.DATA_PRODUCER_CODE_COLUMN)
-    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 Set<DataPE> getParents()
-    {
-        return parents;
-    }
-
-    public void setParents(final Set<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)
-    @DocumentId
-    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)
-    @Field(index = Index.TOKENIZED, store = Store.YES, name = SearchFieldConstants.CODE)
-    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)
-    @IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_PROCEDURE)
-    public ProcedurePE getProcedure()
-    {
-        return procedure;
-    }
-
-    /** Sets <code>procedure</code>. */
-    public void setProcedure(final ProcedurePE procedure)
-    {
-        this.procedure = procedure;
-    }
-
-    @OneToMany(fetch = FetchType.LAZY, mappedBy = "dataInternal", cascade = CascadeType.ALL)
-    private final Set<EventPE> getEventsInternal()
-    {
-        return events;
-    }
-
-    // Required by Hibernate.
-    @SuppressWarnings("unused")
-    private final void setEventsInternal(final Set<EventPE> events)
-    {
-        this.events = events;
-    }
-
-    public final void setEvents(final Set<EventPE> events)
-    {
-        getEventsInternal().clear();
-        for (final EventPE child : events)
-        {
-            addEvent(child);
-        }
-    }
-
-    @Transient
-    public final Set<EventPE> getEvents()
-    {
-        return new UnmodifiableSetDecorator<EventPE>(getEventsInternal());
-    }
-
-    public void addEvent(final EventPE event)
-    {
-        final DataPE data = event.getData();
-        if (data != null)
-        {
-            data.removeEvent(event);
-        }
-        event.setDataInternal(this);
-        getEventsInternal().add(event);
-    }
-
-    public void removeEvent(final EventPE event)
-    {
-        assert event != null : "Unspecified event.";
-        getEventsInternal().remove(event);
-        event.setDataInternal(null);
-    }
+	private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+	public static final DataPE[] EMPTY_ARRAY = new DataPE[0];
+
+	private transient Long id;
+
+	private String code;
+
+	private boolean placeholder;
+
+	private boolean deleted;
+
+	/** 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 Set<DataPE> parents = new HashSet<DataPE>();
+
+	private Set<EventPE> events = new HashSet<EventPE>();
+
+	@Column(name = ColumnNames.REGISTRATION_TIMESTAMP_COLUMN, nullable = false, insertable = false)
+	@Generated(GenerationTime.ALWAYS)
+	public Date getRegistrationDate() {
+		return HibernateAbstractRegistrationHolder.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)
+	@IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_DATASET_TYPE)
+	/* * 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;
+	}
+
+	@Column(name = ColumnNames.IS_DELETED_COLUMN)
+	@Field(index = Index.UN_TOKENIZED, store = Store.YES, name = SearchFieldConstants.DELETED)
+	public boolean isDeleted() {
+		return deleted;
+	}
+
+	public void setDeleted(boolean deleted) {
+		this.deleted = deleted;
+	}
+
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = ColumnNames.SAMPLE_ACQUIRED_FROM)
+	@IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_SAMPLE)
+	public SamplePE getSampleAcquiredFrom() {
+		return sampleAcquiredFrom;
+	}
+
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = ColumnNames.SAMPLE_DERIVED_FROM)
+	@IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_SAMPLE)
+	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)
+	public Date getProductionDate() {
+		return HibernateAbstractRegistrationHolder.getDate(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>.
+	 * </p>
+	 */
+	@Length(min = 1, max = 40, message = ValidationMessages.CODE_LENGTH_MESSAGE)
+	@Column(name = ColumnNames.DATA_PRODUCER_CODE_COLUMN)
+	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 Set<DataPE> getParents() {
+		return parents;
+	}
+
+	public void setParents(final Set<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)
+	@DocumentId
+	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)
+	@Field(index = Index.TOKENIZED, store = Store.YES, name = SearchFieldConstants.CODE)
+	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)
+	@IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_PROCEDURE)
+	public ProcedurePE getProcedure() {
+		return procedure;
+	}
+
+	/** Sets <code>procedure</code>. */
+	public void setProcedure(final ProcedurePE procedure) {
+		this.procedure = procedure;
+	}
+
+	@OneToMany(fetch = FetchType.LAZY, mappedBy = "dataInternal", cascade = CascadeType.ALL)
+	private final Set<EventPE> getEventsInternal() {
+		return events;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private final void setEventsInternal(final Set<EventPE> events) {
+		this.events = events;
+	}
+
+	public final void setEvents(final Set<EventPE> events) {
+		getEventsInternal().clear();
+		for (final EventPE child : events) {
+			addEvent(child);
+		}
+	}
+
+	@Transient
+	public final Set<EventPE> getEvents() {
+		return new UnmodifiableSetDecorator<EventPE>(getEventsInternal());
+	}
+
+	public void addEvent(final EventPE event) {
+		final DataPE data = event.getData();
+		if (data != null) {
+			data.removeEvent(event);
+		}
+		event.setDataInternal(this);
+		getEventsInternal().add(event);
+	}
+
+	public void removeEvent(final EventPE event) {
+		assert event != null : "Unspecified event.";
+		getEventsInternal().remove(event);
+		event.setDataInternal(null);
+	}
+
+	private Set<DataSetPropertyPE> properties = new HashSet<DataSetPropertyPE>();
+
+	@Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "entity")
+	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+	@IndexedEmbedded(prefix = SearchFieldConstants.PREFIX_PROPERTIES)
+	private Set<DataSetPropertyPE> getDataSetProperties() {
+		return properties;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setDataSetProperties(final Set<DataSetPropertyPE> properties) {
+		this.properties = properties;
+	}
+
+	public void addProperty(final DataSetPropertyPE property) {
+		property.setEntity(this);
+		getDataSetProperties().add(property);
+	}
+
+	public void setProperties(final Set<DataSetPropertyPE> properties) {
+		getDataSetProperties().clear();
+		for (final DataSetPropertyPE property : properties) {
+			final DataPE parent = property.getDataSet();
+			if (parent != null) {
+				parent.getDataSetProperties().remove(property);
+			}
+			addProperty(property);
+		}
+	}
+
+	@Transient
+	public Set<DataSetPropertyPE> getProperties() {
+	        return new UnmodifiableSetDecorator<DataSetPropertyPE>(
+				getDataSetProperties());
+	}
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetPropertyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetPropertyPE.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4f333ad1701e2b2f4b21e2ec68b7a827cce1238
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetPropertyPE.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 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.annotations.Cache;
+import org.hibernate.annotations.CacheConcurrencyStrategy;
+import org.hibernate.validator.NotNull;
+
+import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
+
+/**
+ * Persistence entity representing data set property.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.DATA_SET_PROPERTIES_TABLE, uniqueConstraints = @UniqueConstraint(columnNames = {
+		ColumnNames.DATA_SET_COLUMN,
+		ColumnNames.DATA_SET_TYPE_PROPERTY_TYPE_COLUMN }))
+@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
+public class DataSetPropertyPE extends EntityPropertyPE {
+	private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+	public final static DataSetPropertyPE[] EMPTY_ARRAY = new DataSetPropertyPE[0];
+
+	private DataPE dataSet;
+
+	@Transient
+	public final DataPE getDataSet() {
+		return dataSet;
+	}
+
+	//
+	// EntityPropertyPE
+	//
+
+	@NotNull(message = ValidationMessages.DATA_SET_TYPE_NOT_NULL_MESSAGE)
+	@ManyToOne(fetch = FetchType.EAGER, targetEntity = DataSetTypePropertyTypePE.class)
+	@JoinColumn(name = ColumnNames.DATA_SET_TYPE_PROPERTY_TYPE_COLUMN, updatable = false)
+	public EntityTypePropertyTypePE getEntityTypePropertyType() {
+		return entityTypePropertyType;
+	}
+
+	@SequenceGenerator(name = SequenceNames.DATA_SET_PROPERTY_SEQUENCE, sequenceName = SequenceNames.DATA_SET_PROPERTY_SEQUENCE, allocationSize = 1)
+	@Id
+	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_SET_PROPERTY_SEQUENCE)
+	public Long getId() {
+		return id;
+	}
+
+	@ManyToOne(fetch = FetchType.LAZY, targetEntity = DataPE.class)
+	@JoinColumn(name = ColumnNames.DATA_SET_COLUMN, updatable = false)
+	public IIdAndCodeHolder getEntity() {
+		return getDataSet();
+	}
+
+	/**
+	 * Sets the <var>data set</var> of this property.
+	 * <p>
+	 * <i>Do not use directly, instead, call
+	 * {@link DataPE#addProperty(DataSetPropertyPE)} with <code>this</code>
+	 * object!</i>
+	 */
+	void setEntity(final IIdAndCodeHolder entity) {
+		this.dataSet = (DataPE) entity;
+	}
+
+	@Override
+	public void setHolder(final IIdAndCodeHolder entity) {
+		((DataPE) entity).addProperty(this);
+	}
+}
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
index f0821591c8ce38c1a7ff0c5d2507c98c6d44793e..a6a8d81443be0773b7a620910ab284922f68b398 100644
--- 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
@@ -16,55 +16,75 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.dto;
 
+import java.util.HashSet;
+import java.util.Set;
+
 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.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;
+@Table(name = TableNames.DATA_SET_TYPES_TABLE, uniqueConstraints = { @UniqueConstraint(columnNames = {
+		ColumnNames.CODE_COLUMN, ColumnNames.DATABASE_INSTANCE_COLUMN }) })
+public class DataSetTypePE extends EntityTypePE {
+	private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+	private Set<DataSetTypePropertyTypePE> dataSetTypePropertyTypes = new HashSet<DataSetTypePropertyTypePE>();
+
+	@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;
+	}
+
+	public void addDataSetTypePropertyType(final DataSetTypePropertyTypePE child) {
+		final DataSetTypePE parent = (DataSetTypePE) child.getEntityType();
+		if (parent != null) {
+			parent.getDataSetTypePropertyTypesInternal().remove(child);
+		}
+		child.setEntityTypeInternal(this);
+		getDataSetTypePropertyTypesInternal().add(child);
+	}
 
-    private DatabaseInstancePE databaseInstance;
+	@OneToMany(fetch = FetchType.LAZY, mappedBy = "entityTypeInternal")
+	@JoinColumn(name = ColumnNames.DATA_SET_TYPE_COLUMN, updatable = false)
+	private Set<DataSetTypePropertyTypePE> getDataSetTypePropertyTypesInternal() {
+		return dataSetTypePropertyTypes;
+	}
 
-    @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;
-    }
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setDataSetTypePropertyTypesInternal(
+			final Set<DataSetTypePropertyTypePE> dataSetTypePropertyTypes) {
+		this.dataSetTypePropertyTypes = dataSetTypePropertyTypes;
+	}
 
-    @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;
-    }
+	@Transient
+	public Set<DataSetTypePropertyTypePE> getDataSetTypePropertyTypes() {
+		return getDataSetTypePropertyTypesInternal();
+	}
 
-    public void setDatabaseInstance(final DatabaseInstancePE databaseInstance)
-    {
-        this.databaseInstance = databaseInstance;
-    }
+	public final void setDataSetTypePropertyTypes(
+			final Set<DataSetTypePropertyTypePE> dataSetTypePropertyTypes) {
+		getDataSetTypePropertyTypesInternal().clear();
+		for (final DataSetTypePropertyTypePE child : dataSetTypePropertyTypes) {
+			addDataSetTypePropertyType(child);
+		}
+	}
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePropertyTypePE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePropertyTypePE.java
new file mode 100644
index 0000000000000000000000000000000000000000..3de079bae414b5761a313159f899458000e67c3e
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/DataSetTypePropertyTypePE.java
@@ -0,0 +1,94 @@
+/*
+ * 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.Set;
+
+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.ManyToOne;
+import javax.persistence.OneToMany;
+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 experiment type - property type relation.
+ * 
+ * @author Izabela Adamczyk
+ */
+@Entity
+@Table(name = TableNames.DATA_SET_TYPE_PROPERTY_TYPE_TABLE, uniqueConstraints = { @UniqueConstraint(columnNames = {
+		ColumnNames.DATA_SET_TYPE_COLUMN, ColumnNames.PROPERTY_TYPE_COLUMN }) })
+public class DataSetTypePropertyTypePE extends EntityTypePropertyTypePE {
+
+	private static final long serialVersionUID = GenericSharedConstants.VERSION;
+
+	public static final DataSetTypePropertyTypePE[] EMPTY_ARRAY = new DataSetTypePropertyTypePE[0];
+
+	@NotNull(message = ValidationMessages.DATA_SET_TYPE_NOT_NULL_MESSAGE)
+	@ManyToOne(fetch = FetchType.EAGER, targetEntity = ExperimentTypePE.class)
+	@JoinColumn(name = ColumnNames.DATA_SET_TYPE_COLUMN)
+	private EntityTypePE getEntityTypeInternal() {
+		return entityType;
+	}
+
+	//
+	// EntityTypePropertyTypePE
+	//
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "entityTypePropertyType", targetEntity = DataSetPropertyPE.class)
+	public Set<EntityPropertyPE> getPropertyValues() {
+		return propertyValues;
+	}
+
+	@Transient
+	public EntityTypePE getEntityType() {
+		return getEntityTypeInternal();
+	}
+
+	@Override
+	// This setter sets the bidirectional connection. That's why we must have an
+	// another internal
+	// plain setter for Hibernate.
+	public void setEntityType(EntityTypePE entityType) {
+		((DataSetTypePE) entityType).addDataSetTypePropertyType(this);
+	}
+
+	@SequenceGenerator(name = SequenceNames.DATA_SET_TYPE_PROPERTY_TYPE_SEQUENCE, sequenceName = SequenceNames.DATA_SET_TYPE_PROPERTY_TYPE_SEQUENCE, allocationSize = 1)
+	@Id
+	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = SequenceNames.DATA_SET_TYPE_PROPERTY_TYPE_SEQUENCE)
+	public Long getId() {
+		return id;
+	}
+
+	@Override
+	public void setPropertyType(PropertyTypePE propertyType) {
+		propertyType.addDataSetTypePropertyType(this);
+	}
+
+}
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
index d284288895a5ae6735cf8f15d68a4b56e7d226b5..8842d026ab3a88b895759cdd9764b0334478e493 100644
--- 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
@@ -57,7 +57,6 @@ 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;
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
index b8f48dfaac8fda20ec6ac647aef1ca32084c5735..98a9a3052c1574dbba7433e570bba6fd7ddd5598 100644
--- 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
@@ -31,7 +31,6 @@ public final class NewSampleComponent extends NewSampleComponentWithFixedMateria
 {
     private static final long serialVersionUID = GenericSharedConstants.VERSION;
 
-    @SuppressWarnings("hiding")
     public final static NewSampleComponent[] EMPTY_ARRAY = new NewSampleComponent[0];
 
     private String materialTypeCode;
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
index 323085c2b8e2bb133099a484b86760be897a2713..5a145b3f7d3a743c4f9e8cd5e4d4330896853ef8 100644
--- 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
@@ -54,371 +54,352 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.hibernate.InternalNamespace;
  * @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 HibernateAbstractRegistrationHolder 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;
-
-    /** can be null. Is always null when {@link #materialType} is not null. */
-    private VocabularyPE vocabulary;
-
-    /**
-     * If this field is set, then it specifies the type of the materials, which are values of this
-     * property type.<br>
-     * Note that this field can be null and the data type can be still MATERIAL, it means that, that
-     * material of any type can be a valid property value.
-     */
-    private MaterialTypePE materialType;
-
-    private boolean internalNamespace;
-
-    private boolean managedInternally;
-
-    private transient Long id;
-
-    private DatabaseInstancePE databaseInstance;
-
-    private Set<MaterialTypePropertyTypePE> materialTypePropertyTypes =
-            new HashSet<MaterialTypePropertyTypePE>();
-
-    private Set<ExperimentTypePropertyTypePE> experimentTypePropertyTypes =
-            new HashSet<ExperimentTypePropertyTypePE>();
-
-    private Set<SampleTypePropertyTypePE> sampleTypePropertyTypes =
-            new HashSet<SampleTypePropertyTypePE>();
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = ColumnNames.CONTROLLED_VOCABULARY_COLUMN, updatable = false)
-    public VocabularyPE getVocabulary()
-    {
-        return vocabulary;
-    }
-
-    public void setVocabulary(final VocabularyPE vocabulary)
-    {
-        assert materialType == null || vocabulary == null : "Property cannot be of controled vocabulary and material type at the same moment";
-        this.vocabulary = vocabulary;
-    }
-
-    @ManyToOne(fetch = FetchType.EAGER)
-    @JoinColumn(name = ColumnNames.PROPERTY_MATERIAL_TYPE_COLUMN, updatable = false)
-    public MaterialTypePE getMaterialType()
-    {
-        return materialType;
-    }
-
-    public void setMaterialType(MaterialTypePE materialType)
-    {
-        assert materialType == null || vocabulary == null : "Property cannot be of controled vocabulary and material type at the same moment";
-        this.materialType = materialType;
-    }
-
-    /**
-     * Sets code in 'database format' - without 'user prefix'. To set full code (with user prefix
-     * use {@link #setCode(String)}).
-     */
-    public 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)
-    public 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)
-    @InternalNamespace(message = ValidationMessages.CODE_NOT_USER_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();
-    }
-
-    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
-    private Set<SampleTypePropertyTypePE> getSampleTypePropertyTypesInternal()
-    {
-        return sampleTypePropertyTypes;
-    }
-
-    // Required by Hibernate.
-    @SuppressWarnings("unused")
-    private void setSampleTypePropertyTypesInternal(
-            Set<SampleTypePropertyTypePE> sampleTypePropertyTypes)
-    {
-        this.sampleTypePropertyTypes = sampleTypePropertyTypes;
-    }
-
-    @Transient
-    public Set<SampleTypePropertyTypePE> getSampleTypePropertyTypes()
-    {
-        return new UnmodifiableSetDecorator<SampleTypePropertyTypePE>(
-                getSampleTypePropertyTypesInternal());
-    }
-
-    public final void setSampleTypePropertyTypes(final Iterable<SampleTypePropertyTypePE> childs)
-    {
-        getSampleTypePropertyTypesInternal().clear();
-        for (final SampleTypePropertyTypePE child : childs)
-        {
-            addSampleTypePropertyType(child);
-        }
-    }
-
-    public void addSampleTypePropertyType(final SampleTypePropertyTypePE child)
-    {
-        final PropertyTypePE parent = child.getPropertyType();
-        if (parent != null)
-        {
-            parent.getSampleTypePropertyTypesInternal().remove(child);
-        }
-        child.setPropertyTypeInternal(this);
-        getSampleTypePropertyTypesInternal().add(child);
-    }
-
-    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
-    private Set<ExperimentTypePropertyTypePE> getExperimentTypePropertyTypesInternal()
-    {
-        return experimentTypePropertyTypes;
-    }
-
-    // Required by Hibernate.
-    @SuppressWarnings("unused")
-    private void setExperimentTypePropertyTypesInternal(
-            Set<ExperimentTypePropertyTypePE> experimentTypePropertyTypes)
-    {
-        this.experimentTypePropertyTypes = experimentTypePropertyTypes;
-    }
-
-    @Transient
-    public Set<ExperimentTypePropertyTypePE> getExperimentTypePropertyTypes()
-    {
-        return new UnmodifiableSetDecorator<ExperimentTypePropertyTypePE>(
-                getExperimentTypePropertyTypesInternal());
-    }
-
-    public final void setExperimentTypePropertyTypes(
-            final Iterable<ExperimentTypePropertyTypePE> childs)
-    {
-        getExperimentTypePropertyTypesInternal().clear();
-        for (final ExperimentTypePropertyTypePE child : childs)
-        {
-            addExperimentTypePropertyType(child);
-        }
-    }
-
-    public void addExperimentTypePropertyType(final ExperimentTypePropertyTypePE child)
-    {
-        final PropertyTypePE parent = child.getPropertyType();
-        if (parent != null)
-        {
-            parent.getExperimentTypePropertyTypesInternal().remove(child);
-        }
-        child.setPropertyTypeInternal(this);
-        getExperimentTypePropertyTypesInternal().add(child);
-    }
-
-    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
-    private Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypesInternal()
-    {
-        return materialTypePropertyTypes;
-    }
-
-    // Required by Hibernate.
-    @SuppressWarnings("unused")
-    private void setMaterialTypePropertyTypesInternal(
-            Set<MaterialTypePropertyTypePE> materialTypePropertyTypes)
-    {
-        this.materialTypePropertyTypes = materialTypePropertyTypes;
-    }
-
-    @Transient
-    public Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypes()
-    {
-        return new UnmodifiableSetDecorator<MaterialTypePropertyTypePE>(
-                getMaterialTypePropertyTypesInternal());
-    }
-
-    public final void setMaterialTypePropertyTypes(final Iterable<MaterialTypePropertyTypePE> childs)
-    {
-        getMaterialTypePropertyTypesInternal().clear();
-        for (final MaterialTypePropertyTypePE child : childs)
-        {
-            addMaterialTypePropertyType(child);
-        }
-    }
-
-    public void addMaterialTypePropertyType(final MaterialTypePropertyTypePE child)
-    {
-        final PropertyTypePE parent = child.getPropertyType();
-        if (parent != null)
-        {
-            parent.getMaterialTypePropertyTypesInternal().remove(child);
-        }
-        child.setPropertyTypeInternal(this);
-        getMaterialTypePropertyTypesInternal().add(child);
-    }
+@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 HibernateAbstractRegistrationHolder
+		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;
+
+	/** can be null. Is always null when {@link #materialType} is not null. */
+	private VocabularyPE vocabulary;
+
+	/**
+	 * If this field is set, then it specifies the type of the materials, which
+	 * are values of this property type.<br>
+	 * Note that this field can be null and the data type can be still MATERIAL,
+	 * it means that, that material of any type can be a valid property value.
+	 */
+	private MaterialTypePE materialType;
+
+	private boolean internalNamespace;
+
+	private boolean managedInternally;
+
+	private transient Long id;
+
+	private DatabaseInstancePE databaseInstance;
+
+	private Set<MaterialTypePropertyTypePE> materialTypePropertyTypes = new HashSet<MaterialTypePropertyTypePE>();
+
+	private Set<ExperimentTypePropertyTypePE> experimentTypePropertyTypes = new HashSet<ExperimentTypePropertyTypePE>();
+
+	private Set<SampleTypePropertyTypePE> sampleTypePropertyTypes = new HashSet<SampleTypePropertyTypePE>();
+
+	private Set<DataSetTypePropertyTypePE> dataSetTypePropertyTypes = new HashSet<DataSetTypePropertyTypePE>();
+
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = ColumnNames.CONTROLLED_VOCABULARY_COLUMN, updatable = false)
+	public VocabularyPE getVocabulary() {
+		return vocabulary;
+	}
+
+	public void setVocabulary(final VocabularyPE vocabulary) {
+		assert materialType == null || vocabulary == null : "Property cannot be of controled vocabulary and material type at the same moment";
+		this.vocabulary = vocabulary;
+	}
+
+	@ManyToOne(fetch = FetchType.EAGER)
+	@JoinColumn(name = ColumnNames.PROPERTY_MATERIAL_TYPE_COLUMN, updatable = false)
+	public MaterialTypePE getMaterialType() {
+		return materialType;
+	}
+
+	public void setMaterialType(MaterialTypePE materialType) {
+		assert materialType == null || vocabulary == null : "Property cannot be of controled vocabulary and material type at the same moment";
+		this.materialType = materialType;
+	}
+
+	/**
+	 * Sets code in 'database format' - without 'user prefix'. To set full code
+	 * (with user prefix use {@link #setCode(String)}).
+	 */
+	public 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)
+	public 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)
+	@InternalNamespace(message = ValidationMessages.CODE_NOT_USER_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();
+	}
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
+	private Set<SampleTypePropertyTypePE> getSampleTypePropertyTypesInternal() {
+		return sampleTypePropertyTypes;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setSampleTypePropertyTypesInternal(
+			Set<SampleTypePropertyTypePE> sampleTypePropertyTypes) {
+		this.sampleTypePropertyTypes = sampleTypePropertyTypes;
+	}
+
+	@Transient
+	public Set<SampleTypePropertyTypePE> getSampleTypePropertyTypes() {
+		return new UnmodifiableSetDecorator<SampleTypePropertyTypePE>(
+				getSampleTypePropertyTypesInternal());
+	}
+
+	public final void setSampleTypePropertyTypes(
+			final Iterable<SampleTypePropertyTypePE> childs) {
+		getSampleTypePropertyTypesInternal().clear();
+		for (final SampleTypePropertyTypePE child : childs) {
+			addSampleTypePropertyType(child);
+		}
+	}
+
+	public void addSampleTypePropertyType(final SampleTypePropertyTypePE child) {
+		final PropertyTypePE parent = child.getPropertyType();
+		if (parent != null) {
+			parent.getSampleTypePropertyTypesInternal().remove(child);
+		}
+		child.setPropertyTypeInternal(this);
+		getSampleTypePropertyTypesInternal().add(child);
+	}
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
+	private Set<ExperimentTypePropertyTypePE> getExperimentTypePropertyTypesInternal() {
+		return experimentTypePropertyTypes;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setExperimentTypePropertyTypesInternal(
+			Set<ExperimentTypePropertyTypePE> experimentTypePropertyTypes) {
+		this.experimentTypePropertyTypes = experimentTypePropertyTypes;
+	}
+
+	@Transient
+	public Set<ExperimentTypePropertyTypePE> getExperimentTypePropertyTypes() {
+		return new UnmodifiableSetDecorator<ExperimentTypePropertyTypePE>(
+				getExperimentTypePropertyTypesInternal());
+	}
+
+	public final void setExperimentTypePropertyTypes(
+			final Iterable<ExperimentTypePropertyTypePE> childs) {
+		getExperimentTypePropertyTypesInternal().clear();
+		for (final ExperimentTypePropertyTypePE child : childs) {
+			addExperimentTypePropertyType(child);
+		}
+	}
+
+	public void addExperimentTypePropertyType(
+			final ExperimentTypePropertyTypePE child) {
+		final PropertyTypePE parent = child.getPropertyType();
+		if (parent != null) {
+			parent.getExperimentTypePropertyTypesInternal().remove(child);
+		}
+		child.setPropertyTypeInternal(this);
+		getExperimentTypePropertyTypesInternal().add(child);
+	}
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
+	private Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypesInternal() {
+		return materialTypePropertyTypes;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setMaterialTypePropertyTypesInternal(
+			Set<MaterialTypePropertyTypePE> materialTypePropertyTypes) {
+		this.materialTypePropertyTypes = materialTypePropertyTypes;
+	}
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "propertyTypeInternal")
+	private Set<DataSetTypePropertyTypePE> getDataSetTypePropertyTypesInternal() {
+		return dataSetTypePropertyTypes;
+	}
+
+	// Required by Hibernate.
+	@SuppressWarnings("unused")
+	private void setDataSetTypePropertyTypesInternal(
+			Set<DataSetTypePropertyTypePE> dataSetTypePropertyTypes) {
+		this.dataSetTypePropertyTypes = dataSetTypePropertyTypes;
+	}
+
+	@Transient
+	public Set<MaterialTypePropertyTypePE> getMaterialTypePropertyTypes() {
+		return new UnmodifiableSetDecorator<MaterialTypePropertyTypePE>(
+				getMaterialTypePropertyTypesInternal());
+	}
+
+	public final void setMaterialTypePropertyTypes(
+			final Iterable<MaterialTypePropertyTypePE> childs) {
+		getMaterialTypePropertyTypesInternal().clear();
+		for (final MaterialTypePropertyTypePE child : childs) {
+			addMaterialTypePropertyType(child);
+		}
+	}
+
+	public void addMaterialTypePropertyType(
+			final MaterialTypePropertyTypePE child) {
+		final PropertyTypePE parent = child.getPropertyType();
+		if (parent != null) {
+			parent.getMaterialTypePropertyTypesInternal().remove(child);
+		}
+		child.setPropertyTypeInternal(this);
+		getMaterialTypePropertyTypesInternal().add(child);
+	}
+
+	public void addDataSetTypePropertyType(DataSetTypePropertyTypePE child) {
+		final PropertyTypePE parent = child.getPropertyType();
+		if (parent != null) {
+			parent.getDataSetTypePropertyTypesInternal().remove(child);
+		}
+		child.setPropertyTypeInternal(this);
+		getDataSetTypePropertyTypesInternal().add(child);
+	}
+
+	@Transient
+	public Set<DataSetTypePropertyTypePE> getDataSetTypePropertyTypes() {
+		return new UnmodifiableSetDecorator<DataSetTypePropertyTypePE>(
+				getDataSetTypePropertyTypesInternal());
+	}
 }
\ No newline at end of file
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
index 5daa0847a98ac7ee3a4ec18de39b90e40fd937d9..d955f93de9e5daec1084dbfa42caf3f4877c5ca9 100644
--- 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
@@ -88,12 +88,13 @@ public class SamplePropertyPE extends EntityPropertyPE
         return getSample();
     }
 
-    /**
-     * Sets the <var>sample</var> of this property.
-     * <p>
-     * <i>Do not use directly, instead, call {@link MaterialPE#addProperty(MaterialPropertyPE)} with
-     * <code>this</code> object!</i>
-     */
+	/**
+	 * Sets the <var>sample</var> of this property.
+	 * <p>
+	 * <i>Do not use directly, instead, call
+	 * {@link SamplePE#addProperty(SamplePropertyPE)} with <code>this</code>
+	 * object!</i>
+	 */
     void setEntity(final IIdAndCodeHolder entity)
     {
         this.sample = (SamplePE) entity;
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
index 543fa348f11b40851fabc0b62161dfce00676918..c3098da38dbe314f2bdd3d49f57e1efb0f4b5054 100644
--- 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
@@ -43,73 +43,64 @@ import ch.systemsx.cisd.openbis.generic.shared.GenericSharedConstants;
  * @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];
-
-    private boolean displayed;
-
-    @Column(name = ColumnNames.IS_DISPLAYED)
-    public boolean isDisplayed()
-    {
-        return displayed;
-    }
-
-    public void setDisplayed(final boolean displayed)
-    {
-        this.displayed = displayed;
-    }
-
-    @NotNull(message = ValidationMessages.SAMPLE_TYPE_NOT_NULL_MESSAGE)
-    @ManyToOne(fetch = FetchType.EAGER, targetEntity = SampleTypePE.class)
-    @JoinColumn(name = ColumnNames.SAMPLE_TYPE_COLUMN)
-    private EntityTypePE getEntityTypeInternal()
-    {
-        return entityType;
-    }
-
-    //
-    // EntityTypePropertyTypePE
-    //
-
-    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "entityTypePropertyType", targetEntity = SamplePropertyPE.class)
-    public Set<EntityPropertyPE> getPropertyValues()
-    {
-        return propertyValues;
-    }
-
-    @Transient
-    public EntityTypePE getEntityType()
-    {
-        return getEntityTypeInternal();
-    }
-
-    @Override
-    // This setter sets the bidirectional connection. That's why we must have an another internal
-    // plain setter for Hibernate.
-    public void setEntityType(EntityTypePE entityType)
-    {
-        ((SampleTypePE) entityType).addSampleTypePropertyType(this);
-    }
-
-    @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;
-    }
-
-    @Override
-    public void setPropertyType(PropertyTypePE propertyType)
-    {
-        propertyType.addSampleTypePropertyType(this);
-    }
+@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];
+
+	private boolean displayed;
+
+	@Column(name = ColumnNames.IS_DISPLAYED)
+	public boolean isDisplayed() {
+		return displayed;
+	}
+
+	public void setDisplayed(final boolean displayed) {
+		this.displayed = displayed;
+	}
+
+	@NotNull(message = ValidationMessages.SAMPLE_TYPE_NOT_NULL_MESSAGE)
+	@ManyToOne(fetch = FetchType.EAGER, targetEntity = SampleTypePE.class)
+	@JoinColumn(name = ColumnNames.SAMPLE_TYPE_COLUMN)
+	private EntityTypePE getEntityTypeInternal() {
+		return entityType;
+	}
+
+	//
+	// EntityTypePropertyTypePE
+	//
+
+	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "entityTypePropertyType", targetEntity = SamplePropertyPE.class)
+	public Set<EntityPropertyPE> getPropertyValues() {
+		return propertyValues;
+	}
+
+	@Transient
+	public EntityTypePE getEntityType() {
+		return getEntityTypeInternal();
+	}
+
+	@Override
+	// This setter sets the bidirectional connection. That's why we must have an
+	// another internal
+	// plain setter for Hibernate.
+	public void setEntityType(EntityTypePE entityType) {
+		((SampleTypePE) entityType).addSampleTypePropertyType(this);
+	}
+
+	@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;
+	}
+
+	@Override
+	public void setPropertyType(PropertyTypePE propertyType) {
+		propertyType.addSampleTypePropertyType(this);
+	}
 
 }
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
index 7dac00f42914a7b7645cadb7ca1e14230d52f89a..b8a339d972ad07e31d88797ce76e9183d7f58393 100644
--- 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
@@ -21,84 +21,85 @@ package ch.systemsx.cisd.openbis.generic.shared.dto;
  * 
  * @author Christian Ribeaud
  */
-public final class SequenceNames
-{
+public final class SequenceNames {
 
-    public static final String CONTROLLED_VOCABULARY_SEQUENCE = "CONTROLLED_VOCABULARY_ID_SEQ";
+	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 CONTROLLED_VOCABULARY_TERM_SEQUENCE = "CVTE_ID_SEQ";
 
-    public static final String DATA_SEQUENCE = "DATA_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_SET_RELATIONSHIP_SEQUENCE = "DATA_SET_RELATIONSHIP_ID_SEQ";
 
-    public static final String DATA_SET_TYPE_SEQUENCE = "DATA_SET_TYPE_ID_SEQ";
+	public static final String DATA_SET_TYPE_SEQUENCE = "DATA_SET_TYPE_ID_SEQ";
 
-    public static final String DATA_STORE_SEQUENCE = "DATA_STORE_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 DATA_TYPE_SEQUENCE = "DATA_TYPE_ID_SEQ";
 
-    public static final String DATABASE_INSTANCE_SEQUENCE = "DATABASE_INSTANCE_ID_SEQ";
+	public static final String DATABASE_INSTANCE_SEQUENCE = "DATABASE_INSTANCE_ID_SEQ";
 
-    public static final String EXPERIMENT_ATTACHMENT_CONTENT_SEQUENCE =
-            "EXPERIMENT_ATTACHMENT_CONTENT_ID_SEQ";
+	public static final String EXPERIMENT_ATTACHMENT_CONTENT_SEQUENCE = "EXPERIMENT_ATTACHMENT_CONTENT_ID_SEQ";
 
-    public static final String EXPERIMENT_ATTACHMENT_SEQUENCE = "EXPERIMENT_ATTACHMENT_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_PROPERTY_SEQUENCE = "EXPERIMENT_PROPERTY_ID_SEQ";
 
-    public static final String EXPERIMENT_SEQUENCE = "EXPERIMENT_ID_SEQ";
+	public static final String DATA_SET_PROPERTY_SEQUENCE = "DATA_SET_PROPERTY_ID_SEQ";
 
-    public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE = "ETPT_ID_SEQ";
+	public static final String EXPERIMENT_SEQUENCE = "EXPERIMENT_ID_SEQ";
 
-    public static final String EXPERIMENT_TYPE_SEQUENCE = "EXPERIMENT_TYPE_ID_SEQ";
+	public static final String EXPERIMENT_TYPE_PROPERTY_TYPE_SEQUENCE = "ETPT_ID_SEQ";
 
-    public static final String FILE_FORMAT_TYPE_SEQUENCE = "FILE_FORMAT_TYPE_ID_SEQ";
+	public static final String DATA_SET_TYPE_PROPERTY_TYPE_SEQUENCE = "DSTPT_ID_SEQ";
 
-    public static final String GROUP_SEQUENCE = "GROUP_ID_SEQ";
+	public static final String EXPERIMENT_TYPE_SEQUENCE = "EXPERIMENT_TYPE_ID_SEQ";
 
-    public static final String INVALIDATION_SEQUENCE = "INVALIDATION_ID_SEQ";
+	public static final String FILE_FORMAT_TYPE_SEQUENCE = "FILE_FORMAT_TYPE_ID_SEQ";
 
-    public static final String LOCATOR_TYPE_SEQUENCE = "LOCATOR_TYPE_ID_SEQ";
+	public static final String GROUP_SEQUENCE = "GROUP_ID_SEQ";
 
-    public static final String MATERIAL_BATCH_SEQUENCE = "MATERIAL_BATCH_ID_SEQ";
+	public static final String INVALIDATION_SEQUENCE = "INVALIDATION_ID_SEQ";
 
-    public static final String MATERIAL_PROPERTY_SEQUENCE = "MATERIAL_PROPERTY_ID_SEQ";
+	public static final String LOCATOR_TYPE_SEQUENCE = "LOCATOR_TYPE_ID_SEQ";
 
-    public static final String MATERIAL_SEQUENCE = "MATERIAL_ID_SEQ";
+	public static final String MATERIAL_BATCH_SEQUENCE = "MATERIAL_BATCH_ID_SEQ";
 
-    public static final String MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE = "MTPT_ID_SEQ";
+	public static final String MATERIAL_PROPERTY_SEQUENCE = "MATERIAL_PROPERTY_ID_SEQ";
 
-    public static final String MATERIAL_TYPE_SEQUENCE = "MATERIAL_TYPE_ID_SEQ";
+	public static final String MATERIAL_SEQUENCE = "MATERIAL_ID_SEQ";
 
-    public final static String PERSON_SEQUENCE = "PERSON_ID_SEQ";
+	public static final String MATERIAL_TYPE_PROPERTY_TYPE_SEQUENCE = "MTPT_ID_SEQ";
 
-    public static final String PROCEDURE_SEQUENCE = "PROCEDURE_ID_SEQ";
+	public static final String MATERIAL_TYPE_SEQUENCE = "MATERIAL_TYPE_ID_SEQ";
 
-    public static final String PROCEDURE_TYPE_SEQUENCE = "PROCEDURE_TYPE_ID_SEQ";
+	public final static String PERSON_SEQUENCE = "PERSON_ID_SEQ";
 
-    public static final String PROJECT_SEQUENCE = "PROJECT_ID_SEQ";
+	public static final String PROCEDURE_SEQUENCE = "PROCEDURE_ID_SEQ";
 
-    public static final String PROPERTY_TYPES_SEQUENCE = "PROPERTY_TYPE_ID_SEQ";
+	public static final String PROCEDURE_TYPE_SEQUENCE = "PROCEDURE_TYPE_ID_SEQ";
 
-    public static final String ROLE_ASSIGNMENT_SEQUENCE = "ROLE_ASSIGNMENT_ID_SEQ";
+	public static final String PROJECT_SEQUENCE = "PROJECT_ID_SEQ";
 
-    public static final String SAMPLE_INPUT_SEQUENCE = "SAMPLE_INPUT_ID_SEQ";
+	public static final String PROPERTY_TYPES_SEQUENCE = "PROPERTY_TYPE_ID_SEQ";
 
-    public static final String SAMPLE_MATERIAL_BATCH_SEQUENCE = "SAMPLE_MATERIAL_BATCH_ID_SEQ";
+	public static final String ROLE_ASSIGNMENT_SEQUENCE = "ROLE_ASSIGNMENT_ID_SEQ";
 
-    public static final String SAMPLE_PROPERTY_SEQUENCE = "SAMPLE_PROPERTY_ID_SEQ";
+	public static final String SAMPLE_INPUT_SEQUENCE = "SAMPLE_INPUT_ID_SEQ";
 
-    public static final String SAMPLE_SEQUENCE = "SAMPLE_ID_SEQ";
+	public static final String SAMPLE_MATERIAL_BATCH_SEQUENCE = "SAMPLE_MATERIAL_BATCH_ID_SEQ";
 
-    public static final String SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE = "STPT_ID_SEQ";
+	public static final String SAMPLE_PROPERTY_SEQUENCE = "SAMPLE_PROPERTY_ID_SEQ";
 
-    public static final String SAMPLE_TYPE_SEQUENCE = "SAMPLE_TYPE_ID_SEQ";
-    
-    public static final String EVENT_SEQUENCE = "EVENT_ID_SEQ";
+	public static final String SAMPLE_SEQUENCE = "SAMPLE_ID_SEQ";
 
-    private SequenceNames()
-    {
-        // Can not be instantiated.
-    }
+	public static final String SAMPLE_TYPE_PROPERTY_TYPE_SEQUENCE = "STPT_ID_SEQ";
+
+	public static final String SAMPLE_TYPE_SEQUENCE = "SAMPLE_TYPE_ID_SEQ";
+
+	public static final String EVENT_SEQUENCE = "EVENT_ID_SEQ";
+
+	private SequenceNames() {
+		// Can not be instantiated.
+	}
 }
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
index d054fe704cbf7874fea8c47a0c4f1a076fd915ed..56a25bf60a5cf17c027c118ad6241dec9955decc 100644
--- 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
@@ -37,6 +37,11 @@ public final class TableNames
     public static final String DATA_STORES_TABLE = "data_stores";
 
     public static final String DATA_TABLE = "data";
+    
+    public static final String DATA_SET_PROPERTIES_TABLE = "data_set_properties";
+
+    public static final String DATA_SET_TYPE_PROPERTY_TYPE_TABLE =
+        "data_set_type_property_types";
 
     public static final String DATA_TYPES_TABLE = "data_types";
 
@@ -48,7 +53,7 @@ public final class TableNames
     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";
 
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
index 5119f194e1d9c4e562251afe21749ef4dcdc1900..8e564fe22c91c66af67ba79cbc527fb7c8c73e1e 100644
--- 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
@@ -25,136 +25,159 @@ package ch.systemsx.cisd.openbis.generic.shared.dto;
  * 
  * @author Christian Ribeaud
  */
-public final class ValidationMessages
-{
+public final class ValidationMessages {
 
-    private static final String CAN_NOT_BE_NULL = " can not be null.";
+	private static final String CAN_NOT_BE_NULL = " can not be null.";
 
-    private static final String LENGTH_PREFIX = "Given ";
+	private static final String LENGTH_PREFIX = "Given ";
 
-    private static final String LENGTH_SUFFIX =
-            " '%s' is too long (maximal length: {max} characters).";
+	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 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_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_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 CODE_PATTERN_MESSAGE = "Given code '%s' contains illegal characters (allowed: A-Z, a-z, 0-9, _ and -)";
 
-    public static final String DATA_SET_TYPE_NOT_NULL_MESSAGE = "Data set 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 DATA_TYPE_NOT_NULL_MESSAGE = "Data type" + CAN_NOT_BE_NULL;
+	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 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 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 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 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_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 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_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_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 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_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_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 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 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 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 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_LENGTH_MESSAGE = LENGTH_PREFIX + "label"
+			+ LENGTH_SUFFIX;
 
-    public static final String LABEL_NOT_NULL_MESSAGE = "Label" + CAN_NOT_BE_NULL;
+	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 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_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_NULL_MESSAGE = "Location"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String LOCATION_NOT_RELATIVE = "Location is not relative";
+	public static final String LOCATION_NOT_RELATIVE = "Location is not relative";
 
-    public static final String CODE_NOT_USER_NAMESPACE =
-            "Code does not contain '" + CodeConverter.USER_PROPERTY_PREFIX + "' prefix.";
+	public static final String CODE_NOT_USER_NAMESPACE = "Code does not contain '"
+			+ CodeConverter.USER_PROPERTY_PREFIX + "' prefix.";
 
-    public static final String LOCATOR_TYPE_NOT_NULL_MESSAGE = "Locator type" + CAN_NOT_BE_NULL;
+	public static final String LOCATOR_TYPE_NOT_NULL_MESSAGE = "Locator type"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String MATERIAL_NOT_NULL_MESSAGE = "Material" + CAN_NOT_BE_NULL;
+	public static final String MATERIAL_NOT_NULL_MESSAGE = "Material"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String MATERIAL_TYPE_NOT_NULL_MESSAGE = "Material 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_TYPE_PROPERTY_TYPE_NOT_NULL_MESSAGE =
-            "Material type - property type" + 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 PERSON_NOT_NULL_MESSAGE = "Person" + 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 PROCEDURE_NOT_NULL_MESSAGE = "Procedure"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String PROJECT_NOT_NULL_MESSAGE = "Project" + CAN_NOT_BE_NULL;
+	public static final String PROJECT_NOT_NULL_MESSAGE = "Project"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String PROPERTY_TYPE_NOT_NULL_MESSAGE = "Property type" + 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 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_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 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 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_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 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 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 VALUE_LENGTH_MESSAGE = LENGTH_PREFIX + "value"
+			+ LENGTH_SUFFIX;
 
-    public static final String VALUE_NOT_NULL_MESSAGE = "Value" + CAN_NOT_BE_NULL;
+	public static final String VALUE_NOT_NULL_MESSAGE = "Value"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String VERSION_NOT_NULL_MESSAGE = "Version" + CAN_NOT_BE_NULL;
+	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 VOCABULARY_NOT_NULL_MESSAGE = "Vocabulary"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String VALID_USER_CODE_DESCRIPTION =
-            "User code must not be empty and must contain only allowed characters: "
-                    + "letters, digits, '_', '.', '-', '@'. Note that whitespaces are not allowed.";
+	public static final String VALID_USER_CODE_DESCRIPTION = "User code must not be empty and must contain only allowed characters: "
+			+ "letters, digits, '_', '.', '-', '@'. Note that whitespaces are not allowed.";
 
-    public static final String EVENT_TYPE_NOT_NULL_MESSAGE = "Event Type" + CAN_NOT_BE_NULL;
+	public static final String EVENT_TYPE_NOT_NULL_MESSAGE = "Event Type"
+			+ CAN_NOT_BE_NULL;
 
-    public static final String DATA_NOT_NULL_MESSAGE = "Data " + CAN_NOT_BE_NULL;
+	public static final String DATA_NOT_NULL_MESSAGE = "Data "
+			+ CAN_NOT_BE_NULL;
 
-    private ValidationMessages()
-    {
-        // Can not be instantiated.
-    }
+	private ValidationMessages() {
+		// Can not be instantiated.
+	}
 }
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
index 5380544775b5c62cdfe78f7f1b9bc7e08c91c62c..1a2777950a2a1f17c2effb99f56e01f099248016 100644
--- 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
@@ -16,6 +16,10 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.dto.properties;
 
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetPropertyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePropertyTypePE;
 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;
@@ -37,70 +41,65 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePropertyTypePE;
  * 
  * @author Franz-Josef Elmer
  */
-public enum EntityKind
-{
-    MATERIAL("material", MaterialPE.class, MaterialTypePE.class, MaterialTypePropertyTypePE.class,
-            MaterialPropertyPE.class),
-
-    EXPERIMENT("experiment", ExperimentPE.class, ExperimentTypePE.class,
-            ExperimentTypePropertyTypePE.class, ExperimentPropertyPE.class),
-
-    SAMPLE("sample", SamplePE.class, SampleTypePE.class, SampleTypePropertyTypePE.class,
-            SamplePropertyPE.class);
-
-    private final String entityLabel;
-
-    private transient final Class<?> entityClass;
-
-    private transient final Class<?> typeClass;
-
-    private transient final Class<?> assignmentClass;
-
-    private transient final Class<?> propertyClass;
-
-    private EntityKind(final String entityLabel, final Class<?> entityClass,
-            final Class<?> typeClass, final Class<?> assignmentClass, Class<?> propertyClass)
-    {
-        this.entityLabel = entityLabel;
-        this.entityClass = entityClass;
-        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 final <T extends EntityPropertyPE> Class<T> getEntityPropertyClass()
-    {
-        return cast(propertyClass);
-    }
-
-    public final <T> Class<T> getEntityClass()
-    {
-        return cast(entityClass);
-    }
-
-    public final String getEntityTypeFieldName()
-    {
-        return entityLabel + "Type";
-    }
+public enum EntityKind {
+	MATERIAL("material", MaterialPE.class, MaterialTypePE.class,
+			MaterialTypePropertyTypePE.class, MaterialPropertyPE.class),
+
+	EXPERIMENT("experiment", ExperimentPE.class, ExperimentTypePE.class,
+			ExperimentTypePropertyTypePE.class, ExperimentPropertyPE.class),
+
+	SAMPLE("sample", SamplePE.class, SampleTypePE.class,
+			SampleTypePropertyTypePE.class, SamplePropertyPE.class),
+
+	DATA_SET("dataSet", DataPE.class, DataSetTypePE.class,
+			DataSetTypePropertyTypePE.class, DataSetPropertyPE.class);
+
+	private final String entityLabel;
+
+	private transient final Class<?> entityClass;
+
+	private transient final Class<?> typeClass;
+
+	private transient final Class<?> assignmentClass;
+
+	private transient final Class<?> propertyClass;
+
+	private EntityKind(final String entityLabel, final Class<?> entityClass,
+			final Class<?> typeClass, final Class<?> assignmentClass,
+			Class<?> propertyClass) {
+		this.entityLabel = entityLabel;
+		this.entityClass = entityClass;
+		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 final <T extends EntityPropertyPE> Class<T> getEntityPropertyClass() {
+		return cast(propertyClass);
+	}
+
+	public final <T> Class<T> getEntityClass() {
+		return cast(entityClass);
+	}
+
+	public final String getEntityTypeFieldName() {
+		return entityLabel + "Type";
+	}
 }
diff --git a/openbis/source/java/hibernateContext.xml b/openbis/source/java/hibernateContext.xml
index 501bb209bb45c4272d7f9e3e0168c2290a2fe341..2ecfa4b9e28b18b9c848c75db6b6d721b0b43522 100644
--- a/openbis/source/java/hibernateContext.xml
+++ b/openbis/source/java/hibernateContext.xml
@@ -70,6 +70,9 @@
 
                 <value>ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE</value>
                 <value>ch.systemsx.cisd.openbis.generic.shared.dto.MaterialBatchPE</value>
+                
+                <value>ch.systemsx.cisd.openbis.generic.shared.dto.DataSetPropertyPE</value>
+                <value>ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePropertyTypePE</value>
             </list>
         </property>
         <!-- 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java
index 8e72b2d138095e930687651bf2d397a080306071..dd5f78ab08502a70999669a4146e0ca1e9b41e07 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/HibernateSearchDAOTest.java
@@ -46,13 +46,13 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchCriterion;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchField;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetSearchFieldKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.HierarchyType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialPropertyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
@@ -239,7 +239,7 @@ public final class HibernateSearchDAOTest extends AbstractDAOTest
         return codes;
     }
 
-    private List<DataSetSearchHitDTO> searchForDatasets(DataSetSearchCriteria criteria)
+    private List<ExternalDataPE> searchForDatasets(DataSetSearchCriteria criteria)
     {
         final IHibernateSearchDAO hibernateSearchDAO = daoFactory.getHibernateSearchDAO();
         return hibernateSearchDAO.searchForDataSets(criteria);
@@ -250,11 +250,11 @@ public final class HibernateSearchDAOTest extends AbstractDAOTest
     private void assertCorrectDatasetsFound(DataSetSearchCriteria criteria,
             DSLoc... expectedLocations)
     {
-        List<DataSetSearchHitDTO> dataSets = searchForDatasets(criteria);
+        List<ExternalDataPE> dataSets = searchForDatasets(criteria);
         AssertJUnit.assertEquals(expectedLocations.length, dataSets.size());
-        for (DataSetSearchHitDTO dataSet : dataSets)
+        for (ExternalDataPE dataSet : dataSets)
         {
-            assertContains(expectedLocations, dataSet.getDataSet().getLocation());
+            assertContains(expectedLocations, dataSet.getLocation());
         }
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
index f06f868779a27c6e3f85659ff37057194c6974ef..b81a82be2b514c863f1f54cd9391b5e990715afd 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java.expected
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.DataSetCo
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.GroupIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.NullableGroupIdentifierPredicate;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.predicate.SampleOwnerIdentifierPredicate;
+import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ExternalDataValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.GroupValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.MatchingEntityValidator;
 import ch.systemsx.cisd.openbis.generic.shared.authorization.validator.ProjectValidator;
@@ -43,7 +44,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetSearchHitDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
@@ -75,315 +76,346 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
  * 
  * @author Franz-Josef Elmer
  */
-public interface ICommonServer extends IServer
-{
-    /**
-     * Returns all groups which belong to the specified database instance. *
-     * 
-     * @return a sorted list of {@link GroupPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = GroupValidator.class)
-    public List<GroupPE> listGroups(String sessionToken, DatabaseInstanceIdentifier identifier);
-
-    /**
-     * Registers a new group with specified code and optional description and group leader ID.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerGroup(String sessionToken, String groupCode, String descriptionOrNull,
-            String groupLeaderOrNull);
-
-    /**
-     * Returns all persons from current instance.
-     * 
-     * @return a sorted list of {@link PersonPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<PersonPE> listPersons(String sessionToken);
-
-    /**
-     * Returns all projects.
-     * 
-     * @return a sorted list of {@link ProjectPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = ProjectValidator.class)
-    public List<ProjectPE> listProjects(String sessionToken);
-
-    /**
-     * Registers a new person.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerPerson(String sessionToken, String userID);
-
-    /**
-     * Returns a list of all roles.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public List<RoleAssignmentPE> listRoles(String sessionToken);
-
-    /**
-     * Registers a new group role.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void registerGroupRole(String sessionToken, RoleCode roleCode,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            GroupIdentifier identifier, String person);
-
-    /**
-     * Registers a new instance role.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerInstanceRole(String sessionToken, RoleCode roleCode, String person);
-
-    /**
-     * Deletes role described by given role code, group identifier and user id.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void deleteGroupRole(String sessionToken, RoleCode roleCode,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            GroupIdentifier groupIdentifier, String person);
-
-    /**
-     * Deletes role described by given role code and user id.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void deleteInstanceRole(String sessionToken, RoleCode roleCode, String person);
-
-    /**
-     * Lists sample types which are appropriate for listing.
-     * 
-     * @return a sorted list of {@link SampleTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<SampleTypePE> listSampleTypes(String sessionToken);
-
-    /**
-     * Lists samples using given configuration.
-     * 
-     * @return a sorted list of {@link SamplePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<SamplePE> listSamples(final String sessionToken,
-            final ListSampleCriteriaDTO criteria);
-
-    /**
-     * Lists experiments.
-     * 
-     * @return a sorted list of {@link ExperimentPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExperimentPE> listExperiments(final String sessionToken,
-            ExperimentTypePE experimentType,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier project);
-
-    /**
-     * For given {@link SampleIdentifier} returns the corresponding list of {@link ExternalDataPE}.
-     * 
-     * @return a sorted list of {@link ExternalDataPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExternalDataPE> listExternalData(final String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
-            final SampleIdentifier identifier);
-
-    /**
-     * For given {@link ExperimentIdentifier} returns the corresponding list of
-     * {@link ExternalDataPE}.
-     * 
-     * @return a sorted list of {@link ExternalDataPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExternalDataPE> listExternalData(final String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            final ExperimentIdentifier identifier);
-
-    /**
-     * Performs an <i>Hibernate Search</i> based on given parameters.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    @ReturnValueFilter(validatorClass = MatchingEntityValidator.class)
-    public List<SearchHit> listMatchingEntities(final String sessionToken,
-            final SearchableEntity[] searchableEntities, final String queryText);
-
-    /**
-     * List experiment types.
-     * 
-     * @return a sorted list of {@link ExperimentTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<ExperimentTypePE> listExperimentTypes(String sessionToken);
-
-    /**
-     * List property types.
-     * 
-     * @return a sorted list of {@link PropertyTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<PropertyTypePE> listPropertyTypes(final String sessionToken);
-
-    /**
-     * Lists data types.
-     * 
-     * @return a sorted list of {@link DataTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataTypePE> listDataTypes(final String sessionToken);
-
-    /**
-     * Lists vocabularies.
-     * 
-     * @return a sorted list of {@link VocabularyPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<VocabularyPE> listVocabularies(final String sessionToken, final boolean withTerms,
-            boolean excludeInternal);
-
-    /**
-     * Registers given {@link PropertyType}.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerPropertyType(final String sessionToken, final PropertyType propertyType);
-
-    /**
-     * Assigns property type to entity type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public String assignPropertyType(final String sessionToken, final EntityKind entityKind,
-            final String propertyTypeCode, final String entityTypeCode, final boolean isMandatory,
-            final String defaultValue);
-
-    /**
-     * Registers given {@link Vocabulary}.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerVocabulary(final String sessionToken, final Vocabulary vocabulary);
-
-    /**
-     * Registers new project.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void registerProject(String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier projectIdentifier, String description, String leaderId);
-
-    /**
-     * Performs an <i>Hibernate Search</i> based on given parameters.
-     */
-    // TODO 2009-03-16 FJE, @ReturnValueFilter missing
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<DataSetSearchHitDTO> searchForDataSets(String sessionToken,
-            DataSetSearchCriteria criteria);
-
-    /**
-     * List material types.
-     * 
-     * @return a sorted list of {@link MaterialTypePE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<MaterialTypePE> listMaterialTypes(String sessionToken);
-
-    /**
-     * Lists materials.
-     * 
-     * @return a sorted list of {@link MaterialPE}.
-     */
-    @Transactional(readOnly = true)
-    @RolesAllowed(RoleSet.OBSERVER)
-    public List<MaterialPE> listMaterials(String sessionToken, MaterialTypePE materialType);
-
-    /**
-     * Creates a new material type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerMaterialType(String sessionToken, MaterialType entityType);
-
-    /**
-     * Creates a new sample type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerSampleType(String sessionToken, SampleType entityType);
-
-    /**
-     * Creates a new experiment type.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void registerExperimentType(String sessionToken, ExperimentType entityType);
-
-    /**
-     * Deletes specified data sets.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.GROUP_ADMIN)
-    public void deleteDataSets(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodePredicate.class)
-            List<String> dataSetCodes, String reason);
-
-    /**
-     * Saves changed experiment.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public void editExperiment(String sessionToken,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ExperimentIdentifier experimentIdentifier, List<ExperimentProperty> properties,
-            List<AttachmentPE> attachments,
-            @AuthorizationGuard(guardClass = GroupIdentifierPredicate.class)
-            ProjectIdentifier newProjectIdentifier, Date version);
-
-    /**
-     * Saves changed material.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.INSTANCE_ADMIN)
-    public void editMaterial(String sessionToken, MaterialIdentifier identifier,
-            List<MaterialProperty> properties, Date version);
-
-    /**
-     * Saves changed sample.
-     */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public void editSample(String sessionToken,
-            @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class)
-            SampleIdentifier identifier, List<SampleProperty> properties,
-            @AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class)
-            ExperimentIdentifier experimentIdentifierOrNull, Date version);
-
-    /** Lists vocabulary terms of a given vocabulary. Includes terms usage statistics. */
-    @Transactional
-    @RolesAllowed(RoleSet.USER)
-    public List<VocabularyTermWithStats> listVocabularyTerms(String sessionToken,
-            Vocabulary vocabulary);
+public interface ICommonServer extends IServer {
+	/**
+	 * Returns all groups which belong to the specified database instance. *
+	 * 
+	 * @return a sorted list of {@link GroupPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = GroupValidator.class)
+	public List<GroupPE> listGroups(String sessionToken,
+			DatabaseInstanceIdentifier identifier);
+
+	/**
+	 * Registers a new group with specified code and optional description and
+	 * group leader ID.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerGroup(String sessionToken, String groupCode,
+			String descriptionOrNull, String groupLeaderOrNull);
+
+	/**
+	 * Returns all persons from current instance.
+	 * 
+	 * @return a sorted list of {@link PersonPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<PersonPE> listPersons(String sessionToken);
+
+	/**
+	 * Returns all projects.
+	 * 
+	 * @return a sorted list of {@link ProjectPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = ProjectValidator.class)
+	public List<ProjectPE> listProjects(String sessionToken);
+
+	/**
+	 * Registers a new person.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerPerson(String sessionToken, String userID);
+
+	/**
+	 * Returns a list of all roles.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public List<RoleAssignmentPE> listRoles(String sessionToken);
+
+	/**
+	 * Registers a new group role.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void registerGroupRole(
+			String sessionToken,
+			RoleCode roleCode,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier identifier,
+			String person);
+
+	/**
+	 * Registers a new instance role.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerInstanceRole(String sessionToken, RoleCode roleCode,
+			String person);
+
+	/**
+	 * Deletes role described by given role code, group identifier and user id.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void deleteGroupRole(
+			String sessionToken,
+			RoleCode roleCode,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) GroupIdentifier groupIdentifier,
+			String person);
+
+	/**
+	 * Deletes role described by given role code and user id.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void deleteInstanceRole(String sessionToken, RoleCode roleCode,
+			String person);
+
+	/**
+	 * Lists sample types which are appropriate for listing.
+	 * 
+	 * @return a sorted list of {@link SampleTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<SampleTypePE> listSampleTypes(String sessionToken);
+
+	/**
+	 * Lists samples using given configuration.
+	 * 
+	 * @return a sorted list of {@link SamplePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<SamplePE> listSamples(final String sessionToken,
+			final ListSampleCriteriaDTO criteria);
+
+	/**
+	 * Lists experiments.
+	 * 
+	 * @return a sorted list of {@link ExperimentPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExperimentPE> listExperiments(
+			final String sessionToken,
+			ExperimentTypePE experimentType,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier project);
+
+	/**
+	 * For given {@link SampleIdentifier} returns the corresponding list of
+	 * {@link ExternalDataPE}.
+	 * 
+	 * @return a sorted list of {@link ExternalDataPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExternalDataPE> listExternalData(
+			final String sessionToken,
+			@AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier identifier);
+
+	/**
+	 * For given {@link ExperimentIdentifier} returns the corresponding list of
+	 * {@link ExternalDataPE}.
+	 * 
+	 * @return a sorted list of {@link ExternalDataPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExternalDataPE> listExternalData(
+			final String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) final ExperimentIdentifier identifier);
+
+	/**
+	 * Performs an <i>Hibernate Search</i> based on given parameters.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = MatchingEntityValidator.class)
+	public List<SearchHit> listMatchingEntities(final String sessionToken,
+			final SearchableEntity[] searchableEntities, final String queryText);
+
+	/**
+	 * List experiment types.
+	 * 
+	 * @return a sorted list of {@link ExperimentTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<ExperimentTypePE> listExperimentTypes(String sessionToken);
+
+	/**
+	 * List property types.
+	 * 
+	 * @return a sorted list of {@link PropertyTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<PropertyTypePE> listPropertyTypes(final String sessionToken);
+
+	/**
+	 * Lists data types.
+	 * 
+	 * @return a sorted list of {@link DataTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<DataTypePE> listDataTypes(final String sessionToken);
+
+	/**
+	 * Lists vocabularies.
+	 * 
+	 * @return a sorted list of {@link VocabularyPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<VocabularyPE> listVocabularies(final String sessionToken,
+			final boolean withTerms, boolean excludeInternal);
+
+	/**
+	 * Registers given {@link PropertyType}.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerPropertyType(final String sessionToken,
+			final PropertyType propertyType);
+
+	/**
+	 * Assigns property type to entity type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public String assignPropertyType(final String sessionToken,
+			final EntityKind entityKind, final String propertyTypeCode,
+			final String entityTypeCode, final boolean isMandatory,
+			final String defaultValue);
+
+	/**
+	 * Registers given {@link Vocabulary}.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerVocabulary(final String sessionToken,
+			final Vocabulary vocabulary);
+
+	/**
+	 * Registers new project.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void registerProject(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier projectIdentifier,
+			String description, String leaderId);
+
+	/**
+	 * Performs an <i>Hibernate Search</i> based on given parameters.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	@ReturnValueFilter(validatorClass = ExternalDataValidator.class)
+	public List<ExternalDataPE> searchForDataSets(String sessionToken,
+			DataSetSearchCriteria criteria);
+
+	/**
+	 * List material types.
+	 * 
+	 * @return a sorted list of {@link MaterialTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<MaterialTypePE> listMaterialTypes(String sessionToken);
+
+	/**
+	 * Lists materials.
+	 * 
+	 * @return a sorted list of {@link MaterialPE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<MaterialPE> listMaterials(String sessionToken,
+			MaterialTypePE materialType);
+
+	/**
+	 * Creates a new material type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerMaterialType(String sessionToken,
+			MaterialType entityType);
+
+	/**
+	 * Creates a new sample type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerSampleType(String sessionToken, SampleType entityType);
+
+	/**
+	 * Creates a new experiment type.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void registerExperimentType(String sessionToken,
+			ExperimentType entityType);
+
+	/**
+	 * Deletes specified data sets.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.GROUP_ADMIN)
+	public void deleteDataSets(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = DataSetCodePredicate.class) List<String> dataSetCodes,
+			String reason);
+
+	/**
+	 * Saves changed experiment.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public void editExperiment(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier,
+			List<ExperimentProperty> properties,
+			List<AttachmentPE> attachments,
+			@AuthorizationGuard(guardClass = GroupIdentifierPredicate.class) ProjectIdentifier newProjectIdentifier,
+			Date version);
+
+	/**
+	 * Saves changed material.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.INSTANCE_ADMIN)
+	public void editMaterial(String sessionToken,
+			MaterialIdentifier identifier, List<MaterialProperty> properties,
+			Date version);
+
+	/**
+	 * Saves changed sample.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public void editSample(
+			String sessionToken,
+			@AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) SampleIdentifier identifier,
+			List<SampleProperty> properties,
+			@AuthorizationGuard(guardClass = NullableGroupIdentifierPredicate.class) ExperimentIdentifier experimentIdentifierOrNull,
+			Date version);
+
+	/**
+	 * Lists vocabulary terms of a given vocabulary. Includes terms usage
+	 * statistics.
+	 */
+	@Transactional
+	@RolesAllowed(RoleSet.USER)
+	public List<VocabularyTermWithStats> listVocabularyTerms(
+			String sessionToken, Vocabulary vocabulary);
+
+	/**
+	 * List data set types.
+	 * 
+	 * @return a sorted list of {@link DataSetTypePE}.
+	 */
+	@Transactional(readOnly = true)
+	@RolesAllowed(RoleSet.OBSERVER)
+	public List<DataSetTypePE> listDataSetTypes(String sessionToken);
 
 }