diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
index d510ade54a33c4d069a3a04dc015149c726f5a76..4ee74d6d67e1f93144f778b1613a8e0933edd0fc 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.FileFormatType;
@@ -282,7 +283,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         externalData.setDataProducerCode(newData.getDataProducerCode());
         externalData.setProductionDate(newData.getProductionDate());
         externalData.setCode(newData.getCode());
-        externalData.setDataSetType(getDataSetType(dataSetType));
+        externalData.setDataSetType(getDataSetType(dataSetType, DataSetKind.EXTERNAL));
         externalData.setFileFormatType(getFileFomatType(fileFormatType));
         externalData.setComplete(newData.getComplete());
         externalData.setShareId(newData.getShareId());
@@ -316,7 +317,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         dataPE.setDataProducerCode(newData.getDataProducerCode());
         dataPE.setProductionDate(newData.getProductionDate());
         dataPE.setCode(newData.getCode());
-        dataPE.setDataSetType(getDataSetType(dataSetType));
+        dataPE.setDataSetType(getDataSetType(dataSetType, DataSetKind.CONTAINER));
         dataPE.setRegistrator(tryToGetRegistrator(newData));
         dataStore = getDataStoreDAO().tryToFindDataStoreByCode(newData.getDataStoreCode());
         dataPE.setDataStore(dataStore);
@@ -346,7 +347,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         dataPE.setDataProducerCode(newData.getDataProducerCode());
         dataPE.setProductionDate(newData.getProductionDate());
         dataPE.setCode(newData.getCode());
-        dataPE.setDataSetType(getDataSetType(dataSetType));
+        dataPE.setDataSetType(getDataSetType(dataSetType, DataSetKind.LINK));
         dataPE.setRegistrator(tryToGetRegistrator(newData));
         dataStore = getDataStoreDAO().tryToFindDataStoreByCode(newData.getDataStoreCode());
         dataPE.setDataStore(dataStore);
@@ -395,7 +396,8 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         return null;
     }
 
-    private final DataSetTypePE getDataSetType(final DataSetType dataSetType)
+    private final DataSetTypePE getDataSetType(final DataSetType dataSetType,
+            DataSetKind expectedDataSetKind)
     {
         final String dataSetTypeCode = dataSetType.getCode();
         final DataSetTypePE dataSetTypeOrNull =
@@ -405,6 +407,15 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
             throw UserFailureException.fromTemplate("There is no data set type with code '%s'",
                     dataSetTypeCode);
         }
+        String dataSetKind = dataSetTypeOrNull.getDataSetKind();
+        if (dataSetKind.equals(expectedDataSetKind.toString()) == false)
+        {
+            String dataSetKinAsString = dataSetKind.toString();
+            throw new UserFailureException("Data set type " + dataSetTypeCode + " is not a "
+                    + expectedDataSetKind + " data set type but "
+                    + (dataSetKinAsString.startsWith("E") ? "an " : "a ") + dataSetKinAsString
+                    + " data set type.");
+        }
         return dataSetTypeOrNull;
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
index 13205c09c798bfdc1d81480c0a7ee6fefefea8d7..fef206d1b8ea18d88101b4e9b19c848d367db1cd 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBOTest.java
@@ -40,6 +40,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityPropertyTypeDAO
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEventDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataManagementSystemDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IGridCustomFilterDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ILocatorTypeDAO;
@@ -135,6 +136,8 @@ public abstract class AbstractBOTest extends AssertJUnit
 
     protected IDatasetLister datasetLister;
 
+    protected IExternalDataManagementSystemDAO dataManagementSystemDAO;
+
     @BeforeMethod
     public void beforeMethod()
     {
@@ -172,6 +175,7 @@ public abstract class AbstractBOTest extends AssertJUnit
         entityOperationChecker = context.mock(IEntityOperationChecker.class);
         sampleLister = context.mock(ISampleLister.class);
         datasetLister = context.mock(IDatasetLister.class);
+        dataManagementSystemDAO = context.mock(IExternalDataManagementSystemDAO.class);
         context.checking(new Expectations()
             {
                 {
@@ -222,6 +226,8 @@ public abstract class AbstractBOTest extends AssertJUnit
                     will(returnValue(corePluginDAO));
                     allowing(daoFactory).getProjectDAO();
                     will(returnValue(projectDAO));
+                    allowing(daoFactory).getExternalDataManagementSystemDAO();
+                    will(returnValue(dataManagementSystemDAO));
                 }
             });
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
index 6811f39cd9df21d40c1d1aad8d581a9781b166aa..ad2029be4e0606f5744b8c5f04d9845d325b1133 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
@@ -52,11 +52,13 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewLinkDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
@@ -77,6 +79,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.types.DataSetTypeCode;
 // TODO 2009-09-10, Piotr Buczek: write tests with many parents and cycle check
 public class DataBOTest extends AbstractBOTest
 {
+    private static final String EXTERNAL_DATA_MANAGEMENT_SYSTEM_CODE = "dms";
+
     private static final int SPEED_HINT = (Constants.DEFAULT_SPEED_HINT + Constants.MAX_SPEED) / 2;
 
     private static final TechId TECH_ID = new TechId(42l);
@@ -137,7 +141,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineWithDirectSampleConnection()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         final FileFormatTypePE fileFormatType = new FileFormatTypePE();
         final VocabularyPE vocabulary = new VocabularyPE();
         vocabulary.addTerm(new VocabularyTermPE());
@@ -178,7 +182,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineWithUserID()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         final FileFormatTypePE fileFormatType = new FileFormatTypePE();
         final VocabularyPE vocabulary = new VocabularyPE();
         vocabulary.addTerm(new VocabularyTermPE());
@@ -228,7 +232,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineWithUserEMail()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         final FileFormatTypePE fileFormatType = new FileFormatTypePE();
         final VocabularyPE vocabulary = new VocabularyPE();
         vocabulary.addTerm(new VocabularyTermPE());
@@ -279,7 +283,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineWithExistingParentDataSet()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         final FileFormatTypePE fileFormatType = new FileFormatTypePE();
         final VocabularyPE vocabulary = new VocabularyPE();
         vocabulary.addTerm(new VocabularyTermPE());
@@ -316,7 +320,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineWithNonExistingParentDataSet()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         final FileFormatTypePE fileFormatType = new FileFormatTypePE();
         final VocabularyPE vocabulary = new VocabularyPE();
         vocabulary.addTerm(new VocabularyTermPE());
@@ -327,7 +331,7 @@ public class DataBOTest extends AbstractBOTest
         final ExperimentPE experiment = new ExperimentPE();
         final DataStorePE dataStore = new DataStorePE();
         prepareDefineExternalData(dataSetType, fileFormatType, vocabulary, locatorType, dataStore);
-        final DataSetTypePE dataSetTypeUnknown = new DataSetTypePE();
+        final DataSetTypePE dataSetTypeUnknown = createDataSetType(DataSetKind.EXTERNAL);
         final DataPE parentData = new DataPE();
         parentData.setCode(PARENT_CODE);
         parentData.setDataSetType(dataSetTypeUnknown);
@@ -372,7 +376,7 @@ public class DataBOTest extends AbstractBOTest
         final LocatorTypePE locatorType = new LocatorTypePE();
         final DataStorePE dataStore = new DataStorePE();
         prepareDefineExternalData(dataSetType, fileFormatType, vocabulary, locatorType, dataStore);
-        final DataSetTypePE dataSetTypeUnknown = new DataSetTypePE();
+        final DataSetTypePE dataSetTypeUnknown = createDataSetType(DataSetKind.EXTERNAL);
         final DataPE parentData = new DataPE();
         parentData.setCode(PARENT_CODE);
         parentData.setDataSetType(dataSetTypeUnknown);
@@ -408,7 +412,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineContainerWithExistingComponent()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.CONTAINER);
         ExperimentPE experimentPE = createExperiment("EXP1");
         DataStorePE dataStore = new DataStorePE();
         prepareDefineData(dataSetType, dataStore);
@@ -440,11 +444,11 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineContainerWithNonExistingComponent()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.CONTAINER);
         final ExperimentPE experiment = createExperiment("EXP1");
         final DataStorePE dataStore = new DataStorePE();
         prepareDefineData(dataSetType, dataStore);
-        final DataSetTypePE dataSetTypeUnknown = new DataSetTypePE();
+        final DataSetTypePE dataSetTypeUnknown = createDataSetType(DataSetKind.EXTERNAL);
         final DataPE component = new DataPE();
         component.setCode(COMPONENT_CODE);
         component.setDataSetType(dataSetTypeUnknown);
@@ -481,7 +485,7 @@ public class DataBOTest extends AbstractBOTest
     @Test
     public void testDefineContainerWithComponentFromDifferentSpaceFails()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.CONTAINER);
         ExperimentPE experiment1 = createExperiment("EXP1", "S1");
         ExperimentPE experiment2 = createExperiment("EXP2", "S2");
         DataStorePE dataStore = new DataStorePE();
@@ -527,6 +531,38 @@ public class DataBOTest extends AbstractBOTest
         context.assertIsSatisfied();
     }
 
+    @Test
+    public void testDefineLinkDataSet()
+    {
+        DataSetTypePE dataSetType = createDataSetType(DataSetKind.LINK);
+        dataSetType.setCode("my-type");
+        DataStorePE dataStore = new DataStorePE();
+        prepareDefineData(dataSetType, dataStore);
+        ExperimentPE experimentPE = new ExperimentPE();
+        final NewExternalData data = createLinkDataSetWithComponents("x2");
+        final ExternalDataManagementSystemPE dms = new ExternalDataManagementSystemPE();
+        dms.setCode(EXTERNAL_DATA_MANAGEMENT_SYSTEM_CODE);
+        context.checking(new Expectations()
+            {
+                {
+                    one(dataManagementSystemDAO).tryToFindExternalDataManagementSystemByCode(
+                            EXTERNAL_DATA_MANAGEMENT_SYSTEM_CODE);
+                    will(returnValue(dms));
+                }
+            });
+        IDataBO dataBO = createDataBO();
+
+        dataBO.define(data, experimentPE, SourceType.MEASUREMENT);
+        DataPE dataSet = dataBO.getData();
+
+        assertEquals(DATA_SET_CODE, dataSet.getCode());
+        assertEquals("my-type", dataSet.getDataSetType().getCode());
+        assertEquals(true, dataSet.isLinkData());
+        assertEquals(dms, dataSet.tryAsLinkData().getExternalDataManagementSystem());
+        assertEquals("x2", dataSet.tryAsLinkData().getExternalCode());
+        context.assertIsSatisfied();
+    }
+
     @Test
     public void testUpdateStatuses()
     {
@@ -823,7 +859,7 @@ public class DataBOTest extends AbstractBOTest
         dataSet.setModificationDate(PRODUCTION_DATE);
         dataSet.setSample(sampleOrNull);
         dataSet.setExperiment(experimentOrNull);
-        DataSetTypePE dataSetType = new DataSetTypePE();
+        DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         dataSetType.setCode(DATA_SET_TYPE.getCode());
         DatabaseInstancePE databaseInstance = new DatabaseInstancePE();
         databaseInstance.setCode("db");
@@ -848,7 +884,7 @@ public class DataBOTest extends AbstractBOTest
         dataSet.setModificationDate(PRODUCTION_DATE);
         dataSet.setSample(sampleOrNull);
         dataSet.setExperiment(experimentOrNull);
-        DataSetTypePE dataSetType = new DataSetTypePE();
+        DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         dataSetType.setCode(DATA_SET_TYPE.getCode());
         DatabaseInstancePE databaseInstance = new DatabaseInstancePE();
         databaseInstance.setCode("db");
@@ -963,12 +999,19 @@ public class DataBOTest extends AbstractBOTest
 
     private DataSetTypePE createDataSetType()
     {
-        final DataSetTypePE dataSetType = new DataSetTypePE();
+        final DataSetTypePE dataSetType = createDataSetType(DataSetKind.EXTERNAL);
         dataSetType.setCode("data-set-type-code");
         dataSetType.setDatabaseInstance(new DatabaseInstancePE());
         return dataSetType;
     }
 
+    private DataSetTypePE createDataSetType(DataSetKind dataSetKind)
+    {
+        final DataSetTypePE dataSetType = new DataSetTypePE();
+        dataSetType.setDataSetKind(dataSetKind.toString());
+        return dataSetType;
+    }
+
     private ExperimentPE createExperiment(String experimentCode)
     {
         return createExperiment(experimentCode, "S");
@@ -1063,6 +1106,17 @@ public class DataBOTest extends AbstractBOTest
         return data;
     }
 
+    private NewLinkDataSet createLinkDataSetWithComponents(String externalCode)
+    {
+        NewLinkDataSet data = new NewLinkDataSet();
+        data.setCode(DATA_SET_CODE);
+        data.setExternalCode(externalCode);
+        data.setExternalDataManagementSystemCode(EXTERNAL_DATA_MANAGEMENT_SYSTEM_CODE);
+        data.setDataSetType(DATA_SET_TYPE);
+        data.setDataStoreCode(DATA_STORE_CODE);
+        return data;
+    }
+
     private final IDataBO createDataBO()
     {
         return new DataBO(daoFactory, EXAMPLE_SESSION, propertiesConverter, relationshipService);