diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/EntitySynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/EntitySynchronizer.java
index 61c473c6caa3e074b7e1141afab74d071297875c..13a2b02a00a161d0aeba5bf3d5c9c1d42963f9fe 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/EntitySynchronizer.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/EntitySynchronizer.java
@@ -36,6 +36,7 @@ import java.util.Set;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.time.DateUtils;
 import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 
@@ -66,6 +67,7 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.Res
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.ResourceListParserData.ProjectWithConnections;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.ResourceListParserData.SampleWithConnections;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.datasourceconnector.DataSourceConnector;
+import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.datasourceconnector.IDataSourceConnector;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.translator.INameTranslator;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.translator.PrefixBasedNameTranslator;
 import ch.ethz.sis.openbis.generic.shared.entitygraph.EntityGraph;
@@ -75,6 +77,7 @@ import ch.systemsx.cisd.common.concurrent.ParallelizedExecutor;
 import ch.systemsx.cisd.common.exceptions.Status;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
+import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
 import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.ConversionUtils;
 import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetDirectoryProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.DataSetProcessingContext;
@@ -84,6 +87,11 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager;
 import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
 import ch.systemsx.cisd.openbis.dss.generic.shared.utils.SegmentedStoreUtils;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.EncapsulatedCommonServer;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataRegistrationException;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataRegistrationTransactionWrapper;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.impl.MasterDataTransactionErrors;
+import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
@@ -145,6 +153,8 @@ public class EntitySynchronizer
 
     private final Set<String> blackListedDataSetCodes;
 
+    private final MasterDataRegistrationTransactionWrapper masterDataRegistrationTransaction;
+
     public EntitySynchronizer(IEncapsulatedOpenBISService service, String dataStoreCode, File storeRoot, Date lastSyncTimestamp,
             Set<String> dataSetsCodesToRetry, Set<String> blackListedDataSetCodes, DataSetProcessingContext context,
             SyncConfig config, Logger operationLog)
@@ -158,17 +168,20 @@ public class EntitySynchronizer
         this.context = context;
         this.config = config;
         this.operationLog = operationLog;
+        this.masterDataRegistrationTransaction = getMasterDataRegistrationTransactionWrapper();
     }
 
     public Date syncronizeEntities() throws Exception
     {
-        // operationLog.info("register master data");
-        // registerMasterData();
+        DataSourceConnector dataSourceConnector = new DataSourceConnector(config.getDataSourceURI(), config.getAuthenticationCredentials());
+        return syncronizeEntities(dataSourceConnector);
+    }
 
+    public Date syncronizeEntities(IDataSourceConnector dataSourceConnector) throws Exception
+    {
         // retrieve the document from the data source
         operationLog.info("Retrieving the resource list..");
-        DataSourceConnector connector = new DataSourceConnector(config.getDataSourceURI(), config.getAuthenticationCredentials());
-        Document doc = connector.getResourceListAsXMLDoc(Arrays.asList(ArrayUtils.EMPTY_STRING_ARRAY));
+        Document doc = dataSourceConnector.getResourceListAsXMLDoc(Arrays.asList(ArrayUtils.EMPTY_STRING_ARRAY));
 
         // Parse the resource list: This sends back all projects,
         // experiments, samples and data sets contained in the XML together with their last modification date to be used for filtering
@@ -180,11 +193,15 @@ public class EntitySynchronizer
             nameTranslator = new PrefixBasedNameTranslator(dataSourcePrefix);
         }
 
-        ResourceListParser parser = ResourceListParser.create(nameTranslator, dataStoreCode); // , lastSyncTimestamp
+        ResourceListParser parser = ResourceListParser.create(nameTranslator, dataStoreCode, masterDataRegistrationTransaction); // ,
+                                                                                                                                 // lastSyncTimestamp
         ResourceListParserData data = parser.parseResourceListDocument(doc);
 
         processDeletions(data);
 
+        operationLog.info("registering master data");
+        // registerMasterData();
+
         AtomicEntityOperationDetailsBuilder builder = new AtomicEntityOperationDetailsBuilder();
 
         for (String spaceCode : data.getHarvesterSpaceList())
@@ -416,11 +433,28 @@ public class EntitySynchronizer
 
     private void registerMasterData()
     {
-        // EncapsulatedCommonServer encapsulatedServer = EncapsulatedCommonServer.create("http://localhost:8888/openbis/openbis", "admin", "a");
-        // MasterDataRegistrationService service = new MasterDataRegistrationService(encapsulatedServer);
-        // IMasterDataRegistrationTransaction transaction = service.transaction();
-        // transaction.getOrCreateNewDataSetType("test dataset type");
-        // service.commit();
+        masterDataRegistrationTransaction.execute();
+        MasterDataTransactionErrors transactionErrors = masterDataRegistrationTransaction.getTransactionErrors();
+        if (false == transactionErrors.getErrors().isEmpty())
+        {
+            MasterDataRegistrationException masterDataRegistrationException =
+                    new MasterDataRegistrationException("Master data synchronization finished with errors:",
+                            Collections
+                                    .<MasterDataTransactionErrors> singletonList(transactionErrors));
+            operationLog.info("Master data synchronizatio finished with errors");
+            masterDataRegistrationException.logErrors(new Log4jSimpleLogger(operationLog));
+        }
+    }
+
+    private MasterDataRegistrationTransactionWrapper getMasterDataRegistrationTransactionWrapper()
+    {
+        ICommonServer commonService =
+                HttpInvokerUtils.createServiceStub(ICommonServer.class, ServiceProvider.getConfigProvider().getOpenBisServerUrl() +
+                        "/openbis/rmi-common",
+                        5 * DateUtils.MILLIS_PER_MINUTE);
+        EncapsulatedCommonServer encapsulatedServer =
+                EncapsulatedCommonServer.create(commonService, ServiceProvider.getOpenBISService().getSessionToken());
+        return new MasterDataRegistrationTransactionWrapper(encapsulatedServer);
     }
 
     private void processDeletions(ResourceListParserData data) throws NoSuchAlgorithmException, UnsupportedEncodingException
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/MasterDataParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/MasterDataParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..88f422af2f5c31ebb54808d8340386d0cfdd8f7f
--- /dev/null
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/MasterDataParser.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2016 ETH Zuerich, SIS
+ *
+ * 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.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.DataType;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.IMasterDataRegistrationTransaction;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.IPropertyAssignment;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.IPropertyType;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.ISampleType;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.IVocabulary;
+
+/**
+ * 
+ *
+ * @author Ganime Betul Akin
+ */
+public class MasterDataParser
+{
+    private final IMasterDataRegistrationTransaction masterDataRegistrationTransaction;
+    
+    private Map<String, IPropertyType> propertyTypeMap = new HashMap<String, IPropertyType>();
+
+    private Map<String, IVocabulary> vocabularyMap = new HashMap<String, IVocabulary>();
+
+    /**
+     * @param masterDataRegistrationTransaction
+     */
+    public MasterDataParser(IMasterDataRegistrationTransaction masterDataRegistrationTransaction)
+    {
+        this.masterDataRegistrationTransaction = masterDataRegistrationTransaction;
+    }
+
+    public void parseMasterData(Document doc, XPath xpath, String uri) throws XPathExpressionException
+    {
+        XPathExpression expr =
+                xpath.compile("//s:url/s:loc[normalize-space(.)='" + uri + "']//following-sibling::*[local-name() = 'masterData'][1]");
+        Node xdNode = (Node) expr.evaluate(doc, XPathConstants.NODE);
+        if (xdNode == null)
+        {
+            throw new XPathExpressionException("The master data resurce list should contain 1 master data element");
+        }
+        Element docElement = (Element) xdNode;
+
+        parseVocabularies(docElement.getElementsByTagName("vocabularies"));
+        parsePropertyTypes(docElement.getElementsByTagName("propertyTypes"));
+        parseSampleTypes(docElement.getElementsByTagName("sampleTypes"));
+    }
+
+    private void parseVocabularies(NodeList vocabulariesNode)
+    {
+        if (vocabulariesNode.getLength() == 1)
+        {
+            Element vocabsElement = (Element) vocabulariesNode.item(0);
+            NodeList vocabNodes = vocabsElement.getElementsByTagName("vocabulary");
+            for (int i = 0; i < vocabNodes.getLength(); i++)
+            {
+                Element vocabElement = (Element) vocabNodes.item(i);
+                String code = vocabElement.getAttributes().getNamedItem("code").getTextContent();
+                if (code.startsWith("$"))
+                    continue;
+                //TODO complete other attributes
+                IVocabulary newVocabulary = masterDataRegistrationTransaction.getOrCreateNewVocabulary(code);
+                vocabularyMap.put(code, newVocabulary);
+                parseVocabularyTerms(vocabElement, newVocabulary);
+            }
+        }
+    }
+
+    private void parseVocabularyTerms(Element vocabElement, IVocabulary newVocabulary)
+    {
+        NodeList termNodes = vocabElement.getElementsByTagName("term");
+        for (int i = 0; i < termNodes.getLength(); i++)
+        {
+            Element termElement = (Element) termNodes.item(i);
+            // TODO set other attributes
+            String code = termElement.getAttributes().getNamedItem("code").getTextContent();
+            newVocabulary.addTerm(masterDataRegistrationTransaction.createNewVocabularyTerm(code));
+        }
+    }
+
+    private void parseSampleTypes(NodeList sampleTypesNode)
+    {
+        if (sampleTypesNode.getLength() == 1)
+        {
+            Element sampleTypesElement = (Element) sampleTypesNode.item(0);
+            NodeList sampleTypeNodes = sampleTypesElement.getElementsByTagName("sampleType");
+            for (int i = 0; i < sampleTypeNodes.getLength(); i++)
+            {
+                Element sampleTypeElement = (Element) sampleTypeNodes.item(i);
+                String code = sampleTypeElement.getAttributes().getNamedItem("code").getTextContent();
+                ISampleType newSampleType = masterDataRegistrationTransaction.getOrCreateNewSampleType(code);
+                newSampleType.setGeneratedCodePrefix("S");
+
+                handlePropertyAssignments(newSampleType, sampleTypeElement.getElementsByTagName("propertyAssignments"));
+            }
+        }
+    }
+
+    private void handlePropertyAssignments(ISampleType newSampleType, NodeList propertyAssignmentsNode)
+    {
+        if (propertyAssignmentsNode.getLength() == 1)
+        {
+            Element propertyAssignmentsElement = (Element) propertyAssignmentsNode.item(0);
+            NodeList propertyAssignmentNodes = propertyAssignmentsElement.getElementsByTagName("propertyAssigment");
+            for (int i = 0; i < propertyAssignmentNodes.getLength(); i++)
+            {
+                Element propertyAssignmentElement = (Element) propertyAssignmentNodes.item(i);
+                // TODO set other attributes
+                String property_type_code = propertyAssignmentElement.getAttributes().getNamedItem("property_type_code").getTextContent();
+                String data_type_code = propertyAssignmentElement.getAttributes().getNamedItem("data_type_code").getTextContent();
+                if (property_type_code.startsWith("$"))
+                    continue;
+                boolean mandatory = Boolean.valueOf(propertyAssignmentElement.getAttributes().getNamedItem("mandatory").getTextContent());
+                int ordinal = Integer.valueOf(propertyAssignmentElement.getAttributes().getNamedItem("ordinal").getTextContent());
+
+                if (propertyTypeMap.get(property_type_code) != null)
+                {
+                    IPropertyAssignment assignment =
+                            masterDataRegistrationTransaction.assignPropertyType(newSampleType, propertyTypeMap.get(property_type_code));
+                    assignment.setMandatory(mandatory);
+                }
+            }
+        }
+    }
+
+    private void parsePropertyTypes(NodeList propertyTypesNode)
+    {
+        if (propertyTypesNode.getLength() == 1)
+        {
+            Element propertyTypesElement = (Element) propertyTypesNode.item(0);
+            NodeList propertyTypeNodes = propertyTypesElement.getElementsByTagName("propertyType");
+            for (int i = 0; i < propertyTypeNodes.getLength(); i++)
+            {
+                Element propertyTypeElement = (Element) propertyTypeNodes.item(i);
+                String code = propertyTypeElement.getAttributes().getNamedItem("code").getTextContent();
+                // TODO handle internal properties
+                if (code.startsWith("$"))
+                    continue;
+                String label = propertyTypeElement.getAttributes().getNamedItem("label").getTextContent();
+                String dataType = propertyTypeElement.getAttributes().getNamedItem("dataType").getTextContent();
+                String description = propertyTypeElement.getAttributes().getNamedItem("description").getTextContent();
+                boolean internalNamespace = Boolean.valueOf(propertyTypeElement.getAttributes().getNamedItem("internalNamespace").getTextContent());
+                boolean managedInternally = Boolean.valueOf(propertyTypeElement.getAttributes().getNamedItem("managedInternally").getTextContent());
+                String vocabulary = null;
+                Node namedItem = propertyTypeElement.getAttributes().getNamedItem("vocabulary");
+                if (namedItem != null)
+                {
+                    vocabulary = namedItem.getTextContent();
+                }
+                
+                IPropertyType newPropertyType = masterDataRegistrationTransaction.getOrCreateNewPropertyType(code, DataType.valueOf(dataType));
+                propertyTypeMap.put(code, newPropertyType);
+                newPropertyType.setInternalNamespace(internalNamespace);
+                newPropertyType.setManagedInternally(managedInternally);
+                newPropertyType.setLabel(label);
+                newPropertyType.setDescription(description);
+                if (vocabulary != null)
+                {
+                    newPropertyType.setVocabulary(vocabularyMap.get(vocabulary));
+                }
+                // TODO handle the case for property types that are of data type material
+            }
+        }
+    }
+}
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/ResourceListParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/ResourceListParser.java
index 7c31428637a87aeb30405c1b5045b18c0419deeb..728403185c5091505d53cc24e490efdb8a0e9ff2 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/ResourceListParser.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/harvester/synchronizer/ResourceListParser.java
@@ -49,6 +49,7 @@ import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.Res
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.ResourceListParserData.SampleWithConnections;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.translator.DefaultNameTranslator;
 import ch.ethz.sis.openbis.generic.server.dss.plugins.harvester.synchronizer.translator.INameTranslator;
+import ch.systemsx.cisd.openbis.generic.server.jython.api.v1.IMasterDataRegistrationTransaction;
 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.IEntityProperty;
@@ -80,30 +81,35 @@ public class ResourceListParser
 
     private final String dataStoreCode;
 
+    private final IMasterDataRegistrationTransaction masterDataRegistrationTransaction;
+
     public INameTranslator getNameTranslator()
     {
         return nameTranslator;
     }
 
-    private ResourceListParser(INameTranslator nameTranslator, String dataStoreCode)
+    private ResourceListParser(INameTranslator nameTranslator, String dataStoreCode,
+            IMasterDataRegistrationTransaction masterDataRegistrationTransaction)
     {
         this.data = new ResourceListParserData();
         this.nameTranslator = nameTranslator;
         this.dataStoreCode = dataStoreCode;
+        this.masterDataRegistrationTransaction = masterDataRegistrationTransaction;
     }
 
-    public static ResourceListParser create(INameTranslator nameTranslator, String dataStoreCode)
+    public static ResourceListParser create(INameTranslator nameTranslator, String dataStoreCode,
+            IMasterDataRegistrationTransaction masterDataRegistrationTransaction)
     {
         if (nameTranslator == null)
         {
-            return create(dataStoreCode);
+            return create(dataStoreCode, masterDataRegistrationTransaction);
         }
-        return new ResourceListParser(nameTranslator, dataStoreCode);
+        return new ResourceListParser(nameTranslator, dataStoreCode, masterDataRegistrationTransaction);
     }
 
-    public static ResourceListParser create(String dataStoreCode)
+    public static ResourceListParser create(String dataStoreCode, IMasterDataRegistrationTransaction masterDataRegistrationTransaction)
     {
-        return create(new DefaultNameTranslator(), dataStoreCode);
+        return create(new DefaultNameTranslator(), dataStoreCode, masterDataRegistrationTransaction);
     }
 
     public ResourceListParserData parseResourceListDocument(Document doc) throws XPathExpressionException
@@ -152,19 +158,16 @@ public class ResourceListParser
 
     private Date getResourceListTimestamp(Document doc, XPath xpath) throws XPathExpressionException
     {
-        XPathExpression expr = xpath.compile("/s:urlset/rs:md");
-        Object result = expr.evaluate(doc, XPathConstants.NODESET);
-        NodeList nodes = (NodeList) result;
-        for (int i = 0; i < nodes.getLength(); i++)
+        XPathExpression expr = xpath.compile("*[name() = 'urlset']/*[name() = 'rs:md']");
+        Node mdNode = (Node) expr.evaluate(doc, XPathConstants.NODE);
+        String timestamp = mdNode.getAttributes().getNamedItem("at").getTextContent();
+        try
         {
-            String capability = nodes.item(i).getAttributes().getNamedItem("capability").getTextContent();
-            if (capability.equals("resourcelist"))
-            {
-                String timestamp = nodes.item(i).getAttributes().getNamedItem("at").getTextContent();
-                return convertFromW3CDate(timestamp);
-            }
+            return convertFromW3CDate(timestamp);
+        } catch (ParseException e)
+        {
+            throw new XPathExpressionException("Last modification date cannot be parsed:" + timestamp);
         }
-        throw new XPathExpressionException("The master data resurce list should send a timestamp.");
     }
 
     private List<String> getResourceLocations(Document doc, XPath xpath) throws XPathExpressionException
@@ -176,14 +179,12 @@ public class ResourceListParser
         List<String> list = new ArrayList<String>();
         for (int i = 0; i < nodes.getLength(); i++)
         {
-            // System.out.print(nodes.item(i).getNodeName() + ":" + nodes.item(i).getAttributes().getNamedItem("href"));
             String uri = nodes.item(i).getTextContent();
-            // if (uri.endsWith("MASTER_DATA/MASTER_DATA/M"))
-            // {
-            // // parseMasterData(doc, xpath, uri);
-            // }
-            // else
-            if (uri.endsWith("/M"))
+            if (uri.endsWith("MASTER_DATA/MASTER_DATA/M"))
+            {
+                parseMasterData(doc, xpath, uri);
+            }
+            else if (uri.endsWith("/M"))
             {
                 list.add(uri);
             }
@@ -193,27 +194,8 @@ public class ResourceListParser
 
     private void parseMasterData(Document doc, XPath xpath, String uri) throws XPathExpressionException
     {
-        XPathExpression expr =
-                xpath.compile("//s:url/s:loc[normalize-space(.)='" + uri + "']//following-sibling::*[local-name() = 'masterData'][1]");
-        Node xdNode = (Node) expr.evaluate(doc, XPathConstants.NODE);
-        if (xdNode == null)
-        {
-            throw new XPathExpressionException("The master data resurce list should contain 1 master data element");
-        }
-        Element docElement = (Element) xdNode;
-        NodeList sampleTypesNode = docElement.getElementsByTagName("sampleTypes");
-        if (sampleTypesNode.getLength() == 1)
-        {
-            Element sampleTypesElement = (Element) sampleTypesNode.item(0);
-            NodeList sampleTypeNodes = sampleTypesElement.getElementsByTagName("sampleType");
-            for (int i = 0; i < sampleTypeNodes.getLength(); i++)
-            {
-                Element sampleTypeElement = (Element) sampleTypeNodes.item(i);
-                // TODO proper error handling needed below in case the XML is not correct and item 0 does not exist
-                String code = sampleTypeElement.getElementsByTagName("code").item(0).getTextContent();
-
-            }
-        }
+        MasterDataParser mdParser = new MasterDataParser(masterDataRegistrationTransaction);
+        mdParser.parseMasterData(doc, xpath, uri);
     }
 
     private void parseUriMetaData(Document doc, XPath xpath, String uri) throws XPathExpressionException
@@ -255,25 +237,22 @@ public class ResourceListParser
         }
 
         String lastModDataStr = lastModNode.getTextContent().trim();
-        // TODO data source servlet that generates the XML on the data source side MUST use the same format
-        return convertFromW3CDate(lastModDataStr);
-    }
-
-    private Date convertFromW3CDate(String lastModDataStr) throws XPathExpressionException
-    {
-        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
-        df1.setTimeZone(TimeZone.getTimeZone("GMT"));
-        // DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
         try
         {
-            return df1.parse(lastModDataStr);
+            return convertFromW3CDate(lastModDataStr);
         } catch (ParseException e)
         {
-            e.printStackTrace();
-            throw new XPathExpressionException("Lastmod date cannot be parsed");
+            throw new XPathExpressionException("Last modification date cannot be parsed:" + lastModDataStr);
         }
     }
 
+    private Date convertFromW3CDate(String lastModDataStr) throws ParseException
+    {
+        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
+        df1.setTimeZone(TimeZone.getTimeZone("GMT"));
+        return df1.parse(lastModDataStr);
+    }
+
     private Node extractXdNode(Document doc, XPath xpath, String uri) throws XPathExpressionException
     {
         // alternative expression: //s:url/s:loc[normalize-space(.)='" + uri + "']/../x:xd");