diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java
index 101a4070368317152d5bfc7163c0cb62e1784652..75b313dfe0096408f43361a0800fd28b3edc3ed5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/Translator.java
@@ -16,12 +16,15 @@
 
 package ch.systemsx.cisd.openbis.generic.server.api.v1;
 
+import java.util.List;
+
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Role;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.DataSetInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample.SampleInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleLevel;
 
@@ -48,6 +51,12 @@ class Translator
         initializer.setIdentifier(privateSample.getIdentifier());
         initializer.setSampleTypeId(privateSample.getSampleType().getId());
         initializer.setSampleTypeCode(privateSample.getSampleType().getCode());
+        List<IEntityProperty> properties = privateSample.getProperties();
+        for (IEntityProperty prop : properties)
+        {
+            initializer.putProperty(prop.getPropertyType().getCode(), prop.getValue());
+        }
+
         return new Sample(initializer);
     }
 
@@ -59,6 +68,13 @@ class Translator
     {
         DataSetInitializer initializer = new DataSetInitializer();
         initializer.setCode(externalDatum.getCode());
+        initializer.setDataSetTypeCode(externalDatum.getDataSetType().getCode());
+        List<IEntityProperty> properties = externalDatum.getProperties();
+        for (IEntityProperty prop : properties)
+        {
+            initializer.putProperty(prop.getPropertyType().getCode(), prop.getValue());
+        }
+
         return new DataSet(initializer);
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java
index 06dbb657c1ada1df98daa50e0fe1262dcadbcbb7..35685f3ec43e857c8e196378c69a39dcc32c3497 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.shared.api.v1.dto;
 
 import java.io.Serializable;
+import java.util.HashMap;
 
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -32,8 +33,6 @@ public final class DataSet implements Serializable
 {
     private static final long serialVersionUID = 1L;
 
-    private final String code;
-
     /**
      * Class used to initialize a new data set instance. Necessary since all the fields of a DataSet
      * are final.
@@ -44,6 +43,10 @@ public final class DataSet implements Serializable
     {
         private String code;
 
+        private String dataSetTypeCode;
+
+        private HashMap<String, String> properties = new HashMap<String, String>();
+
         public String getCode()
         {
             return code;
@@ -53,8 +56,34 @@ public final class DataSet implements Serializable
         {
             this.code = code;
         }
+
+        public void setDataSetTypeCode(String dataSetTypeCode)
+        {
+            this.dataSetTypeCode = dataSetTypeCode;
+        }
+
+        public String getDataSetTypeCode()
+        {
+            return dataSetTypeCode;
+        }
+
+        public HashMap<String, String> getProperties()
+        {
+            return properties;
+        }
+
+        public void putProperty(String propCode, String value)
+        {
+            properties.put(propCode, value);
+        }
     }
 
+    private final String code;
+
+    private final String dataSetTypeCode;
+
+    private final HashMap<String, String> properties;
+
     /**
      * Creates a new instance with the provided initializer
      * 
@@ -62,12 +91,21 @@ public final class DataSet implements Serializable
      */
     public DataSet(DataSetInitializer initializer)
     {
-        String id = initializer.getCode();
-        if (id == null || id.length() == 0)
+        checkValidString(initializer.getCode(), "Unspecified code.");
+        this.code = initializer.getCode();
+
+        checkValidString(initializer.getDataSetTypeCode(), "Unspecified data set type code.");
+        this.dataSetTypeCode = initializer.getDataSetTypeCode();
+
+        this.properties = initializer.getProperties();
+    }
+
+    private void checkValidString(String string, String message) throws IllegalArgumentException
+    {
+        if (string == null || string.length() == 0)
         {
-            throw new IllegalArgumentException("Unspecified code.");
+            throw new IllegalArgumentException(message);
         }
-        this.code = id;
     }
 
     /**
@@ -78,6 +116,16 @@ public final class DataSet implements Serializable
         return code;
     }
 
+    public String getDataSetTypeCode()
+    {
+        return dataSetTypeCode;
+    }
+
+    public HashMap<String, String> getProperties()
+    {
+        return properties;
+    }
+
     @Override
     public boolean equals(Object obj)
     {
@@ -109,6 +157,8 @@ public final class DataSet implements Serializable
     {
         ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
         builder.append(getCode());
+        builder.append(getDataSetTypeCode());
+        builder.append(getProperties());
         return builder.toString();
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
index dfc8bd8d3ecb529e6be020a0100f12ba8bd25c1c..f2c767cd505d8e5bfb62bca2d2e31b3c2b2f3513 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/Sample.java
@@ -17,6 +17,9 @@
 package ch.systemsx.cisd.openbis.generic.shared.api.v1.dto;
 
 import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
@@ -53,6 +56,8 @@ public final class Sample implements Serializable
 
         private String sampleTypeCode;
 
+        private HashMap<String, String> properties = new HashMap<String, String>();
+
         public void setId(Long id)
         {
             this.id = id;
@@ -102,6 +107,16 @@ public final class Sample implements Serializable
         {
             return sampleTypeCode;
         }
+
+        public HashMap<String, String> getProperties()
+        {
+            return properties;
+        }
+
+        public void putProperty(String propCode, String value)
+        {
+            properties.put(propCode, value);
+        }
     }
 
     private final Long id;
@@ -114,6 +129,8 @@ public final class Sample implements Serializable
 
     private final String sampleTypeCode;
 
+    private final HashMap<String, String> properties;
+
     /**
      * Creates a new instance with the provided initializer
      * 
@@ -135,6 +152,8 @@ public final class Sample implements Serializable
 
         checkValidString(initializer.getSampleTypeCode(), "Unspecified sample type code.");
         this.sampleTypeCode = initializer.getSampleTypeCode();
+
+        this.properties = initializer.getProperties();
     }
 
     private void checkValidString(String string, String message) throws IllegalArgumentException
@@ -193,6 +212,11 @@ public final class Sample implements Serializable
         return sampleTypeCode;
     }
 
+    public Map<String, String> getProperties()
+    {
+        return Collections.unmodifiableMap(properties);
+    }
+
     @Override
     public boolean equals(Object obj)
     {
@@ -225,6 +249,7 @@ public final class Sample implements Serializable
         ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
         builder.append(getIdentifier());
         builder.append(getSampleTypeCode());
+        builder.append(getProperties());
         return builder.toString();
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
index 1fd96312e35ecd68f5434d1e0e9170259c85df8e..8f53cf4b7a0037160b8636403fc470e5e1ed7f92 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
@@ -42,7 +42,9 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample.SampleInitializ
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClause;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClauseAttribute;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetRelatedEntities;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RoleWithHierarchy.RoleCode;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
@@ -208,6 +210,7 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
                     returnSampleType.setId(new Long(1));
                     returnSampleType.setCode("sample-type");
                     returnSample.setSampleType(returnSampleType);
+                    returnSample.setProperties(new ArrayList<IEntityProperty>());
                     will(returnValue(Collections.singletonList(returnSample)));
                 }
             });
@@ -230,7 +233,11 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
                             with(any(DataSetRelatedEntities.class)));
                     ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData returnData =
                             new ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData();
+                    DataSetType returnDataSetType = new DataSetType();
+                    returnDataSetType.setCode("ds-type");
                     returnData.setCode("ds-code");
+                    returnData.setDataSetType(returnDataSetType);
+                    returnData.setDataSetProperties(new ArrayList<IEntityProperty>());
                     will(returnValue(Collections.singletonList(returnData)));
                 }
             });
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3beff699e682a78ff2f22b122ec1a1dc2f26d88
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSetTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010 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.api.v1.dto;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.DataSetInitializer;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class DataSetTest extends AssertJUnit
+{
+    private static final String DATA_SET_CODE = "dataSet-code";
+
+    private static final String DATA_SET_TYPE_CODE = "dataSet-type";
+
+    private DataSet dataSet;
+
+    @BeforeMethod
+    public void setUp()
+    {
+        DataSetInitializer initializer = new DataSetInitializer();
+        initializer.setCode(DATA_SET_CODE);
+        initializer.setDataSetTypeCode(DATA_SET_TYPE_CODE);
+        initializer.putProperty("PROP1", "value1");
+        dataSet = new DataSet(initializer);
+    }
+
+    @Test(expectedExceptions =
+        { IllegalArgumentException.class })
+    public void testInitialization()
+    {
+        DataSetInitializer initializer = new DataSetInitializer();
+        initializer.setCode(DATA_SET_CODE);
+        new DataSet(initializer);
+    }
+
+    @Test
+    public void testEquals()
+    {
+        DataSetInitializer initializer = new DataSetInitializer();
+        initializer.setCode(DATA_SET_CODE);
+        initializer.setDataSetTypeCode(DATA_SET_TYPE_CODE);
+        initializer.putProperty("PROP1", "value1");
+        DataSet myDataSet = new DataSet(initializer);
+        assertTrue("Data sets with the same code should be equal.", dataSet.equals(myDataSet));
+        assertEquals(dataSet.hashCode(), myDataSet.hashCode());
+
+        initializer = new DataSetInitializer();
+        initializer.setCode(DATA_SET_CODE);
+        initializer.setDataSetTypeCode("new-code");
+        myDataSet = new DataSet(initializer);
+        assertTrue("Data sets with the same code should be equal.", dataSet.equals(myDataSet));
+        assertEquals(dataSet.hashCode(), myDataSet.hashCode());
+
+        initializer = new DataSetInitializer();
+        initializer.setCode("code-2");
+        initializer.setDataSetTypeCode(DATA_SET_TYPE_CODE);
+        initializer.putProperty("PROP1", "value1");
+        myDataSet = new DataSet(initializer);
+        assertFalse("Data sets with the different ids should not be equal.", dataSet
+                .equals(myDataSet));
+    }
+
+    @Test
+    public void testToString()
+    {
+        String stringRepresentation = dataSet.toString();
+        assertEquals("DataSet[dataSet-code,dataSet-type,{PROP1=value1}]", stringRepresentation);
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleTest.java
index 4676bc9eef1939e41c701848316904165ea12e20..becb2a71e765baf192e8f194d6190d4f4f19a8c8 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SampleTest.java
@@ -48,6 +48,7 @@ public class SampleTest extends AssertJUnit
         initializer.setIdentifier(SAMPLE_IDENTIFIER);
         initializer.setSampleTypeId(SAMPLE_TYPE_ID);
         initializer.setSampleTypeCode(SAMPLE_TYPE_CODE);
+        initializer.putProperty("PROP1", "value1");
         sample = new Sample(initializer);
     }
 
@@ -69,6 +70,7 @@ public class SampleTest extends AssertJUnit
         initializer.setIdentifier(SAMPLE_IDENTIFIER);
         initializer.setSampleTypeId(SAMPLE_TYPE_ID);
         initializer.setSampleTypeCode(SAMPLE_TYPE_CODE);
+        initializer.putProperty("PROP1", "value1");
         Sample mySample = new Sample(initializer);
         assertTrue("Samples with the same id should be equal.", sample.equals(mySample));
         assertEquals(sample.hashCode(), mySample.hashCode());
@@ -97,6 +99,6 @@ public class SampleTest extends AssertJUnit
     public void testToString()
     {
         String stringRepresentation = sample.toString();
-        assertEquals("Sample[/space/sample-code,sample-type]", stringRepresentation);
+        assertEquals("Sample[/space/sample-code,sample-type,{PROP1=value1}]", stringRepresentation);
     }
 }