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 adf2ea45aa68f16070b6f97ae60f1ea593317e08..77143e16fafbc0d499c9f867caeac0c5fe3c4c41 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
@@ -90,6 +90,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDeletionDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityHistoryDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataManagementSystemDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.HibernateSearchDataProvider;
@@ -2912,8 +2913,17 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
     {
         checkSession(sessionToken);
 
-        getDAOFactory().getExternalDataManagementSystemDAO()
-                .createOrUpdateExternalDataManagementSystem(
-                        ExternalDataManagementSystemTranslator.translate(edms));
+        IDAOFactory daoFactory = getDAOFactory();
+        IExternalDataManagementSystemDAO edmsDAO = daoFactory.getExternalDataManagementSystemDAO();
+        ExternalDataManagementSystemPE edmsPE =
+                edmsDAO.tryToFindExternalDataManagementSystemByCode(edms.getCode());
+        if (edmsPE == null)
+        {
+            edmsPE = new ExternalDataManagementSystemPE();
+            edmsPE.setDatabaseInstance(daoFactory.getHomeDatabaseInstance());
+        }
+
+        edmsDAO.createOrUpdateExternalDataManagementSystem(ExternalDataManagementSystemTranslator
+                .translate(edms, edmsPE));
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SequenceNameMapper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SequenceNameMapper.java
index 21be088a308cdcf0f65ffae299dd8d0d6e8a5f42..03f17047ada396d11d09f31881d7a80c77064de4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SequenceNameMapper.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SequenceNameMapper.java
@@ -88,6 +88,7 @@ public final class SequenceNameMapper extends StandardSequenceNameMapper
         add(set, TableNames.DATA_SET_RELATIONSHIPS_VIEW);
         add(set, TableNames.DATA_SET_RELATIONSHIPS_ALL_TABLE);
         add(set, TableNames.DATA_STORE_SERVICES_DATASET_TYPES_TABLE);
+        add(set, TableNames.LINK_DATA_TABLE);
         return Collections.unmodifiableSet(set);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
index 4ba726a7840dc07c4f9b3d66bbcbcdb726a82dd8..6073949fc6a6ae52e2ac70f153dad644155724bf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslator.java
@@ -150,7 +150,7 @@ public class DataSetTranslator
             externalData = translateContainerDataSetProperties(dataPE, baseIndexURL, withDetails);
         } else if (dataPE.isLinkData())
         {
-            externalData = translateLinkDataSetProperties(dataPE, baseIndexURL);
+            externalData = translateLinkDataSetProperties(dataPE);
         } else if (dataPE instanceof ExternalDataPE)
         {
             externalData = translateDataSetProperties((ExternalDataPE) dataPE);
@@ -211,7 +211,7 @@ public class DataSetTranslator
         return containerDataSet;
     }
 
-    private static LinkDataSet translateLinkDataSetProperties(DataPE dataPE, String baseIndexURL)
+    private static LinkDataSet translateLinkDataSetProperties(DataPE dataPE)
     {
         LinkDataSet linkDataSet = new LinkDataSet();
         LinkDataPE linkDataPE = dataPE.tryAsLinkData();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslator.java
index b5ef07d5b342207a8c2b1a7fdf2e9133508acddc..ad4fb12b409bfd32f7008ab837a6c20bb6e9d1f9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslator.java
@@ -41,13 +41,10 @@ public class ExternalDataManagementSystemTranslator
         return result;
     }
 
-    public static ExternalDataManagementSystemPE translate(ExternalDataManagementSystem edms)
+    public static ExternalDataManagementSystemPE translate(ExternalDataManagementSystem edms,
+            ExternalDataManagementSystemPE result)
     {
-        ExternalDataManagementSystemPE result = new ExternalDataManagementSystemPE();
-
-        result.setId(edms.getId());
         result.setCode(edms.getCode());
-        result.setDatabaseInstance(DatabaseInstanceTranslator.translate(edms.getDatabaseInstance()));
         result.setLabel(edms.getLabel());
         result.setUrlTemplate(edms.getUrlTemplate());
         result.setOpenBIS(edms.isOpenBIS());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
index 703ab4009ee2446dd3e634af96a2449209700ad9..3641ffc386180c22aac9f3d07e39a1c042f64118 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
@@ -432,7 +432,7 @@ public class ETLServiceDatabaseTest extends AbstractDAOTest
         LinkedList<String> dataSetCodesAll = new LinkedList<String>();
         dataSetCodesAll.add("20081105092259000-20");
         dataSetCodesAll.add("20081105092259000-21");
-        dataSetCodesAll.add("20120619092259000-21");
+        dataSetCodesAll.add("20120619092259000-22");
 
         List<String> result =
                 service.filterToVisibleDataSets(sessionToken, "test_role", dataSetCodesAll);
@@ -442,7 +442,7 @@ public class ETLServiceDatabaseTest extends AbstractDAOTest
         assertTrue(result.contains("20081105092259000-20"));
         assertTrue(result.contains("20081105092259000-21"));
 
-        assertFalse(result.contains("20120619092259000-21"));
+        assertFalse(result.contains("20120619092259000-22"));
     }
 
     public void testFilterExperiments()
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
index f2bc376db139fe6daa458532d8ddbae9333de035..73a2cff78bc16cc8df0ce41faadbb0b4118e8ad4 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/datasetlister/DatasetListerTest.java
@@ -221,7 +221,7 @@ public class DatasetListerTest extends AbstractDAOTest
         assertEquals("20081105092259900-0", dataSets.get(0).getCode());
         assertEquals("STANDARD", dataSets.get(0).getDataStore().getCode());
         assertEquals(0, dataSets.get(0).getProperties().size());
-        assertEquals(11, dataSets.size());
+        assertEquals(14, dataSets.size());
     }
 
     @Test
@@ -262,6 +262,63 @@ public class DatasetListerTest extends AbstractDAOTest
         assertEquals(dataset1.tryGetContainer(), containerDataSet);
     }
 
+    @Test
+    public void testListByDataSetIdsWithLinkDataSets()
+    {
+        final Long ds1Id = 23L;
+        final Long ds2Id = 24L;
+        final Long ds3Id = 25L;
+
+        List<ExternalData> datasets = lister.listByDatasetIds(Arrays.asList(ds1Id, ds2Id, ds3Id));
+
+        assertEquals(3, datasets.size());
+        assertTrue(datasets.get(0).isLinkData());
+        assertTrue(datasets.get(1).isLinkData());
+        assertTrue(datasets.get(2).isLinkData());
+        assertNotNull(datasets.get(0).tryGetAsLinkDataSet());
+        assertNotNull(datasets.get(1).tryGetAsLinkDataSet());
+        assertNotNull(datasets.get(2).tryGetAsLinkDataSet());
+        assertEquals("20120628092259000-23", datasets.get(0).getCode());
+        assertEquals("20120628092259000-24", datasets.get(1).getCode());
+        assertEquals("20120628092259000-25", datasets.get(2).getCode());
+        assertNotNull(datasets.get(0).tryGetAsLinkDataSet().getExternalDataManagementSystem());
+        assertNotNull(datasets.get(1).tryGetAsLinkDataSet().getExternalDataManagementSystem());
+        assertNotNull(datasets.get(2).tryGetAsLinkDataSet().getExternalDataManagementSystem());
+        assertEquals(1L, datasets.get(0).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .getId().longValue());
+        assertEquals(1L, datasets.get(1).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .getId().longValue());
+        assertEquals(2L, datasets.get(2).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .getId().longValue());
+        assertEquals("DMS_1", datasets.get(0).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getCode());
+        assertEquals("DMS_1", datasets.get(1).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getCode());
+        assertEquals("DMS_2", datasets.get(2).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getCode());
+        assertEquals("Test EDMS", datasets.get(0).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getLabel());
+        assertEquals("Test EDMS", datasets.get(1).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getLabel());
+        assertEquals("Test External openBIS instance", datasets.get(2).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getLabel());
+        assertEquals("http://example.edms.pl/code=${code}", datasets.get(0).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getUrlTemplate());
+        assertEquals("http://example.edms.pl/code=${code}", datasets.get(1).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getUrlTemplate());
+        assertEquals("http://www.openbis.ch/perm_id=${code}", datasets.get(2).tryGetAsLinkDataSet()
+                .getExternalDataManagementSystem().getUrlTemplate());
+        assertFalse(datasets.get(0).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .isOpenBIS());
+        assertFalse(datasets.get(1).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .isOpenBIS());
+        assertTrue(datasets.get(2).tryGetAsLinkDataSet().getExternalDataManagementSystem()
+                .isOpenBIS());
+        assertEquals("CODE1", datasets.get(0).tryGetAsLinkDataSet().getExternalCode());
+        assertEquals("CODE2", datasets.get(1).tryGetAsLinkDataSet().getExternalCode());
+        assertEquals("CODE3", datasets.get(2).tryGetAsLinkDataSet().getExternalCode());
+    }
+
     @Test
     public void testContainerParentPopulated()
     {
@@ -326,7 +383,7 @@ public class DatasetListerTest extends AbstractDAOTest
         assertEquals("42", ((DataSet) dataSet).getShareId());
         assertEquals(4711L, ((DataSet) dataSet).getSize().longValue());
         assertEquals(DataSetArchivingStatus.AVAILABLE, ((DataSet) dataSet).getStatus());
-        assertEquals(17, list.size());
+        assertEquals(20, list.size());
     }
 
     @Test
@@ -349,7 +406,7 @@ public class DatasetListerTest extends AbstractDAOTest
         DataSetShareId dataSet2 = list.get(1);
         assertEquals("20081105092159111-1", dataSet2.getDataSetCode());
         assertEquals("42", dataSet2.getShareId());
-        assertEquals(19, list.size());
+        assertEquals(22, list.size());
     }
 
     private void assertSameDataSetsForSameCode(Map<String, ExternalData> dataSetsByCode,
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAOTest.java
index 475a44eafe7b95dbdc4eab902331924ebd2bf905..1d7d2a4c6b80f3ff25a82de1c86cb131e14e3aac 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAOTest.java
@@ -48,8 +48,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 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.LinkDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
@@ -83,6 +85,8 @@ public final class DataDAOTest extends AbstractDAOTest
 
     private final String VIRTUAL_DATA_SET_TYPE_CODE = "CONTAINER_TYPE";
 
+    private final String LINK_DATA_SET_TYPE_CODE = "LINK_TYPE";
+
     @Test
     public final void testListSampleDataSets()
     {
@@ -177,6 +181,19 @@ public final class DataDAOTest extends AbstractDAOTest
         assertDataEqual(data, dataSet);
     }
 
+    @Test
+    public void testFindFullLinkDataSet()
+    {
+        IDataDAO dataDAO = daoFactory.getDataDAO();
+        String dataSetCode = daoFactory.getPermIdDAO().createPermId();
+        LinkDataPE linkData = createLinkDataSet(dataSetCode, "ext-1", pickASample());
+        dataDAO.createDataSet(linkData, getTestPerson());
+
+        DataPE dataSet = dataDAO.tryToFindFullDataSetByCode(dataSetCode, true, true);
+
+        assertDataEqual(linkData, dataSet);
+    }
+
     @Test
     public void testCreateVirtualDataSetWithComponents()
     {
@@ -262,6 +279,22 @@ public final class DataDAOTest extends AbstractDAOTest
         return data;
     }
 
+    private LinkDataPE createLinkDataSet(String dataSetCode, String externalDataSetCode,
+            SamplePE sample)
+    {
+        LinkDataPE data = new LinkDataPE();
+
+        data.setCode(dataSetCode);
+        data.setDataSetType(getDataSetType(LINK_DATA_SET_TYPE_CODE));
+        data.setExperiment(pickAnExperiment());
+        data.setSampleAcquiredFrom(sample);
+        data.setPlaceholder(false);
+        data.setDataStore(pickADataStore());
+        data.setExternalCode(externalDataSetCode);
+        data.setExternalDataManagementSystem(pickAnExternalDataManagementSystem());
+        return data;
+    }
+
     private void assertDataEqual(DataPE expectedDataSet, DataPE dataSet)
     {
         assertEquals(expectedDataSet.getCode(), dataSet.getCode());
@@ -271,7 +304,8 @@ public final class DataDAOTest extends AbstractDAOTest
         assertEquals(expectedDataSet.isMeasured(), dataSet.isMeasured());
         assertEquals(expectedDataSet.tryGetSample(), dataSet.tryGetSample());
         assertEquals(expectedDataSet.isContainer(), dataSet.isContainer());
-        if (expectedDataSet.isContainer() == false)
+        assertEquals(expectedDataSet.isLinkData(), dataSet.isLinkData());
+        if (expectedDataSet.isContainer() == false && expectedDataSet.isLinkData() == false)
         {
             ExternalDataPE expectedExternalData = expectedDataSet.tryAsExternalData();
             ExternalDataPE externalData = dataSet.tryAsExternalData();
@@ -281,6 +315,13 @@ public final class DataDAOTest extends AbstractDAOTest
             assertEquals(expectedExternalData.getComplete(), externalData.getComplete());
             assertEquals(expectedExternalData.getStorageFormat(), externalData.getStorageFormat());
         }
+        if (expectedDataSet.isLinkData())
+        {
+            assertEquals(expectedDataSet.tryAsLinkData().getExternalCode(), dataSet.tryAsLinkData()
+                    .getExternalCode());
+            assertEquals(expectedDataSet.tryAsLinkData().getExternalDataManagementSystem().getId(),
+                    dataSet.tryAsLinkData().getExternalDataManagementSystem().getId());
+        }
     }
 
     @Test
@@ -479,6 +520,12 @@ public final class DataDAOTest extends AbstractDAOTest
         return daoFactory.getDataStoreDAO().tryToFindDataStoreByCode("STANDARD");
     }
 
+    protected ExternalDataManagementSystemPE pickAnExternalDataManagementSystem()
+    {
+        return daoFactory.getExternalDataManagementSystemDAO()
+                .tryToFindExternalDataManagementSystemByCode("DMS_2");
+    }
+
     protected DataSetTypePE getDataSetType(DataSetTypeCode type)
     {
         return getDataSetType(type.getCode());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
index e30dda32c5ca3bff5e911fc4fbc6d3023e61d5f9..9d780f599cf3b36d1ebd3a649e27410a4020fcef 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/DataSetTranslatorTest.java
@@ -29,6 +29,7 @@ import ch.systemsx.cisd.common.types.BooleanOrUnknown;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetRelationshipPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
@@ -37,8 +38,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DeletionPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.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.LinkDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
@@ -193,6 +196,59 @@ public class DataSetTranslatorTest extends AssertJUnit
         assertEquals(null, externalData.getDeletion());
     }
 
+    @Test
+    public void testTranslateLinkDataPE()
+    {
+        LinkDataPE linkDataPE = new LinkDataPE();
+        linkDataPE.setCode("TEST_CODE");
+        linkDataPE.setDataStore(createStore());
+        linkDataPE.setExternalCode("TEST EXTERNAL CODE");
+
+        ExperimentPE experimentPE = new ExperimentPE();
+        experimentPE.setCode("my-experiment");
+        experimentPE.setExperimentType(new ExperimentTypePE());
+        ProjectPE projectPE = new ProjectPE();
+        projectPE.setCode("my-project");
+        SpacePE groupPE = new SpacePE();
+        groupPE.setCode("my-group");
+        DatabaseInstancePE databaseInstancePE = new DatabaseInstancePE();
+        databaseInstancePE.setCode("my-instance");
+        groupPE.setDatabaseInstance(databaseInstancePE);
+        projectPE.setSpace(groupPE);
+        experimentPE.setProject(projectPE);
+        linkDataPE.setExperiment(experimentPE);
+
+        ExternalDataManagementSystemPE edms = new ExternalDataManagementSystemPE();
+        edms.setDatabaseInstance(databaseInstancePE);
+        edms.setCode("EDMS");
+        edms.setLabel("Label");
+        linkDataPE.setExternalDataManagementSystem(edms);
+
+        linkDataPE.addParentRelationship(createParentRelationship(linkDataPE, "parent-1"));
+        linkDataPE.addParentRelationship(createParentRelationship(linkDataPE, "parent-2"));
+
+        ExternalData externalData = DataSetTranslator.translate(linkDataPE, BASE_INDEX_URL);
+
+        assertEquals("my-experiment", externalData.getExperiment().getCode());
+        assertEquals(2, externalData.getParents().size());
+        Set<String> parentCodes = extractParentCodes(externalData);
+        assertEquals(true, parentCodes.contains("parent-1"));
+        assertEquals(true, parentCodes.contains("parent-2"));
+        assertEquals(false, externalData.isDerived());
+        assertNull(externalData.getDeletion());
+
+        assertTrue(externalData.isLinkData());
+        assertNotNull(externalData.tryGetAsLinkDataSet());
+        LinkDataSet linkData = externalData.tryGetAsLinkDataSet();
+        assertEquals(linkDataPE.getCode(), linkData.getCode());
+        assertEquals(linkDataPE.getExternalCode(), linkData.getExternalCode());
+        assertNotNull(linkData.getExternalDataManagementSystem());
+        assertEquals(linkDataPE.getExternalDataManagementSystem().getCode(), linkData
+                .getExternalDataManagementSystem().getCode());
+        assertEquals(linkDataPE.getExternalDataManagementSystem().getLabel(), linkData
+                .getExternalDataManagementSystem().getLabel());
+    }
+
     private Set<String> extractParentCodes(ExternalData externalData)
     {
         final Set<String> result = new HashSet<String>();
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslatorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslatorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..46e5788f60956ebfb5267de83a773724329bd1c8
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/translator/ExternalDataManagementSystemTranslatorTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 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.translator;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemPE;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class ExternalDataManagementSystemTranslatorTest extends AssertJUnit
+{
+
+    @Test
+    public void testTranslatePEtoDTO()
+    {
+        ExternalDataManagementSystemPE edmsPE = new ExternalDataManagementSystemPE();
+        DatabaseInstancePE databaseInstancePE = new DatabaseInstancePE();
+        databaseInstancePE.setCode("my-instance");
+        edmsPE.setDatabaseInstance(databaseInstancePE);
+        edmsPE.setId(Math.round(10000.0d * Math.random()));
+        edmsPE.setCode("TEST_EDMS");
+        edmsPE.setLabel("This is only a test");
+        edmsPE.setUrlTemplate("http://www.facebook.com/${code}");
+        edmsPE.setOpenBIS(true);
+
+        ExternalDataManagementSystem edms =
+                ExternalDataManagementSystemTranslator.translate(edmsPE);
+
+        assertNotNull(edms.getDatabaseInstance());
+        assertEquals(edmsPE.getDatabaseInstance().getCode(), edms.getDatabaseInstance().getCode());
+        assertEquals(edmsPE.getId(), edms.getId());
+        assertEquals(edmsPE.getCode(), edms.getCode());
+        assertEquals(edmsPE.getLabel(), edms.getLabel());
+        assertEquals(edmsPE.getUrlTemplate(), edms.getUrlTemplate());
+        assertTrue(edms.isOpenBIS());
+    }
+
+    @Test
+    public void testTranslateDTOtoPE()
+    {
+        ExternalDataManagementSystemPE edmsPE = new ExternalDataManagementSystemPE();
+        DatabaseInstancePE databaseInstancePE = new DatabaseInstancePE();
+        databaseInstancePE.setCode("my-instance");
+        edmsPE.setDatabaseInstance(databaseInstancePE);
+
+        ExternalDataManagementSystem edms = new ExternalDataManagementSystem();
+        DatabaseInstance dbin = new DatabaseInstance();
+        dbin.setCode("fake instance");
+        edms.setDatabaseInstance(dbin);
+        edms.setId(111L);
+        edms.setCode("TEST_EDMS");
+        edms.setLabel("This is only a test");
+        edms.setUrlTemplate("http://www.facebook.com/${code}");
+        edms.setOpenBIS(false);
+
+        ExternalDataManagementSystemTranslator.translate(edms, edmsPE);
+
+        assertNotNull(edmsPE.getDatabaseInstance());
+        assertEquals(databaseInstancePE.getCode(), edmsPE.getDatabaseInstance().getCode());
+        assertNull(edmsPE.getId());
+        assertEquals(edms.getCode(), edmsPE.getCode());
+        assertEquals(edms.getLabel(), edmsPE.getLabel());
+        assertEquals(edms.getUrlTemplate(), edmsPE.getUrlTemplate());
+        assertFalse(edmsPE.isOpenBIS());
+    }
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
index 5ca487e4b1e474f2ed4b605ae44755cbd832d96f..83c343b45be960c61ab08259f40d5e319c5aab13 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/remoteapitest/api/v1/GeneralInformationServiceJsonApiTest.java
@@ -440,7 +440,7 @@ public class GeneralInformationServiceJsonApiTest extends RemoteApiTestCase
     public void testListDataSetTypes()
     {
         List<DataSetType> dataSetTypes = generalInformationService.listDataSetTypes(sessionToken);
-        assertEquals(4, dataSetTypes.size());
+        assertEquals(5, dataSetTypes.size());
 
         Collections.sort(dataSetTypes, new ToStringComparator());
         DataSetType dataSetType = dataSetTypes.get(1);
diff --git a/openbis/sourceTest/sql/postgresql/113/008=data_all.tsv b/openbis/sourceTest/sql/postgresql/113/008=data_all.tsv
index 48988e8c23fc05bd84d27a9af5f54bef01f5bab7..e273fae76540459e89ad5d0ba024d95ac0512e5a 100644
--- a/openbis/sourceTest/sql/postgresql/113/008=data_all.tsv
+++ b/openbis/sourceTest/sql/postgresql/113/008=data_all.tsv
@@ -16,4 +16,7 @@
 19	20081105092259000-19	4	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	8	1	t	\N	2	\N	\N	\N	\N
 20	20081105092259000-20	2	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	8	1	t	\N	2	\N	\N	\N	\N
 21	20081105092259000-21	2	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	8	1	t	\N	2	\N	\N	\N	\N
-22	20120619092259000-21	2	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	23	1	t	\N	2	\N	\N	\N	\N
+22	20120619092259000-22	2	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	23	1	t	\N	2	\N	\N	\N	\N
+23	20120628092259000-23	5	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	23	1	t	\N	2	\N	\N	\N	\N
+24	20120628092259000-24	5	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	23	1	t	\N	2	\N	\N	\N	\N
+25	20120628092259000-25	5	\N	2008-11-05 09:22:59.203+01	2008-11-05 09:22:59.313+01	f	t	2009-03-23 15:34:44.462776+01	23	1	t	\N	2	\N	\N	\N	\N
diff --git a/openbis/sourceTest/sql/postgresql/113/014=data_set_types.tsv b/openbis/sourceTest/sql/postgresql/113/014=data_set_types.tsv
index 366b4e043338466d55deac2a31436053c561ed8c..956c75fd4dca5b606ebea39e81e4aa93120d382a 100644
--- a/openbis/sourceTest/sql/postgresql/113/014=data_set_types.tsv
+++ b/openbis/sourceTest/sql/postgresql/113/014=data_set_types.tsv
@@ -2,3 +2,4 @@
 2	HCS_IMAGE	High Content Screening Image	1	2009-03-23 15:34:44.462776+01	\N	\N	f	EXTERNAL
 3	HCS_IMAGE_ANALYSIS_DATA	Data derived from analysis of HCS images	1	2009-03-23 15:34:44.462776+01	\N	\N	f	EXTERNAL
 4	CONTAINER_TYPE	A container (virtual) data set type	1	2011-05-09 12:24:44.462776+02	\N	\N	f	CONTAINER
+5	LINK_TYPE	A link data set type	1	2012-06-26 12:24:44.462776+02	\N	\N	f	LINK
diff --git a/openbis/sourceTest/sql/postgresql/113/035=link_data.tsv b/openbis/sourceTest/sql/postgresql/113/035=link_data.tsv
new file mode 100644
index 0000000000000000000000000000000000000000..995800490868d699bd01303ed6c5eff8ba404573
--- /dev/null
+++ b/openbis/sourceTest/sql/postgresql/113/035=link_data.tsv
@@ -0,0 +1,3 @@
+23	1	CODE1
+24	1	CODE2
+25	2	CODE3