Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteObjectStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteObjectStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteObjectStoreJobNode.java	(revision 49538)
@@ -0,0 +1,43 @@
+package eu.dnetlib.msro.workflows.nodes.repobye;
+
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class DeleteObjectStoreJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(DeleteObjectStoreJobNode.class);
+
+	private String objectstoreId;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(ObjectStoreService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception {
+		log.info("preparing blackboard job: delete of objectstore " + getObjectstoreId());
+		job.setAction("DELETE");
+		job.getParameters().put("obsID", getObjectstoreId());
+	}
+
+	/**
+	 * @return the objectstoreId
+	 */
+	public String getObjectstoreId() {
+		return objectstoreId;
+	}
+
+	/**
+	 * @param objectstoreId
+	 *            the objectstoreId to set
+	 */
+	public void setObjectstoreId(final String objectstoreId) {
+		this.objectstoreId = objectstoreId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlFromEnvJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlFromEnvJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlFromEnvJobNode.java	(revision 49538)
@@ -0,0 +1,73 @@
+package eu.dnetlib.msro.workflows.nodes.db;
+
+import javax.annotation.Resource;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.enabling.database.rmi.DatabaseService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.AsyncJobNode;
+import org.apache.commons.lang.StringUtils;
+
+public class ExecuteSqlFromEnvJobNode extends AsyncJobNode {
+
+	private String db;
+	private String dbParam;
+	private String dbProperty;
+
+	private String sqlParamName;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		String sql = token.getEnv().getAttribute(sqlParamName);
+		if (StringUtils.isBlank(sql)) throw new IllegalArgumentException("Missing value in env attribute named: " + sqlParamName);
+		serviceLocator.getService(DatabaseService.class).updateSQL(findDb(token), sql);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private String findDb(final NodeToken token) {
+		if (dbParam != null && !dbParam.isEmpty()) {
+			return token.getEnv().getAttribute(dbParam);
+		} else if (dbProperty != null && !dbProperty.isEmpty()) {
+			return getPropertyFetcher().getProperty(dbProperty);
+		} else {
+			return db;
+		}
+	}
+
+	public String getDb() {
+		return db;
+	}
+
+	public void setDb(final String db) {
+		this.db = db;
+	}
+
+	public String getDbParam() {
+		return dbParam;
+	}
+
+	public void setDbParam(final String dbParam) {
+		this.dbParam = dbParam;
+	}
+
+	public String getDbProperty() {
+		return dbProperty;
+	}
+
+	public void setDbProperty(final String dbProperty) {
+		this.dbProperty = dbProperty;
+	}
+
+	public String getSqlParamName() {
+		return sqlParamName;
+	}
+
+	public void setSqlParamName(final String sqlParamName) {
+		this.sqlParamName = sqlParamName;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/QueryDbJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/QueryDbJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/QueryDbJobNode.java	(revision 49538)
@@ -0,0 +1,131 @@
+package eu.dnetlib.msro.workflows.nodes.db;
+
+import java.io.IOException;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.database.rmi.DatabaseService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.AsyncJobNode;
+
+public class QueryDbJobNode extends AsyncJobNode {
+
+	private String db;
+	private String dbParam;
+	private String dbProperty;
+
+	private String sql;
+	private String sqlForSize;
+	private String xslt;
+	private String outputEprParam;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String sqlText = fetchSqlAsText(sql);
+
+		W3CEndpointReference epr = null;
+
+		final DatabaseService dbService = serviceLocator.getService(DatabaseService.class);
+
+		if (StringUtils.isNotBlank(xslt)) {
+			final String xsltText = IOUtils.toString(getClass().getResourceAsStream(xslt));
+
+			if (StringUtils.isBlank(sqlForSize)) {
+				epr = dbService.xsltSearchSQL(findDb(token), sqlText, xsltText);
+			} else {
+				epr = dbService.alternativeXsltSearchSQL(findDb(token), sqlText, fetchSqlAsText(sqlForSize), xsltText);
+			}
+		} else {
+			if (StringUtils.isBlank(sqlForSize)) {
+				epr = dbService.searchSQL(findDb(token), sqlText);
+			} else {
+				epr = dbService.alternativeSearchSQL(findDb(token), sqlText, fetchSqlAsText(sqlForSize));
+			}
+		}
+
+		token.getEnv().setAttribute(outputEprParam, epr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private String fetchSqlAsText(final String path) throws IOException {
+		return IOUtils.toString(getClass().getResourceAsStream(path));
+	}
+
+	private String findDb(final NodeToken token) {
+		if (dbParam != null && !dbParam.isEmpty()) {
+			return token.getEnv().getAttribute(dbParam);
+		} else if (dbProperty != null && !dbProperty.isEmpty()) {
+			return getPropertyFetcher().getProperty(dbProperty);
+		} else {
+			return db;
+		}
+	}
+
+	public String getDb() {
+		return db;
+	}
+
+	public void setDb(final String db) {
+		this.db = db;
+	}
+
+	public String getDbParam() {
+		return dbParam;
+	}
+
+	public void setDbParam(final String dbParam) {
+		this.dbParam = dbParam;
+	}
+
+	public String getSql() {
+		return sql;
+	}
+
+	public void setSql(final String sql) {
+		this.sql = sql;
+	}
+
+	public String getXslt() {
+		return xslt;
+	}
+
+	public void setXslt(final String xslt) {
+		this.xslt = xslt;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getDbProperty() {
+		return dbProperty;
+	}
+
+	public void setDbProperty(final String dbProperty) {
+		this.dbProperty = dbProperty;
+	}
+
+	public String getSqlForSize() {
+		return sqlForSize;
+	}
+
+	public void setSqlForSize(final String sqlForSize) {
+		this.sqlForSize = sqlForSize;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/VerifyDatasourceJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/VerifyDatasourceJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/VerifyDatasourceJobNode.java	(revision 49538)
@@ -0,0 +1,86 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import javax.annotation.Resource;
+
+import com.google.common.base.Splitter;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class VerifyDatasourceJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private String expectedInterfaceTypologyPrefixes;
+
+	private String expectedCompliancePrefixes;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String dsId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_ID);
+		final String ifaceId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE);
+		final ISLookUpService lookupService = serviceLocator.getService(ISLookUpService.class);
+
+		String compliance;
+		try {
+			compliance = lookupService.getResourceProfileByQuery("/*[.//RESOURCE_IDENTIFIER/@value='" + dsId + "']//INTERFACE[@id = '" + ifaceId
+					+ "']/INTERFACE_EXTRA_FIELD[@name='overriding_compliance']/text()");
+		} catch (ISLookUpDocumentNotFoundException e) {
+			compliance = lookupService.getResourceProfileByQuery("/*[.//RESOURCE_IDENTIFIER/@value='" + dsId + "']//INTERFACE[@id = '" + ifaceId
+					+ "']/@compliance/string()");
+		}
+
+		final String typology = lookupService.getResourceProfileByQuery("/*[.//RESOURCE_IDENTIFIER/@value='" + dsId + "']//INTERFACE[@id = '" + ifaceId
+				+ "']/@typology/string()");
+
+		verifyValue(compliance, expectedCompliancePrefixes);
+		verifyValue(typology, expectedInterfaceTypologyPrefixes);
+		token.getFullEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE_COMPLIANCE, compliance);
+
+		if (isPending(dsId)) {
+			return "validateDs";
+		} else {
+			return Arc.DEFAULT_ARC;
+		}
+	}
+
+	private void verifyValue(final String value, final String expected) throws Exception {
+		if (expected != null && !expected.isEmpty()) {
+			for (String s : Splitter.on(",").omitEmptyStrings().trimResults().split(expected)) {
+				if (value.toLowerCase().startsWith(s.toLowerCase())) { return; }
+			}
+			throw new MSROException("Invalid value: " + value + ", Valid term prefixes are: [" + expected + "]");
+		}
+	}
+
+	private boolean isPending(final String id) throws ISLookUpDocumentNotFoundException, ISLookUpException {
+		final String query = "/*[.//RESOURCE_IDENTIFIER/@value='" + id + "']//RESOURCE_KIND/@value/string()";
+		final String res = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(query);
+		return res.trim().equals("PendingRepositoryResources");
+	}
+
+	public String getExpectedInterfaceTypologyPrefixes() {
+		return expectedInterfaceTypologyPrefixes;
+	}
+
+	public void setExpectedInterfaceTypologyPrefixes(final String expectedInterfaceTypologyPrefixes) {
+		this.expectedInterfaceTypologyPrefixes = expectedInterfaceTypologyPrefixes;
+	}
+
+	public String getExpectedCompliancePrefixes() {
+		return expectedCompliancePrefixes;
+	}
+
+	public void setExpectedCompliancePrefixes(final String expectedCompliancePrefixes) {
+		this.expectedCompliancePrefixes = expectedCompliancePrefixes;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/DeleteIndexJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/DeleteIndexJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/DeleteIndexJobNode.java	(revision 49538)
@@ -0,0 +1,49 @@
+package eu.dnetlib.msro.workflows.nodes.index;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.provision.index.rmi.IndexService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+
+public class DeleteIndexJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(DeleteIndexJobNode.class);
+
+	private String indexId;
+	private String defaultIndexId;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(IndexService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception {
+		log.info("deleting index id = " + getIndexId());
+
+		job.setAction("DELETE");
+		job.getParameters().put("id", getIndexId());
+		job.getParameters().put("backend_Id", defaultIndexId);
+
+	}
+
+	public String getIndexId() {
+		return indexId;
+	}
+
+	public void setIndexId(final String indexId) {
+		this.indexId = indexId;
+	}
+
+	public String getDefaultIndexId() {
+		return defaultIndexId;
+	}
+
+	public void setDefaultIndexId(final String defaultIndexId) {
+		this.defaultIndexId = defaultIndexId;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMetaWfJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMetaWfJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMetaWfJobNode.java	(revision 49538)
@@ -0,0 +1,98 @@
+package eu.dnetlib.msro.workflows.nodes.repobye;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class DeleteMetaWfJobNode extends SimpleJobNode {
+
+	private String metaWfId;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private static final Log log = LogFactory.getLog(DeleteMetaWfJobNode.class);
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(metaWfId);
+		final Document doc = new SAXReader().read(new StringReader(profile));
+
+		final String dsId = doc.valueOf("//DATAPROVIDER/@id");
+		final String dsName = doc.valueOf("//DATAPROVIDER/text()");
+		final String ifaceId = doc.valueOf("//DATAPROVIDER/@interface");
+		final String destroyWfId = doc.valueOf("//CONFIGURATION/@destroyWorkflow");
+
+		log.info("Removing a MetaWf of dataprovider: " + dsId);
+
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, dsId);
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_NAME, dsName);
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE, ifaceId);
+
+		final ISRegistryService registry = serviceLocator.getService(ISRegistryService.class);
+
+		for (Object o : doc.selectNodes("//WORKFLOW")) {
+			final String wfId = ((Node) o).valueOf("@id");
+			try {
+				registry.deleteProfile(wfId);
+				log.info(" - Deleted Workflow: " + wfId);
+			} catch (Exception e) {
+				log.error(" - (ERR) Error deleting profile " + wfId);
+			}
+		}
+		registry.deleteProfile(metaWfId);
+		log.info(" - Deleted MetaWorkflow: " + metaWfId);
+
+		registry.deleteProfile(destroyWfId);
+		log.info(" - Deleted destroy workflow: " + destroyWfId);
+
+		verifyDatasource(dsId, ifaceId);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private void verifyDatasource(final String dsId, final String ifaceId) throws Exception {
+		final StringWriter sw = new StringWriter();
+
+		sw.append("for $x in collection('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType') where");
+		sw.append("  $x//DATAPROVIDER/@id = '" + dsId + "' and ");
+		sw.append("  $x//DATAPROVIDER/@interface = '" + ifaceId + "' and ");
+		sw.append("  $x//RESOURCE_IDENTIFIER/@value != '" + metaWfId + "' ");
+		sw.append("return $x//RESOURCE_IDENTIFIER/@value/string()");
+
+		final boolean active = !serviceLocator.getService(ISLookUpService.class).quickSearchProfile(sw.toString()).isEmpty();
+
+		log.info(" - Updating iface, active status: " + active);
+
+		updateIfaceActivationStatus(dsId, ifaceId, active);
+	}
+
+	protected void updateIfaceActivationStatus(final String dsId, final String ifaceId, final boolean active) throws Exception {
+		serviceLocator.getService(ISRegistryService.class).updateProfileNode(dsId, "//INTERFACE[@id = '" + ifaceId + "']/@active", "'" + active + "'");
+	}
+
+	public String getMetaWfId() {
+		return metaWfId;
+	}
+
+	public void setMetaWfId(final String metaWfId) {
+		this.metaWfId = metaWfId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/RegisterMetaWfJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/RegisterMetaWfJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/RegisterMetaWfJobNode.java	(revision 49538)
@@ -0,0 +1,73 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import javax.annotation.Resource;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants.WorkflowStatus;
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+
+public class RegisterMetaWfJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+	private String adminEmail;
+
+	private String wfName;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String dsId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_ID);
+		final String dsName = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_NAME);
+		final String ifaceId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE);
+
+		final String metaWfId = registerDatasourceWorkflow(dsId, dsName, ifaceId);
+
+		token.getFullEnv().setAttribute("META_WORKFLOW_ID", metaWfId);
+		token.getFullEnv().setAttribute("META_WORKFLOW_STATUS", WorkflowStatus.ASSIGNED.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String registerDatasourceWorkflow(final String dsId, final String dsName, final String ifaceId) throws ISRegistryException, IOException {
+		final StringWriter sw = new StringWriter();
+		IOUtils.copy(getClass().getResourceAsStream("/eu/dnetlib/msro/workflows/templates/meta-workflow.xml.st"), sw);
+
+		final StringTemplate st = new StringTemplate(sw.toString());
+		st.setAttribute("dsId", dsId);
+		st.setAttribute("ifaceId", ifaceId);
+		st.setAttribute("dsName", StringEscapeUtils.escapeXml(dsName));
+		st.setAttribute("section", "dataproviders");
+		st.setAttribute("wfName", StringEscapeUtils.escapeXml(getWfName()));
+		st.setAttribute("wfFamily", StringEscapeUtils.escapeXml(getWfName()));
+		st.setAttribute("adminEmail", adminEmail);
+		st.setAttribute("status", WorkflowStatus.ASSIGNED.toString());
+
+		return serviceLocator.getService(ISRegistryService.class).registerProfile(st.toString());
+	}
+
+	public String getWfName() {
+		return wfName;
+	}
+
+	public void setWfName(final String wfName) {
+		this.wfName = wfName;
+	}
+
+	public String getAdminEmail() {
+		return adminEmail;
+	}
+
+	public void setAdminEmail(final String adminEmail) {
+		this.adminEmail = adminEmail;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetEnvParameterJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetEnvParameterJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetEnvParameterJobNode.java	(revision 49538)
@@ -0,0 +1,33 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+public class SetEnvParameterJobNode extends SimpleJobNode {
+
+	private String parameterName;
+	private String parameterValue;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		token.getEnv().setAttribute(parameterName, parameterValue);
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getParameterName() {
+		return parameterName;
+	}
+
+	public void setParameterName(final String parameterName) {
+		this.parameterName = parameterName;
+	}
+
+	public String getParameterValue() {
+		return parameterValue;
+	}
+
+	public void setParameterValue(final String parameterValue) {
+		this.parameterValue = parameterValue;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/PrepareCreateIndexJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/PrepareCreateIndexJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/PrepareCreateIndexJobNode.java	(revision 49538)
@@ -0,0 +1,51 @@
+package eu.dnetlib.msro.workflows.nodes.index;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class PrepareCreateIndexJobNode extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(PrepareCreateIndexJobNode.class);
+
+	private String layout;
+	private String format;
+	private String interpretation;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		log.info("Preparing env for CreateIndexJobNode");
+		token.getEnv().setAttribute("layout", layout);
+		token.getEnv().setAttribute("format", format);
+		token.getEnv().setAttribute("interpretation", interpretation);
+		return null;
+	}
+
+	public String getLayout() {
+		return layout;
+	}
+
+	public void setLayout(final String layout) {
+		this.layout = layout;
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public void setFormat(final String format) {
+		this.format = format;
+	}
+
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/is/ValidateProfilesJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/is/ValidateProfilesJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/is/ValidateProfilesJobNode.java	(revision 49538)
@@ -0,0 +1,98 @@
+package eu.dnetlib.msro.workflows.nodes.is;
+
+import java.io.StringReader;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.xml.XMLConstants;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class ValidateProfilesJobNode extends SimpleJobNode implements ProgressJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private int total = 0;
+	private int current = 0;
+
+	private static final Log log = LogFactory.getLog(ValidateProfilesJobNode.class);
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+
+		final ISLookUpService lookup = serviceLocator.getService(ISLookUpService.class);
+		final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+		int invalidTotals = 0;
+
+		final List<String> list = lookup.listResourceTypes();
+
+		this.total = list.size();
+		this.current = 0;
+		for (String resourceType : list) {
+			int valid = 0;
+			int invalid = 0;
+
+			final String schemaSource = lookup.getResourceTypeSchema(resourceType);
+			final Schema schema = schemaFactory.newSchema(new StreamSource(new StringReader(schemaSource)));
+			final Validator validator = schema.newValidator();
+
+			for (String profile : lookup.quickSearchProfile("/RESOURCE_PROFILE[./HEADER/RESOURCE_TYPE/@value='" + resourceType + "']")) {
+				try {
+					validator.validate(new StreamSource(new StringReader(profile)));
+					valid++;
+				} catch (Exception e) {
+					invalid++;
+				}
+			}
+			invalidTotals += invalid;
+
+			final String message = String.format("Valid: %s, Invalid: %s, Total: %s", valid, invalid, valid + invalid);
+			token.getEnv().setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + resourceType, message);
+			log.info("Validation of " + resourceType + " profiles: " + message);
+		}
+
+		if (invalidTotals > 0) { throw new MSROException("Validation wf has found " + invalidTotals + " invalid profiles"); }
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	@Override
+	public ProgressProvider getProgressProvider() {
+		return new ProgressProvider() {
+
+			@Override
+			public boolean isInaccurate() {
+				return false;
+			}
+
+			@Override
+			public int getTotalValue() {
+				return total;
+			}
+
+			@Override
+			public int getCurrentValue() {
+				return current;
+			}
+		};
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardWorkflowJobListener.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardWorkflowJobListener.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardWorkflowJobListener.java	(revision 49538)
@@ -0,0 +1,97 @@
+package eu.dnetlib.msro.workflows.nodes.blackboard;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+
+import eu.dnetlib.enabling.tools.blackboard.AbstractBlackboardJobListener;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class BlackboardWorkflowJobListener extends AbstractBlackboardJobListener {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(BlackboardWorkflowJobListener.class);
+
+	/**
+	 * workflow engine.
+	 */
+	private Engine engine;
+
+	/**
+	 * workflow node token.
+	 */
+	private NodeToken token;
+
+	@Override
+	protected void onDone(final BlackboardJob job) {
+		log.debug("Blackboard workflow node DONE");
+		complete(job, Arc.DEFAULT_ARC);
+	}
+
+	public BlackboardWorkflowJobListener(final Engine engine, final NodeToken token) {
+		super();
+		this.engine = engine;
+		this.token = token;
+	}
+
+	@Override
+	final public void processJob(final BlackboardJob job) {
+		token.getEnv().setTransientAttribute(WorkflowsConstants.BLACKBOARD_JOB, job);
+		super.processJob(job);
+	}
+
+	@Override
+	final protected void onFailed(final BlackboardJob job) {
+		log.warn("Blackboard workflow node FAILED: " + job.getError());
+		token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
+		token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, job.getError());
+		complete(job, "failed");
+	}
+
+	final protected void complete(final BlackboardJob job, final String arc) {
+		final Env env = token.getEnv();
+
+		populateEnv(env, job.getParameters());
+
+		engine.complete(token, arc);
+		engine.executeQueuedArcTokens(token.getProcess());
+	}
+
+	protected void populateEnv(final Env env, Map<String, String> responseParams) {
+		for (Entry<String, String> entry : responseParams.entrySet()) {
+			env.setAttribute(WorkflowsConstants.BLACKBOARD_PARAM_PREFIX + entry.getKey(), entry.getValue());
+		}
+	}
+
+	@Override
+	protected void onOngoing(final BlackboardJob job) {
+		token.getEnv().setAttribute(WorkflowsConstants.BLACKBOARD_IS_GOING, true);
+	}
+
+	public Engine getEngine() {
+		return engine;
+	}
+
+	public void setEngine(final Engine engine) {
+		this.engine = engine;
+	}
+
+	public NodeToken getToken() {
+		return token;
+	}
+
+	public void setToken(final NodeToken token) {
+		this.token = token;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/FindDateRangeForIncrementalHarvestingJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/FindDateRangeForIncrementalHarvestingJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/FindDateRangeForIncrementalHarvestingJobNode.java	(revision 49538)
@@ -0,0 +1,102 @@
+package eu.dnetlib.msro.workflows.nodes.collect;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.common.logging.DnetLogger;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class FindDateRangeForIncrementalHarvestingJobNode extends SimpleJobNode {
+	
+	private String fromDateParam;
+	private String untilDateParam;
+	private long ONE_DAY = 1000 * 60 * 60 * 24;	
+	
+	@Resource(name = "msroWorkflowLogger")
+	private DnetLogger dnetLogger;
+	
+	private static final Log log = LogFactory.getLog(FindDateRangeForIncrementalHarvestingJobNode.class);
+	
+	@Override
+	protected String execute(NodeToken token) throws Exception {
+		final String profId = findCurrentWfProfileId(token);
+		final String fromDate = calculateFromDate(profId); 
+		final String untilDate = null;
+		
+		log.info("Incremental Harv Details - profId: " + profId + " - from: " + fromDate + " - until: " + untilDate);
+		
+		if (fromDate != null) {
+			token.getEnv().setAttribute(getFromDateParam(), fromDate);
+		}
+		
+		//if (untilDate != null) {
+		//	token.getEnv().setAttribute(getUntilDateParam(), untilDate);
+		//}
+		
+		return Arc.DEFAULT_ARC;
+	}	
+	
+	private String calculateFromDate(final String profId) {
+		final long d = findLastSuccessStartDate(profId);
+		return (d > 0) ? (new SimpleDateFormat("yyyy-MM-dd")).format(new Date(d - ONE_DAY)) : null;
+	}
+
+	private long findLastSuccessStartDate(String profId) {
+		long res = -1;
+		
+		final Iterator<Map<String, String>> iter = dnetLogger.find(WorkflowsConstants.SYSTEM_WF_PROFILE_ID, profId);
+		while (iter.hasNext()) {
+			final Map<String, String> map = iter.next();
+			if ("true".equalsIgnoreCase(map.get(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY))) {
+				final long curr = NumberUtils.toLong(map.get(WorkflowsConstants.SYSTEM_START_DATE), -1);
+				if (curr > res) {
+					res = curr;
+				}
+			}
+		}
+		return res;
+	}
+
+	private String findCurrentWfProfileId(NodeToken token) throws MSROException {
+		final String p1 = token.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID);
+		if (p1 != null && !p1.isEmpty()) {
+			return p1;
+		}
+		final String p2 = token.getFullEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID);
+		if (p2 != null && !p2.isEmpty()) {
+			return p2;
+		}
+		final String p3 = token.getProcess().getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID);
+		if (p3 != null && !p3.isEmpty()) {
+			return p3;
+		}
+		throw new MSROException("Missing property in env: " + WorkflowsConstants.SYSTEM_WF_PROFILE_ID);
+	}
+
+	public String getFromDateParam() {
+		return fromDateParam;
+	}
+	public void setFromDateParam(String fromDateParam) {
+		this.fromDateParam = fromDateParam;
+	}
+	public String getUntilDateParam() {
+		return untilDateParam;
+	}
+	public void setUntilDateParam(String untilDateParam) {
+		this.untilDateParam = untilDateParam;
+	}
+	
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/CleanJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/CleanJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/CleanJobNode.java	(revision 49538)
@@ -0,0 +1,59 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.utility.cleaner.rmi.CleanerService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class CleanJobNode extends SimpleJobNode {
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String ruleId;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+
+		final W3CEndpointReference inputEpr = new EPRUtils().getEpr(token.getEnv().getAttribute(inputEprParam));
+		final W3CEndpointReference outputEpr = ruleId == null || ruleId.isEmpty() ? inputEpr : serviceLocator.getService(CleanerService.class).clean(inputEpr,
+				ruleId);
+
+		token.getEnv().setAttribute(outputEprParam, outputEpr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(final String ruleId) {
+		this.ruleId = ruleId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/ProgressJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/ProgressJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/ProgressJobNode.java	(revision 49538)
@@ -0,0 +1,8 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+
+public interface ProgressJobNode {
+
+	public ProgressProvider getProgressProvider();
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/TransformJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/TransformJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/TransformJobNode.java	(revision 49538)
@@ -0,0 +1,57 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.transformation.service.rmi.TransformationService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class TransformJobNode extends SimpleJobNode {
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String ruleId;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final W3CEndpointReference inputEpr = new EPRUtils().getEpr(token.getEnv().getAttribute(inputEprParam));
+		final W3CEndpointReference outputEpr = serviceLocator.getService(TransformationService.class).transform(ruleId, inputEpr);
+
+		token.getEnv().setAttribute(outputEprParam, outputEpr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getRuleId() {
+		return ruleId;
+	}
+
+	public void setRuleId(final String ruleId) {
+		this.ruleId = ruleId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyUnaryFunction.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyUnaryFunction.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyUnaryFunction.java	(revision 49538)
@@ -0,0 +1,22 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import java.util.Map;
+
+import eu.dnetlib.miscutils.functional.UnaryFunction;
+
+public abstract class GroovyUnaryFunction implements UnaryFunction<String, String> {
+
+	private Map<String, String> params;
+
+	@Override
+	abstract public String evaluate(String input);
+
+	public Map<String, String> getParams() {
+		return params;
+	}
+
+	public void setParams(final Map<String, String> params) {
+		this.params = params;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/ExecuteSqlJobNode.java	(revision 49538)
@@ -0,0 +1,80 @@
+package eu.dnetlib.msro.workflows.nodes.db;
+
+import java.io.IOException;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.io.IOUtils;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.database.rmi.DatabaseService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.AsyncJobNode;
+
+public class ExecuteSqlJobNode extends AsyncJobNode {
+
+	private String db;
+	private String dbParam;
+	private String dbProperty;
+
+	private String sql;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		serviceLocator.getService(DatabaseService.class).updateSQL(findDb(token), fetchSqlAsText(sql));
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private String fetchSqlAsText(final String path) throws IOException {
+		return IOUtils.toString(getClass().getResourceAsStream(path));
+	}
+
+	private String findDb(final NodeToken token) {
+		if (dbParam != null && !dbParam.isEmpty()) {
+			return token.getEnv().getAttribute(dbParam);
+		} else if (dbProperty != null && !dbProperty.isEmpty()) {
+			return getPropertyFetcher().getProperty(dbProperty);
+		} else {
+			return db;
+		}
+	}
+
+	public String getDb() {
+		return db;
+	}
+
+	public void setDb(final String db) {
+		this.db = db;
+	}
+
+	public String getDbParam() {
+		return dbParam;
+	}
+
+	public void setDbParam(final String dbParam) {
+		this.dbParam = dbParam;
+	}
+
+	public String getDbProperty() {
+		return dbProperty;
+	}
+
+	public void setDbProperty(final String dbProperty) {
+		this.dbProperty = dbProperty;
+	}
+
+	public String getSql() {
+		return sql;
+	}
+
+	public void setSql(final String sql) {
+		this.sql = sql;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/OngoingBlackboardWorkflowJobListener.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/OngoingBlackboardWorkflowJobListener.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/OngoingBlackboardWorkflowJobListener.java	(revision 49538)
@@ -0,0 +1,21 @@
+package eu.dnetlib.msro.workflows.nodes.blackboard;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+
+public class OngoingBlackboardWorkflowJobListener extends BlackboardWorkflowJobListener {
+
+	public OngoingBlackboardWorkflowJobListener(Engine engine, NodeToken token) {
+		super(engine, token);
+	}
+
+	@Override
+	protected void onOngoing(BlackboardJob job) {
+		super.onOngoing(job);
+		complete(job, Arc.DEFAULT_ARC);
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetFormatInfoJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetFormatInfoJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SetFormatInfoJobNode.java	(revision 49538)
@@ -0,0 +1,94 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import static java.lang.String.format;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class SetFormatInfoJobNode extends SimpleJobNode {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(SetFormatInfoJobNode.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	private String format;
+	private String formatParam = "format";
+
+	private String layout;
+	private String layoutParam = "layout";
+
+	private String interpretation;
+	private String interpretationParam = "interpretation";
+
+	/**
+	 * {@inheritDoc}
+	 * 
+	 * @see com.googlecode.sarasvati.mem.MemNode#execute(com.googlecode.sarasvati.Engine, com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	public String execute(final NodeToken token) {
+
+		log.info(format("setting mdFromat: %s, layout: %s, interpretation: %s", getFormat(), getLayout(), getInterpretation()));
+
+		token.getEnv().setAttribute(getFormatParam(), getFormat());
+		token.getEnv().setAttribute(getLayoutParam(), getLayout());
+		token.getEnv().setAttribute(getInterpretationParam(), getInterpretation());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public void setFormat(final String format) {
+		this.format = format;
+	}
+
+	public String getLayout() {
+		return layout;
+	}
+
+	public void setLayout(final String layout) {
+		this.layout = layout;
+	}
+
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+	public String getFormatParam() {
+		return formatParam;
+	}
+
+	public void setFormatParam(final String formatParam) {
+		this.formatParam = formatParam;
+	}
+
+	public String getLayoutParam() {
+		return layoutParam;
+	}
+
+	public void setLayoutParam(final String layoutParam) {
+		this.layoutParam = layoutParam;
+	}
+
+	public String getInterpretationParam() {
+		return interpretationParam;
+	}
+
+	public void setInterpretationParam(final String interpretationParam) {
+		this.interpretationParam = interpretationParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProcessQueue.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProcessQueue.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProcessQueue.java	(revision 49538)
@@ -0,0 +1,41 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import java.util.Comparator;
+import java.util.concurrent.PriorityBlockingQueue;
+
+import org.apache.commons.lang.math.NumberUtils;
+
+import com.googlecode.sarasvati.GraphProcess;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class ProcessQueue extends PriorityBlockingQueue<GraphProcess> {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -8342381671561461487L;
+
+	@Override
+	public void put(GraphProcess e) {
+		// TODO Auto-generated method stub
+		super.put(e);
+	}
+
+	private static final int INITIAL_SIZE = 20;
+	
+	public ProcessQueue() {
+		super(INITIAL_SIZE, new Comparator<GraphProcess>() {
+			
+			@Override
+			public int compare(GraphProcess p1, GraphProcess p2) {
+				int n1 = NumberUtils.toInt(p1.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PRIORITY), WorkflowsConstants.DEFAULT_WF_PRIORITY);
+				int n2 = NumberUtils.toInt(p2.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PRIORITY), WorkflowsConstants.DEFAULT_WF_PRIORITY);
+				return NumberUtils.compare(n1, n2);
+			}
+		});
+	}
+	
+	
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/NodeStatus.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/NodeStatus.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/NodeStatus.java	(revision 49538)
@@ -0,0 +1,5 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+public enum NodeStatus {
+	CONFIGURED, NOT_CONFIGURED, DISABLED, SYSTEM
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateObjectStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateObjectStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateObjectStoreJobNode.java	(revision 49538)
@@ -0,0 +1,70 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+
+import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+
+public class CreateObjectStoreJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(CreateObjectStoreJobNode.class);
+
+	private String interpretation;
+	private String outputPrefix = "objectStore_";
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(ObjectStoreService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) {
+		log.info("preparing blackboard job for the creation of the objectStore ");
+		String basePath  = token.getEnv().getAttribute("objectStoreBasePath");
+		job.setAction("CREATE");
+		job.getParameters().put("interpretation", interpretation);
+		if (!StringUtils.isEmpty(basePath)) {
+			job.getParameters().put("basePath", basePath);
+		}
+	}
+
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+	public String getOutputPrefix() {
+		return outputPrefix;
+	}
+
+	public void setOutputPrefix(final String outputPrefix) {
+		this.outputPrefix = outputPrefix;
+	}
+
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+
+				env.setAttribute(getOutputPrefix() + "interpretation", interpretation);
+				env.setAttribute(getOutputPrefix() + "id", responseParams.get("objectStoreId"));
+			}
+		};
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateMDStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateMDStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/CreateMDStoreJobNode.java	(revision 49538)
@@ -0,0 +1,88 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.enabling.locators.comparators.HandledDatastructuresComparator;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+
+public class CreateMDStoreJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(CreateMDStoreJobNode.class);
+
+	private String format;
+	private String layout;
+	private String interpretation;
+	private String outputPrefix = "mdstore";
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(MDStoreService.class, new HandledDatastructuresComparator());
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) {
+		log.info("preparing blackboard job: " + getFormat());
+
+		job.setAction("CREATE");
+		job.getParameters().put("format", getFormat());
+		job.getParameters().put("interpretation", getInterpretation());
+		job.getParameters().put("layout", getLayout());
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public void setFormat(final String format) {
+		this.format = format;
+	}
+
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+	public String getLayout() {
+		return layout;
+	}
+
+	public void setLayout(final String layout) {
+		this.layout = layout;
+	}
+
+	public String getOutputPrefix() {
+		return outputPrefix;
+	}
+
+	public void setOutputPrefix(final String outputPrefix) {
+		this.outputPrefix = outputPrefix;
+	}
+
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+				env.setAttribute(getOutputPrefix() + "format", format);
+				env.setAttribute(getOutputPrefix() + "layout", layout);
+				env.setAttribute(getOutputPrefix() + "interpretation", interpretation);
+				env.setAttribute(getOutputPrefix() + "id", responseParams.get("id"));
+			}
+		};
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemGraphFactory.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemGraphFactory.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemGraphFactory.java	(revision 49538)
@@ -0,0 +1,25 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.load.NodeFactory;
+import com.googlecode.sarasvati.mem.MemGraphFactory;
+
+public class InjectableMemGraphFactory extends MemGraphFactory {
+
+	/**
+	 * custom graph factory.
+	 */
+	private NodeFactory nodeFactory;
+
+	@Override
+	public NodeFactory getNodeFactory(final String type) {
+		return nodeFactory;
+	}
+	
+	@Required
+	public void setNodeFactory(final NodeFactory nodeFactory) {
+		this.nodeFactory = nodeFactory;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/ValidateDatasourceJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/ValidateDatasourceJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/ValidateDatasourceJobNode.java	(revision 49538)
@@ -0,0 +1,40 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class ValidateDatasourceJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private static final Log log = LogFactory.getLog(ValidateDatasourceJobNode.class);
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		String oldId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_ID);
+		String newId = registerDatasourceWorkflow(oldId);
+		token.getFullEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, newId);
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, newId);
+
+		log.info("Validated datasource - OLD ID: " + oldId);
+		log.info("Validated datasource - NEW ID: " + newId);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String registerDatasourceWorkflow(final String oldId) throws ISRegistryException {
+		return serviceLocator.getService(ISRegistryService.class).validateProfile(oldId);
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/unpack/UnpackJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/unpack/UnpackJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/unpack/UnpackJobNode.java	(revision 49538)
@@ -0,0 +1,137 @@
+package eu.dnetlib.msro.workflows.nodes.unpack;
+
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.Queue;
+import java.util.concurrent.PriorityBlockingQueue;
+
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.resultset.IterableResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class UnpackJobNode extends SimpleJobNode {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(UnpackJobNode.class);
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String xpath;
+
+	private IterableResultSetFactory iterableResultSetFactory;
+	private ResultSetClientFactory resultSetClientFactory;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final Iterator<String> client = resultSetClientFactory.getClient(token.getEnv().getAttribute(inputEprParam)).iterator();
+		final Queue<String> queue = new PriorityBlockingQueue<String>();
+
+		while (queue.isEmpty() && client.hasNext()) {
+			populateQueue(queue, client.next(), xpath);
+		}
+
+		final W3CEndpointReference epr = iterableResultSetFactory.createIterableResultSet(new Iterable<String>() {
+
+			@Override
+			public Iterator<String> iterator() {
+				return new Iterator<String>() {
+
+					@Override
+					public boolean hasNext() {
+						synchronized (queue) {
+							return !queue.isEmpty();
+						}
+					}
+
+					@Override
+					public String next() {
+						synchronized (queue) {
+							final String res = queue.poll();
+							while (queue.isEmpty() && client.hasNext()) {
+								populateQueue(queue, client.next(), xpath);
+							}
+							return res;
+						}
+					}
+
+					@Override
+					public void remove() {}
+				};
+			}
+		});
+
+		token.getEnv().setAttribute(outputEprParam, epr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private void populateQueue(final Queue<String> queue, final String record, final String xpath) {
+		try {
+			final SAXReader reader = new SAXReader();
+			final Document doc = reader.read(new StringReader(record));
+			for (Object o : doc.selectNodes(xpath)) {
+				queue.add(((Node) o).asXML());
+			}
+		} catch (Exception e) {
+			log.error("Error unpacking record: \n" + record, e);
+			throw new RuntimeException(e);
+		}
+	}
+
+	public IterableResultSetFactory getIterableResultSetFactory() {
+		return iterableResultSetFactory;
+	}
+
+	@Required
+	public void setIterableResultSetFactory(final IterableResultSetFactory iterableResultSetFactory) {
+		this.iterableResultSetFactory = iterableResultSetFactory;
+	}
+
+	public ResultSetClientFactory getResultSetClientFactory() {
+		return resultSetClientFactory;
+	}
+
+	@Required
+	public void setResultSetClientFactory(final ResultSetClientFactory resultSetClientFactory) {
+		this.resultSetClientFactory = resultSetClientFactory;
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getXpath() {
+		return xpath;
+	}
+
+	public void setXpath(final String xpath) {
+		this.xpath = xpath;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfJobNode.java	(revision 49538)
@@ -0,0 +1,87 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.collect.Maps;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.metawf.DatasourceMetaWorkflow;
+import eu.dnetlib.msro.workflows.metawf.DatasourceMetaWorkflowFactory;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants.WorkflowStatus;
+
+public class UpdateMetaWfJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Resource
+	private DatasourceMetaWorkflowFactory datasourceMetaWorkflowFactory;
+
+	private String beanName;
+
+	private static final Log log = LogFactory.getLog(UpdateMetaWfJobNode.class);
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String metaWfId = token.getFullEnv().getAttribute("META_WORKFLOW_ID");
+
+		serviceLocator.getService(ISRegistryService.class).updateProfileNode(metaWfId, "//CONFIGURATION/@status", "'" + WorkflowStatus.WAIT_SYS_SETTINGS + "'");
+
+		final Map<String, String> map = Maps.newHashMap();
+		for (String s : token.getFullEnv().getAttributeNames()) {
+			map.put(s, token.getFullEnv().getAttribute(s));
+		}
+		for (String s : token.getEnv().getAttributeNames()) {
+			map.put(s, token.getEnv().getAttribute(s));
+		}
+
+		final DatasourceMetaWorkflow prototypeMetaWf = datasourceMetaWorkflowFactory.newMetaWorkflow(beanName);
+
+		log.info("Updating metaWorkflow of type: " + beanName);
+
+		final int count = prototypeMetaWf.registerAllWorkflows(map);
+		log.info("  -- Registered wfs: " + count);
+
+		final String repoByeId = prototypeMetaWf.registerDestroyWorkflow(map);
+		log.info("  -- Repo Bye Wf: " + repoByeId);
+
+		updateDatasourceWorkflow(metaWfId, repoByeId, prototypeMetaWf.asXML());
+		log.info("Done");
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	protected boolean updateDatasourceWorkflow(final String id, final String repoByeId, final String metawf) throws ISRegistryException, IOException {
+		final StringWriter sw = new StringWriter();
+		sw.append("<CONFIGURATION status='");
+		sw.append(WorkflowStatus.WAIT_USER_SETTINGS.toString());
+		sw.append("' destroyWorkflow='");
+		sw.append(repoByeId);
+		sw.append("'>");
+		sw.append(metawf);
+		sw.append("</CONFIGURATION>");
+		return serviceLocator.getService(ISRegistryService.class).updateProfileNode(id, "//CONFIGURATION", sw.toString());
+	}
+
+	@Override
+	public String getBeanName() {
+		return beanName;
+	}
+
+	@Override
+	public void setBeanName(final String name) {
+		this.beanName = name;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfStatusJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfStatusJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repohi/UpdateMetaWfStatusJobNode.java	(revision 49538)
@@ -0,0 +1,56 @@
+package eu.dnetlib.msro.workflows.nodes.repohi;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants.WorkflowStatus;
+
+public class UpdateMetaWfStatusJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String metaWfId = token.getFullEnv().getAttribute("META_WORKFLOW_ID");
+
+		final String dsId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_ID);
+		final String ifaceId = token.getFullEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE);
+
+		updateDatasource(dsId, ifaceId);
+
+		if (isReady(metaWfId)) {
+			serviceLocator.getService(ISRegistryService.class).updateProfileNode(metaWfId, "//CONFIGURATION/@status", "'" + WorkflowStatus.EXECUTABLE + "'");
+		}
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	protected void updateDatasource(final String dsId, final String ifaceId) throws Exception {
+		serviceLocator.getService(ISRegistryService.class).updateProfileNode(dsId, "//INTERFACE[@id = '" + ifaceId + "']/@active", "'true'");
+	}
+
+	private boolean isReady(final String metaWfId) throws Exception {
+		final String query = "for $x in collection('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType')"
+				+ "//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value eq '" + metaWfId + "']//WORKFLOW/@id "
+				+ "for $y in collection('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType') " + "where $y//RESOURCE_IDENTIFIER/@value = $x "
+				+ "return $y//PARAM[@required='true' and string-length(text()) = 0]/@managedBy/string()";
+
+		final List<String> list = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query);
+
+		if (list.contains("system")) { throw new MSROException("A system param is missing in profile: " + metaWfId); }
+
+		return list.isEmpty();
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParamUI.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParamUI.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParamUI.java	(revision 49538)
@@ -0,0 +1,27 @@
+package eu.dnetlib.msro.workflows.util;
+
+public class WorkflowParamUI {
+	private String label = "";
+	private String url  = "";
+	private boolean paramRequired = false;
+	
+	public String getLabel() {
+		return label;
+	}
+	public void setLabel(String label) {
+		this.label = label;
+	}
+	public String getUrl() {
+		return url;
+	}
+	public void setUrl(String url) {
+		this.url = url;
+	}
+	public boolean isParamRequired() {
+		return paramRequired;
+	}
+	public void setParamRequired(boolean paramRequired) {
+		this.paramRequired = paramRequired;
+	}
+		
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/MDStoreToApiExtraFieldJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/MDStoreToApiExtraFieldJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/MDStoreToApiExtraFieldJobNode.java	(revision 49538)
@@ -0,0 +1,121 @@
+package eu.dnetlib.msro.workflows.nodes.info;
+
+import java.io.StringReader;
+import java.util.Map;
+
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.collect.Maps;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.datasources.common.DatasourceManager;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class MDStoreToApiExtraFieldJobNode extends SimpleJobNode {
+
+	private String mdId;
+	private String datasourceId;
+	private String datasourceInterface;
+	private String extraFieldForTotal;
+	private String extraFieldForDate;
+	private String extraFieldForMdId;
+
+	@Autowired
+	private UniqueServiceLocator serviceLocator;
+
+	@Autowired
+	private DatasourceManager<?, ?> dsManager;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String xq = "for $x in collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType') " +
+				"where $x//RESOURCE_IDENTIFIER/@value='" + mdId + "' " +
+				"return concat($x//NUMBER_OF_RECORDS, ' @=@ ', $x//LAST_STORAGE_DATE)";
+
+		final String s = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xq);
+
+		final String[] arr = s.split(" @=@ ");
+
+		final Map<String, String> map = getCurrentExtraFields(datasourceId, datasourceInterface);
+		map.put(extraFieldForTotal, arr[0].trim());
+		map.put(extraFieldForDate, arr[1].trim());
+		map.put(extraFieldForMdId, mdId);
+
+		dsManager.bulkUpdateApiExtraFields(datasourceId, datasourceInterface, map);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private Map<String, String> getCurrentExtraFields(final String repoId, final String ifaceId) throws Exception {
+		final Map<String, String> res = Maps.newHashMap();
+
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);
+
+		final SAXReader reader = new SAXReader();
+		final Document doc = reader.read(new StringReader(profile));
+
+		final Node ifcNode = doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']");
+		if (ifcNode != null) {
+			for (Object o : ifcNode.selectNodes("./INTERFACE_EXTRA_FIELD")) {
+				res.put(((Node) o).valueOf("@name"), ((Node) o).getText());
+			}
+		}
+
+		return res;
+	}
+
+	public String getMdId() {
+		return mdId;
+	}
+
+	public void setMdId(final String mdId) {
+		this.mdId = mdId;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+	public String getExtraFieldForTotal() {
+		return extraFieldForTotal;
+	}
+
+	public void setExtraFieldForTotal(final String extraFieldForTotal) {
+		this.extraFieldForTotal = extraFieldForTotal;
+	}
+
+	public String getExtraFieldForDate() {
+		return extraFieldForDate;
+	}
+
+	public void setExtraFieldForDate(final String extraFieldForDate) {
+		this.extraFieldForDate = extraFieldForDate;
+	}
+
+	public String getExtraFieldForMdId() {
+		return extraFieldForMdId;
+	}
+
+	public void setExtraFieldForMdId(final String extraFieldForMdId) {
+		this.extraFieldForMdId = extraFieldForMdId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/RemoveApiExtraFieldsJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/RemoveApiExtraFieldsJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/RemoveApiExtraFieldsJobNode.java	(revision 49538)
@@ -0,0 +1,91 @@
+package eu.dnetlib.msro.workflows.nodes.info;
+
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cxf.common.util.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.datasources.common.DatasourceManager;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class RemoveApiExtraFieldsJobNode extends SimpleJobNode {
+
+	private String datasourceId;
+	private String datasourceInterface;
+	private String fields;
+
+	@Autowired
+	private UniqueServiceLocator serviceLocator;
+
+	@Autowired
+	private DatasourceManager<?, ?> dsManager;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		if (!StringUtils.isEmpty(fields)) {
+			final Set<String> invalidFields = Sets.newHashSet(Splitter.on(",").omitEmptyStrings().trimResults().split(fields.toLowerCase()));
+			final Map<String, String> map = calculateValidExtraFields(datasourceId, datasourceInterface, invalidFields);
+			dsManager.bulkUpdateApiExtraFields(datasourceId, datasourceInterface, map);
+		}
+		return Arc.DEFAULT_ARC;
+	}
+
+	private Map<String, String> calculateValidExtraFields(final String repoId, final String ifaceId, final Set<String> invalidFields) throws Exception {
+		final Map<String, String> res = Maps.newHashMap();
+
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);
+
+		final SAXReader reader = new SAXReader();
+		final Document doc = reader.read(new StringReader(profile));
+
+		final Node ifcNode = doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']");
+		if (ifcNode != null) {
+			for (Object o : ifcNode.selectNodes("./INTERFACE_EXTRA_FIELD")) {
+				final String name = ((Node) o).valueOf("@name");
+				if (!invalidFields.contains(name.toLowerCase())) {
+					res.put(name, ((Node) o).getText());
+				}
+			}
+		}
+
+		return res;
+	}
+
+	public String getFields() {
+		return fields;
+	}
+
+	public void setFields(final String fields) {
+		this.fields = fields;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WfProfileDescriptor.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WfProfileDescriptor.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WfProfileDescriptor.java	(revision 49538)
@@ -0,0 +1,44 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class WfProfileDescriptor {
+		
+	private String name;
+	private String type;
+	private int priority = WorkflowsConstants.DEFAULT_WF_PRIORITY;
+	private boolean ready = false;
+	
+	private String workflowXml;
+
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getType() {
+		return type;
+	}
+	public void setType(String type) {
+		this.type = type;
+	}
+	public String getWorkflowXml() {
+		return workflowXml;
+	}
+	public void setWorkflowXml(String workflowXml) {
+		this.workflowXml = workflowXml;
+	}
+	public int getPriority() {
+		return priority;
+	}
+	public void setPriority(int priority) {
+		this.priority = priority;
+	}
+	public boolean isReady() {
+		return ready;
+	}
+	public void setReady(boolean ready) {
+		this.ready = ready;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/ObjectStoreToApiExtraFieldJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/ObjectStoreToApiExtraFieldJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/ObjectStoreToApiExtraFieldJobNode.java	(revision 49538)
@@ -0,0 +1,134 @@
+package eu.dnetlib.msro.workflows.nodes.info;
+
+import java.io.StringReader;
+import java.util.Map;
+
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.collect.Maps;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.datasources.common.DatasourceManager;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class ObjectStoreToApiExtraFieldJobNode extends SimpleJobNode {
+
+	private String objId;
+	private String datasourceId;
+	private String datasourceInterface;
+	private String extraFieldForTotal;
+	private String extraFieldForDate;
+	private String extraFieldForObjId;
+
+	@Autowired
+	private UniqueServiceLocator serviceLocator;
+
+	@Autowired
+	private DatasourceManager dsManager;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String xq = "for $x in collection('/db/DRIVER/ObjectStoreDSResources/ObjectStoreDSResourceType') " + "where $x//RESOURCE_IDENTIFIER/@value='"
+				+ objId + "' " + "return concat($x//COUNT_STORE, ' @=@ ', $x//LAST_STORAGE_DATE)";
+
+		final String s = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xq);
+
+		final String[] arr = s.split(" @=@ ");
+
+		final Map<String, String> map = getCurrentExtraFields(datasourceId, datasourceInterface);
+		map.put(extraFieldForTotal, arr[0].trim());
+		map.put(extraFieldForDate, arr[1].trim());
+		map.put(extraFieldForObjId, objId);
+
+		serviceLocator.getService(DatasourceManagerService.class).bulkUpdateApiExtraFields(datasourceId, datasourceInterface, map);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private Map<String, String> getCurrentExtraFields(final String repoId, final String ifaceId) throws Exception {
+		final Map<String, String> res = Maps.newHashMap();
+
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);
+
+		final SAXReader reader = new SAXReader();
+		final Document doc = reader.read(new StringReader(profile));
+
+		final Node ifcNode = doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']");
+		if (ifcNode != null) {
+			for (Object o : ifcNode.selectNodes("./INTERFACE_EXTRA_FIELD")) {
+				res.put(((Node) o).valueOf("@name"), ((Node) o).getText());
+			}
+		}
+
+		return res;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+	public String getExtraFieldForTotal() {
+		return extraFieldForTotal;
+	}
+
+	public void setExtraFieldForTotal(final String extraFieldForTotal) {
+		this.extraFieldForTotal = extraFieldForTotal;
+	}
+
+	public String getExtraFieldForDate() {
+		return extraFieldForDate;
+	}
+
+	public void setExtraFieldForDate(final String extraFieldForDate) {
+		this.extraFieldForDate = extraFieldForDate;
+	}
+
+	/**
+	 * @return the objId
+	 */
+	public String getObjId() {
+		return objId;
+	}
+
+	/**
+	 * @param objId
+	 *            the objId to set
+	 */
+	public void setObjId(final String objId) {
+		this.objId = objId;
+	}
+
+	/**
+	 * @return the extraFieldForObjId
+	 */
+	public String getExtraFieldForObjId() {
+		return extraFieldForObjId;
+	}
+
+	/**
+	 * @param extraFieldForObjId
+	 *            the extraFieldForObjId to set
+	 */
+	public void setExtraFieldForObjId(final String extraFieldForObjId) {
+		this.extraFieldForObjId = extraFieldForObjId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableNodeFactory.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableNodeFactory.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableNodeFactory.java	(revision 49538)
@@ -0,0 +1,57 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+import com.googlecode.sarasvati.Node;
+import com.googlecode.sarasvati.load.DefaultNodeFactory;
+import com.googlecode.sarasvati.load.SarasvatiLoadException;
+import com.googlecode.sarasvati.mem.MemNode;
+
+public class InjectableNodeFactory extends DefaultNodeFactory implements ApplicationContextAware {
+
+	private String beanNamePrefix = "wfNode";
+
+	private static final String DEFAULT_NODE_TYPE = "node";
+	
+	private transient ApplicationContext applicationContext;
+
+	public InjectableNodeFactory() {
+		super(MemNode.class);
+	}
+
+	public InjectableNodeFactory(final Class<? extends Node> defaultClass) {
+		super(defaultClass);
+	}
+
+	@Override
+	public Node newNode(final String type) throws SarasvatiLoadException {
+		
+		if (!DEFAULT_NODE_TYPE.equals(type)) {
+			final Node prototypeNode = (Node) applicationContext.getBean(beanNamePrefix + type, Node.class);
+			
+			if (prototypeNode != null) {
+				return prototypeNode;
+			} else {
+				throw new SarasvatiLoadException("cannot find bean " + beanNamePrefix + type);
+			}
+		}
+		return super.newNode(type);
+	}
+
+	@Override
+	public void setApplicationContext(final ApplicationContext context) {
+		this.applicationContext = context;
+	}
+
+	public String getBeanNamePrefix() {
+		return beanNamePrefix;
+	}
+
+	@Required
+	public void setBeanNamePrefix(final String beanNamePrefix) {
+		this.beanNamePrefix = beanNamePrefix;
+	}
+
+}
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParam.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParam.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowParam.java	(revision 49538)
@@ -0,0 +1,90 @@
+package eu.dnetlib.msro.workflows.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WorkflowParam {
+
+	private String name;
+	private String value;
+	private boolean required;
+	private boolean userParam;
+	private String type;
+	private String function;
+	private List<WorkflowParamUI> uis;
+	
+	public WorkflowParam() {
+		
+	}
+	
+	public WorkflowParam(final String name, final String value, final boolean userParam) {
+		this(name, value, false, userParam, null, null, new ArrayList<WorkflowParamUI>());
+	}
+
+	public WorkflowParam(final String name, final String value, final boolean required, final boolean userParam, final String type, final String function, final List<WorkflowParamUI> uis) {
+		this.name = ((name == null) || name.isEmpty()) ? "" : name;
+		this.value = ((value == null) || value.isEmpty()) ? "" : value;
+		this.required = required;
+		this.userParam = userParam;
+		this.type = ((type == null) || type.isEmpty()) ? "string" : type;
+		this.function = function;
+		this.uis = uis;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(final String value) {
+		this.value = value;
+	}
+
+	public boolean isRequired() {
+		return required;
+	}
+
+	public void setRequired(final boolean required) {
+		this.required = required;
+	}
+
+	public boolean isUserParam() {
+		return userParam;
+	}
+	
+	public void setUserParam(boolean userParam) {
+		this.userParam = userParam;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(final String type) {
+		this.type = type;
+	}
+
+	public String getFunction() {
+		return function;
+	}
+
+	public void setFunction(final String function) {
+		this.function = function;
+	}
+
+	public List<WorkflowParamUI> getUis() {
+		return uis;
+	}
+
+	public void setUis(List<WorkflowParamUI> uis) {
+		this.uis = uis;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/SetProviderInfoJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/SetProviderInfoJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/info/SetProviderInfoJobNode.java	(revision 49538)
@@ -0,0 +1,55 @@
+package eu.dnetlib.msro.workflows.nodes.info;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class SetProviderInfoJobNode extends SimpleJobNode {
+
+	private String providerId;
+	private String providerName;
+	private String api;
+
+	@Override
+	protected String execute(NodeToken token) throws Exception {
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, getProviderId());
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_NAME, getProviderName());
+		token.getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE, getApi());
+
+		token.getFullEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, getProviderId());
+		token.getFullEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_NAME, getProviderName());
+		token.getFullEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE, getApi());
+
+		token.getProcess().getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_ID, getProviderId());
+		token.getProcess().getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_NAME, getProviderName());
+		token.getProcess().getEnv().setAttribute(WorkflowsConstants.DATAPROVIDER_INTERFACE, getApi());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getProviderId() {
+		return providerId;
+	}
+
+	public void setProviderId(String providerId) {
+		this.providerId = providerId;
+	}
+
+	public String getProviderName() {
+		return providerName;
+	}
+
+	public void setProviderName(String providerName) {
+		this.providerName = providerName;
+	}
+
+	public String getApi() {
+		return api;
+	}
+
+	public void setApi(String api) {
+		this.api = api;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProgressProvider.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProgressProvider.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProgressProvider.java	(revision 49538)
@@ -0,0 +1,8 @@
+package eu.dnetlib.msro.workflows.util;
+
+
+public interface ProgressProvider {
+	public int getTotalValue();
+	public int getCurrentValue();
+	public boolean isInaccurate();
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SarasvatiJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SarasvatiJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SarasvatiJobNode.java	(revision 49538)
@@ -0,0 +1,151 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Resource;
+
+import com.google.gson.JsonSyntaxException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.BeanNameAware;
+
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.mem.MemNode;
+
+import eu.dnetlib.conf.PropertyFetcher;
+
+public abstract class SarasvatiJobNode extends MemNode implements BeanNameAware {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(SarasvatiJobNode.class);
+
+	private String beanName;
+
+	/**
+	 * parameter values injected as json map into subclasses instance beans.
+	 */
+	private String params;
+
+	/**
+	 * parameter values retrieved from the sarasvati Env.
+	 */
+	private String envParams;
+
+	/**
+	 * parameter values retrieved from the system properties.
+	 */
+	private String sysParams;
+
+	@Resource(name = "propertyFetcher")
+	private PropertyFetcher propertyFetcher;
+
+	@Override
+	public void execute(final Engine engine, final NodeToken token) {
+		final String prefix = "system:node:" + getName() + ":";
+
+		for (Field field : getClass().getDeclaredFields()) {
+			try {
+				field.setAccessible(true);
+				token.getEnv().setAttribute(prefix + field.getName(), "" + field.get(this));
+			} catch (Exception e) {
+				log.warn("Error accessing value of field: " + field.getName());
+			}
+		}
+	}
+
+	/**
+	 * builds a parameter map overriding values having the same name in the following order: sysparams < envparams < params
+	 * 
+	 * @param token
+	 * @return
+	 */
+	protected Map<String, String> parseJsonParameters(final NodeToken token) {
+		final Map<String, String> res = Maps.newHashMap();
+		for (Entry<?, ?> e : asMapEntries(getSysParams())) {
+			String propertyName = e.getValue().toString();
+
+			if (!getPropertyFetcher().getProps().containsKey(propertyName)) {
+				log.warn("unable to find system property: '" + propertyName + "'");
+			}
+
+			String propertyValue = getPropertyFetcher().getProperty(propertyName);
+			res.put(e.getKey().toString(), propertyValue);
+		}
+		for (Entry<?, ?> e : asMapEntries(getEnvParams())) {
+			final String param = e.getValue().toString();
+
+			if (token.getEnv().hasAttribute(param)) {
+				res.put(e.getKey().toString(), token.getEnv().getAttribute(param));
+			} else {
+				res.put(e.getKey().toString(), token.getFullEnv().getAttribute(param));
+			}
+		}
+		for (Entry<?, ?> e : asMapEntries(getParams())) {
+			res.put(e.getKey().toString(), e.getValue().toString());
+		}
+		return res;
+	}
+
+	@SuppressWarnings("unchecked")
+	private Set<Map.Entry<?, ?>> asMapEntries(final String s) {
+		try {
+			return isSet(s) ? new Gson().fromJson(s, Map.class).entrySet() : new HashSet<>();
+		} catch(JsonSyntaxException e) {
+			log.error(String.format("invalid json: %s", s));
+			throw e;
+		}
+	}
+
+	private boolean isSet(final String s) {
+		return (s != null) && !s.isEmpty();
+	}
+
+	// ///////////////
+
+	public String getBeanName() {
+		return beanName;
+	}
+
+	@Override
+	public void setBeanName(final String beanName) {
+		this.beanName = beanName;
+	}
+
+	public PropertyFetcher getPropertyFetcher() {
+		return propertyFetcher;
+	}
+
+	public String getParams() {
+		return params;
+	}
+
+	public void setParams(final String params) {
+		this.params = params;
+	}
+
+	public String getEnvParams() {
+		return envParams;
+	}
+
+	public void setEnvParams(final String envParams) {
+		this.envParams = envParams;
+	}
+
+	public String getSysParams() {
+		return sysParams;
+	}
+
+	public void setSysParams(final String sysParams) {
+		this.sysParams = sysParams;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ResultsetProgressProvider.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ResultsetProgressProvider.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ResultsetProgressProvider.java	(revision 49538)
@@ -0,0 +1,50 @@
+package eu.dnetlib.msro.workflows.util;
+
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import eu.dnetlib.enabling.resultset.ResultSetFactory;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetListener;
+
+public class ResultsetProgressProvider implements ProgressProvider {
+
+	private W3CEndpointReference epr;
+	private ProcessCountingResultSetListener listener;
+		
+	public ResultsetProgressProvider(ResultSetFactory resultSetFactory,	ProcessCountingResultSetListener listener) {
+		super();
+		this.epr = resultSetFactory.createResultSet(listener);
+		this.listener = listener;
+	}
+
+	@Override
+	public int getTotalValue() {
+		return listener.getSize();
+	}
+
+	@Override
+	public int getCurrentValue() {
+		return listener.getCount();
+	}
+
+	@Override
+	public boolean isInaccurate() {
+		return listener.isInaccurate();
+	}
+
+	public W3CEndpointReference getEpr() {
+		return epr;
+	}
+
+	public void setEpr(W3CEndpointReference epr) {
+		this.epr = epr;
+	}
+
+	public ProcessCountingResultSetListener getListener() {
+		return listener;
+	}
+
+	public void setListener(ProcessCountingResultSetListener listener) {
+		this.listener = listener;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveMdStoreId.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveMdStoreId.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveMdStoreId.java	(revision 49538)
@@ -0,0 +1,168 @@
+package eu.dnetlib.msro.workflows.nodes.objectStore;
+
+import java.util.List;
+import java.util.Set;
+import javax.annotation.Resource;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import org.springframework.beans.factory.annotation.Required;
+
+/**
+ * The Class RetrieveMdStoreId is a job node used to retrieve the correct MDStore from which extract the url of the file to download.
+ * metadata format and interpretation are injected as properties
+ */
+public class RetrieveMdStoreId extends SimpleJobNode {
+
+	/** The metadata format. */
+	private String metadataFormat;
+
+	/** The interpretation. */
+	private String interpretation;
+
+	/** The provider id. */
+	private String providerId;
+
+	/** The service locator. */
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.SimpleJobNode#execute(com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+
+		String workflowQuery =
+				"for $x in collection('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType') where($x//DATAPROVIDER/@id='%s') return  distinct-values($x//WORKFLOW/@id/string())";
+
+		final ISLookUpService isLookUpService = serviceLocator.getService(ISLookUpService.class);
+		List<String> result = isLookUpService.quickSearchProfile(String.format(workflowQuery, providerId));
+		if (result.size() == 0) { throw new RuntimeException("there is no mdStore Associated to the provider " + token.getEnv().getAttribute(getProviderId())); }
+		Set<String> workflowIds = Sets.newHashSet(result);
+
+		Set<String> metadataIds = getMdStores(isLookUpService, workflowIds);
+		Gson g = new GsonBuilder().disableHtmlEscaping().create();
+		token.getEnv().setAttribute("mdId", g.toJson(metadataIds));
+
+		token.getEnv().setAttribute("mdFormat", getMetadataFormat());
+		return Arc.DEFAULT_ARC;
+	}
+
+	private Set<String> getMdStores(final ISLookUpService isLookUpService, final Set<String> workflowsId) {
+		try {
+
+			String query = "//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value='%s']//PARAM[./@category/string()='MDSTORE_ID']/text()";
+
+			Set<String> mdStores = Sets.newHashSet();
+
+			if (workflowsId == null) { return null; }
+
+			for (String workflowId : workflowsId) {
+				List<String> result = isLookUpService.quickSearchProfile(String.format(query, workflowId));
+				Set<String> metadataIds = Sets.newHashSet(result);
+				mdStores.addAll(getRightMetadataId(isLookUpService, Lists.newArrayList(metadataIds)));
+			}
+			return mdStores;
+
+		} catch (ISLookUpException e) {
+
+			return null;
+		}
+	}
+
+	/**
+	 * Gets the right metadata id whith the format metadataFormat and interpretation interpretation
+	 *
+	 * @return the right metadata id
+	 * @throws ISLookUpException
+	 */
+	private Set<String> getRightMetadataId(final ISLookUpService isLookUpService, final Iterable<String> ids) throws ISLookUpException {
+		String query =
+				"let $x:=//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value='%s'] return concat($x//METADATA_FORMAT/text(), '::<<>>::', $x//METADATA_FORMAT_INTERPRETATION/text())";
+		Set<String> result = Sets.newHashSet();
+
+		for (String id : ids) {
+
+			List<String> results = isLookUpService.quickSearchProfile(String.format(query, id));
+			if (results.size() > 0) {
+				String[] values = results.get(0).split("::<<>>::");
+				if (metadataFormat.equals(values[0].trim()) && interpretation.equals(values[1].trim())) {
+					result.add(id);
+				}
+			}
+		}
+		return result;
+
+	}
+
+	/**
+	 * Gets the interpretation.
+	 *
+	 * @return the interpretation
+	 */
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	/**
+	 * Sets the interpretation.
+	 *
+	 * @param interpretation
+	 *            the interpretation to set
+	 */
+	@Required
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+	/**
+	 * Gets the metadata format.
+	 *
+	 * @return the metadataFormat
+	 */
+	public String getMetadataFormat() {
+		return metadataFormat;
+	}
+
+	/**
+	 * Sets the metadata format.
+	 *
+	 * @param metadataFormat
+	 *            the metadataFormat to set
+	 */
+	@Required
+	public void setMetadataFormat(final String metadataFormat) {
+		this.metadataFormat = metadataFormat;
+	}
+
+	/**
+	 * Gets the provider id.
+	 *
+	 * @return the providerId
+	 */
+	public String getProviderId() {
+		return providerId;
+	}
+
+	/**
+	 * Sets the provider id.
+	 *
+	 * @param providerId
+	 *            the providerId to set
+	 */
+	public void setProviderId(final String providerId) {
+		this.providerId = providerId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DropContentObjectStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DropContentObjectStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DropContentObjectStoreJobNode.java	(revision 49538)
@@ -0,0 +1,35 @@
+package eu.dnetlib.msro.workflows.nodes.objectStore;
+
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class DropContentObjectStoreJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(DropContentObjectStoreJobNode.class);
+
+	private String objectstoreId;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(ObjectStoreService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) {
+		log.info("preparing blackboard job for the creation of the objectStore ");
+		job.getParameters().put("obsID", getObjectstoreId());
+		job.setAction("DROP_CONTENT");
+	}
+
+	public String getObjectstoreId() {
+		return objectstoreId;
+	}
+
+	public void setObjectstoreId(final String objectstoreId) {
+		this.objectstoreId = objectstoreId;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DownloadIntoObjectStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DownloadIntoObjectStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/DownloadIntoObjectStoreJobNode.java	(revision 49538)
@@ -0,0 +1,203 @@
+package eu.dnetlib.msro.workflows.nodes.objectStore;
+
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.Map;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+import eu.dnetlib.data.objectstore.rmi.MetadataObjectRecord;
+import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
+import eu.dnetlib.enabling.resultset.IterableResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.InputSource;
+
+public class DownloadIntoObjectStoreJobNode extends BlackboardJobNode implements ProgressJobNode {
+
+	private static final Log log = LogFactory.getLog(DownloadIntoObjectStoreJobNode.class);
+	private String eprParam;
+	private String objectStoreId;
+	private String idXpath; // "//*[local-name()='objIdentifier']
+	private String mimeType;
+	private String objectIsInsideEpr;
+	private String storageType;
+	private IterableResultSetFactory iterableResultSetFactory;
+	private ResultSetClientFactory resultSetClientFactory;
+	private ResultsetProgressProvider progressProvider;
+	private ProcessCountingResultSetFactory processCountingResultSetFactory;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(ObjectStoreService.class);
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+	public String getObjectStoreId() {
+		return objectStoreId;
+	}
+
+	public void setObjectStoreId(final String objectStoreId) {
+		this.objectStoreId = objectStoreId;
+	}
+
+	public ProgressProvider getProgressProvider(final NodeToken token) {
+
+		return progressProvider;
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception {
+
+		job.setAction("FEEDOBJECT");
+		final String eprS = token.getEnv().getAttribute(getEprParam());
+		job.getParameters().put("obsID", getObjectStoreId());
+		job.getParameters().put("mime", getMimeType());
+		final Iterator<String> client = resultSetClientFactory.getClient(eprS).iterator();
+
+		final W3CEndpointReference epr = iterableResultSetFactory.createIterableResultSet(new Iterable<String>() {
+
+			@Override
+			public Iterator<String> iterator() {
+				return new MetadataObjectIterator(client, "//*[local-name()='objIdentifier']", "xml");
+			}
+		});
+		this.progressProvider = processCountingResultSetFactory.createProgressProvider(token.getProcess(), epr);
+		job.getParameters().put("epr", progressProvider.getEpr().toString());
+
+	}
+
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+				log.info("Number of stored records: " + responseParams.get("total"));
+				env.setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "total", responseParams.get("total"));
+			}
+		};
+	}
+
+	public String getObjectIsInsideEpr() {
+		return objectIsInsideEpr;
+	}
+
+	public void setObjectIsInsideEpr(final String objectIsInsideEpr) {
+		this.objectIsInsideEpr = objectIsInsideEpr;
+	}
+
+	@Override
+	public ResultsetProgressProvider getProgressProvider() {
+		return progressProvider;
+	}
+
+	public void setProgressProvider(final ResultsetProgressProvider progressProvider) {
+		this.progressProvider = progressProvider;
+	}
+
+	public ProcessCountingResultSetFactory getProcessCountingResultSetFactory() {
+		return processCountingResultSetFactory;
+	}
+
+	public void setProcessCountingResultSetFactory(final ProcessCountingResultSetFactory processCountingResultSetFactory) {
+		this.processCountingResultSetFactory = processCountingResultSetFactory;
+	}
+
+	public ResultSetClientFactory getResultSetClientFactory() {
+		return resultSetClientFactory;
+	}
+
+	public void setResultSetClientFactory(final ResultSetClientFactory resultSetClientFactory) {
+		this.resultSetClientFactory = resultSetClientFactory;
+	}
+
+	public IterableResultSetFactory getIterableResultSetFactory() {
+		return iterableResultSetFactory;
+	}
+
+	public void setIterableResultSetFactory(final IterableResultSetFactory iterableResultSetFactory) {
+		this.iterableResultSetFactory = iterableResultSetFactory;
+	}
+
+	public String getIdXpath() {
+		return idXpath;
+	}
+
+	public void setIdXpath(final String idXpath) {
+		this.idXpath = idXpath;
+	}
+
+	public String getMimeType() {
+		return mimeType;
+	}
+
+	public void setMimeType(final String mimeType) {
+		this.mimeType = mimeType;
+	}
+
+	public String getStorageType() {
+		return storageType;
+	}
+
+	public void setStorageType(final String storageType) {
+		this.storageType = storageType;
+	}
+
+	class MetadataObjectIterator implements Iterator<String> {
+
+		private Iterator<String> inputIterator;
+
+		private String mime;
+
+		public MetadataObjectIterator(final Iterator<String> inputIterator, final String xpath, final String mime) {
+			this.inputIterator = inputIterator;
+		}
+
+		@Override
+		public boolean hasNext() {
+			return inputIterator.hasNext();
+		}
+
+		@Override
+		public String next() {
+			try {
+				String record = inputIterator.next();
+				XPath xpath = XPathFactory.newInstance().newXPath();
+				InputSource doc = new InputSource(new StringReader(record));
+				String identifier = xpath.evaluate(getIdXpath(), doc);
+				MetadataObjectRecord objectrecord = new MetadataObjectRecord(identifier, record, mime);
+				return objectrecord.toJSON();
+			} catch (Exception e) {
+				return null;
+			}
+		}
+
+		@Override
+		public void remove() {
+
+		}
+
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/UpdateObjectStoreSizeJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/UpdateObjectStoreSizeJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/UpdateObjectStoreSizeJobNode.java	(revision 49538)
@@ -0,0 +1,78 @@
+package eu.dnetlib.msro.workflows.nodes.objectStore;
+
+import javax.annotation.Resource;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.objectstore.rmi.ObjectStoreService;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class UpdateObjectStoreSizeJobNode.
+ */
+public class UpdateObjectStoreSizeJobNode extends SimpleJobNode {
+
+	/** The object store id. */
+	private String objectStoreIdParam;
+
+	/** The service locator. */
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see eu.dnetlib.msro.workflows.nodes.SimpleJobNode#execute(com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+
+		final ISRegistryService registry = serviceLocator.getService(ISRegistryService.class);
+
+		int size = serviceLocator.getService(ObjectStoreService.class, objectStoreIdParam).getSize(objectStoreIdParam);
+
+		String now = DateUtils.now_ISO8601();
+
+		String mdstoreXUpdate = "for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + objectStoreIdParam + "']"
+				+ "return update value $x//LAST_STORAGE_DATE with '" + now + "'";
+
+		registry.executeXUpdate(mdstoreXUpdate);
+
+		String mdstoreNumberXUpdate = "for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + objectStoreIdParam + "']"
+				+ "return update value $x//COUNT_STORE with '" + size + "'";
+
+		registry.executeXUpdate(mdstoreNumberXUpdate);
+
+		mdstoreNumberXUpdate = "for $x in //RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + objectStoreIdParam + "']"
+				+ "return update value $x//STORE_SIZE with '" + size + "'";
+
+		registry.executeXUpdate(mdstoreNumberXUpdate);
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	/**
+	 * Gets the object store id param.
+	 *
+	 * @return the objectStoreIdParam
+	 */
+	public String getObjectStoreIdParam() {
+		return objectStoreIdParam;
+	}
+
+	/**
+	 * Sets the object store id param.
+	 *
+	 * @param objectStoreIdParam
+	 *            the new object store id param
+	 */
+	public void setObjectStoreIdParam(final String objectStoreIdParam) {
+		this.objectStoreIdParam = objectStoreIdParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/CreateIndexJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/CreateIndexJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/CreateIndexJobNode.java	(revision 49538)
@@ -0,0 +1,194 @@
+package eu.dnetlib.msro.workflows.nodes.index;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+
+import eu.dnetlib.data.provision.index.rmi.IndexService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class CreateIndexJobNode.
+ */
+public class CreateIndexJobNode extends BlackboardJobNode {
+
+	/** The Constant log. */
+	private static final Log log = LogFactory.getLog(CreateIndexJobNode.class);
+
+	/** The output prefix. */
+	private String outputPrefix = "index_";
+
+	/** The default backend id. */
+	private String defaultBackendId;
+
+	/** The format. */
+	private String format;
+
+	/** The layout. */
+	private String layout;
+
+	/** The interpretation. */
+	private String interpretation;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(IndexService.class);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see eu.dnetlib.msro.workflows.nodes.BlackboardJobNode#prepareJob(eu.dnetlib.enabling.tools.blackboard.BlackboardJob,
+	 * com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) {
+		final String env_format = token.getFullEnv().getAttribute("format");
+		final String env_layout = token.getFullEnv().getAttribute("layout");
+		final String env_interp = token.getFullEnv().getAttribute("interpretation");
+
+		if (env_format != null && !env_format.isEmpty()) {
+			this.format = env_format;
+		}
+		if (env_layout != null && !env_layout.isEmpty()) {
+			this.layout = env_layout;
+		}
+		if (env_interp != null && !env_interp.isEmpty()) {
+			this.interpretation = env_interp;
+		}
+
+		log.info("preparing CREATE blackboard job: " + format + "-" + layout + "-" + interpretation);
+
+		job.setAction("CREATE");
+		job.getParameters().put("format", format);
+		job.getParameters().put("layout", layout);
+		job.getParameters().put("interpretation", interpretation);
+		job.getParameters().put("backend_Id", defaultBackendId);
+	}
+
+	/**
+	 * Gets the output prefix.
+	 * 
+	 * @return the output prefix
+	 */
+	public String getOutputPrefix() {
+		return outputPrefix;
+	}
+
+	/**
+	 * Sets the output prefix.
+	 * 
+	 * @param outputPrefix
+	 *            the output prefix
+	 */
+	public void setOutputPrefix(final String outputPrefix) {
+		this.outputPrefix = outputPrefix;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see eu.dnetlib.msro.workflows.nodes.BlackboardJobNode#generateBlackboardListener(com.googlecode.sarasvati.Engine,
+	 * com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+				env.setAttribute(getOutputPrefix() + "format", getFormat());
+				env.setAttribute(getOutputPrefix() + "layout", getLayout());
+				env.setAttribute(getOutputPrefix() + "interpretation", getInterpretation());
+				env.setAttribute(getOutputPrefix() + "id", responseParams.get("id"));
+			}
+		};
+	}
+
+	/**
+	 * Gets the default backend id.
+	 * 
+	 * @return the default backend id
+	 */
+	public String getDefaultBackendId() {
+		return defaultBackendId;
+	}
+
+	/**
+	 * Sets the default backend id.
+	 * 
+	 * @param defaultBackendId
+	 *            the default backend id
+	 */
+	@Required
+	public void setDefaultBackendId(final String defaultBackendId) {
+		this.defaultBackendId = defaultBackendId;
+	}
+
+	/**
+	 * Gets the format.
+	 * 
+	 * @return the format
+	 */
+	public String getFormat() {
+		return format;
+	}
+
+	/**
+	 * Sets the format.
+	 * 
+	 * @param format
+	 *            the format
+	 */
+	public void setFormat(final String format) {
+		this.format = format;
+	}
+
+	/**
+	 * Gets the layout.
+	 * 
+	 * @return the layout
+	 */
+	public String getLayout() {
+		return layout;
+	}
+
+	/**
+	 * Sets the layout.
+	 * 
+	 * @param layout
+	 *            the layout
+	 */
+	public void setLayout(final String layout) {
+		this.layout = layout;
+	}
+
+	/**
+	 * Gets the interpretation.
+	 * 
+	 * @return the interpretation
+	 */
+	public String getInterpretation() {
+		return interpretation;
+	}
+
+	/**
+	 * Sets the interpretation.
+	 * 
+	 * @param interpretation
+	 *            the interpretation
+	 */
+	public void setInterpretation(final String interpretation) {
+		this.interpretation = interpretation;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveURLSJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveURLSJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/objectStore/RetrieveURLSJobNode.java	(revision 49538)
@@ -0,0 +1,219 @@
+package eu.dnetlib.msro.workflows.nodes.objectStore;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.google.common.collect.Iterables;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.resultset.IterableResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.nodes.download.UrlExtractor;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class RetrieveURLSJobNode.
+ */
+public class RetrieveURLSJobNode extends SimpleJobNode {
+
+	/** The epr param. */
+	private String inputEprParam;
+
+	/** The output epr param. */
+	private String outputEprParam;
+
+	/** The xpath. */
+	private String xpath;
+
+	/** The xpath metadata id. */
+	private String xpathMetadataId;
+
+	/** The xpath open access. */
+	private String xpathOpenAccess;
+
+	/** The xpath embargo date. */
+	private String xpathEmbargoDate;
+
+	/** The result set client factory. */
+	@Autowired
+	private ResultSetClientFactory resultSetClientFactory;
+
+	/** The result set factory. */
+	@Resource(name = "iterableResultSetFactory")
+	private IterableResultSetFactory resultSetFactory;
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.SimpleJobNode#execute(com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final W3CEndpointReference inputEpr = (new EPRUtils()).getEpr(token.getEnv().getAttribute(inputEprParam));
+		Iterable<String> input = resultSetClientFactory.getClient(inputEpr);
+		Iterable<String> extractedUrls = Iterables.transform(input, new UrlExtractor(xpath, xpathMetadataId, xpathOpenAccess, xpathEmbargoDate));
+		W3CEndpointReference eprUrls = resultSetFactory.createIterableResultSet(extractedUrls);
+		token.getEnv().setAttribute(getOutputEprParam(), eprUrls.toString());
+		return Arc.DEFAULT_ARC;
+	}
+
+	/**
+	 * Gets the xpath.
+	 *
+	 * @return the xpath
+	 */
+	public String getXpath() {
+		return xpath;
+	}
+
+	/**
+	 * Sets the xpath.
+	 *
+	 * @param xpath
+	 *            the xpath to set
+	 */
+	public void setXpath(final String xpath) {
+		this.xpath = xpath;
+	}
+
+	/**
+	 * Gets the xpath metadata id.
+	 *
+	 * @return the xpathMetadataId
+	 */
+	public String getXpathMetadataId() {
+		return xpathMetadataId;
+	}
+
+	/**
+	 * Sets the xpath metadata id.
+	 *
+	 * @param xpathMetadataId
+	 *            the xpathMetadataId to set
+	 */
+	@Required
+	public void setXpathMetadataId(final String xpathMetadataId) {
+		this.xpathMetadataId = xpathMetadataId;
+	}
+
+	/**
+	 * Gets the result set client factory.
+	 *
+	 * @return the resultSetClientFactory
+	 */
+	public ResultSetClientFactory getResultSetClientFactory() {
+		return resultSetClientFactory;
+	}
+
+	/**
+	 * Sets the result set client factory.
+	 *
+	 * @param resultSetClientFactory
+	 *            the resultSetClientFactory to set
+	 */
+	public void setResultSetClientFactory(final ResultSetClientFactory resultSetClientFactory) {
+		this.resultSetClientFactory = resultSetClientFactory;
+	}
+
+	/**
+	 * Gets the result set factory.
+	 *
+	 * @return the resultSetFactory
+	 */
+	public IterableResultSetFactory getResultSetFactory() {
+		return resultSetFactory;
+	}
+
+	/**
+	 * Sets the result set factory.
+	 *
+	 * @param resultSetFactory
+	 *            the resultSetFactory to set
+	 */
+	public void setResultSetFactory(final IterableResultSetFactory resultSetFactory) {
+		this.resultSetFactory = resultSetFactory;
+	}
+
+	/**
+	 * Gets the output epr param.
+	 *
+	 * @return the outputEprParam
+	 */
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	/**
+	 * Sets the output epr param.
+	 *
+	 * @param outputEprParam
+	 *            the outputEprParam to set
+	 */
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	/**
+	 * Gets the input epr param.
+	 *
+	 * @return the inputEprParam
+	 */
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	/**
+	 * Sets the input epr param.
+	 *
+	 * @param inputEprParam
+	 *            the inputEprParam to set
+	 */
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	/**
+	 * Gets the xpath open access.
+	 *
+	 * @return the xpath open access
+	 */
+	public String getXpathOpenAccess() {
+		return xpathOpenAccess;
+	}
+
+	/**
+	 * Sets the xpath open access.
+	 *
+	 * @param xpathOpenAccess
+	 *            the new xpath open access
+	 */
+	public void setXpathOpenAccess(final String xpathOpenAccess) {
+		this.xpathOpenAccess = xpathOpenAccess;
+	}
+
+	/**
+	 * Gets the xpath embargo date.
+	 *
+	 * @return the xpath embargo date
+	 */
+	public String getXpathEmbargoDate() {
+		return xpathEmbargoDate;
+	}
+
+	/**
+	 * Sets the xpath embargo date.
+	 *
+	 * @param xpathEmbargoDate
+	 *            the new xpath embargo date
+	 */
+	public void setXpathEmbargoDate(final String xpathEmbargoDate) {
+		this.xpathEmbargoDate = xpathEmbargoDate;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMDStoreRecordsJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMDStoreRecordsJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMDStoreRecordsJobNode.java	(revision 49538)
@@ -0,0 +1,84 @@
+package eu.dnetlib.msro.workflows.nodes.mdstore;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class FetchMDStoreRecordsJobNode extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(FetchMDStoreRecordsJobNode.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private String mdId;
+	@Deprecated
+	/**
+	 * @Deprecated: mdFormat not used by this job node.
+	 */
+	private String mdFormat;
+	private String eprParam;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		if (getMdId() == null) {
+			setMdId(token.getEnv().getAttribute("mdId"));
+		}
+		if (getMdFormat() == null) {
+			setMdFormat(token.getEnv().getAttribute("mdFormat"));
+		}
+
+		final MDStoreService mdStoreService = serviceLocator.getService(MDStoreService.class, getMdId());
+		int size = mdStoreService.size(getMdId());
+
+		token.getEnv().setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "sourceSize", size);
+		log.info(String.format("getting MDRecords from: %s, sourceSize: %s", getMdId(), size));
+
+		final W3CEndpointReference epr = mdStoreService.deliverMDRecords(getMdId(), "", "", "");
+		if (epr == null) { throw new MSROException("unable to read MDRecords from: " + getMdId()); }
+		token.getEnv().setAttribute(getEprParam(), epr.toString());
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getMdId() {
+		return mdId;
+	}
+
+	public void setMdId(final String mdId) {
+		this.mdId = mdId;
+	}
+
+	@Deprecated
+	/**
+	 * Deprecated: MdFormat is not used by this job node
+	 */
+	public String getMdFormat() {
+		return mdFormat;
+	}
+	@Deprecated
+	/**
+	 * Deprecated: MdFormat is not used by this job node
+	 */
+	public void setMdFormat(final String mdFormat) {
+		this.mdFormat = mdFormat;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/StoreMDStoreRecordsJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/StoreMDStoreRecordsJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/StoreMDStoreRecordsJobNode.java	(revision 49538)
@@ -0,0 +1,102 @@
+package eu.dnetlib.msro.workflows.nodes.mdstore;
+
+import java.util.Map;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+public class StoreMDStoreRecordsJobNode extends BlackboardJobNode implements ProgressJobNode {
+
+	private static final Log log = LogFactory.getLog(StoreMDStoreRecordsJobNode.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	private String eprParam;
+	private String mdId;
+	private String storingType;
+	private ProcessCountingResultSetFactory processCountingResultSetFactory;
+	private ResultsetProgressProvider progressProvider;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(MDStoreService.class, mdId);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws ResultSetException {
+		job.setAction("FEED");
+
+		final String eprS = token.getEnv().getAttribute(getEprParam());
+
+		this.progressProvider = processCountingResultSetFactory.createProgressProvider(token.getProcess(), eprS);
+
+		job.getParameters().put("epr", progressProvider.getEpr().toString());
+		job.getParameters().put("storingType", getStoringType());
+		job.getParameters().put("mdId", getMdId());
+	}
+
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+				log.info("New mdstore size : " + responseParams.get("mdstoreSize"));
+				log.info("Number of write operations: " + responseParams.get("writeOps"));
+				env.setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "sinkSize", responseParams.get("mdstoreSize"));
+				env.setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "processedSize", responseParams.get("writeOps"));
+			}
+		};
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+	public String getMdId() {
+		return mdId;
+	}
+
+	public void setMdId(final String mdId) {
+		this.mdId = mdId;
+	}
+
+	public String getStoringType() {
+		return storingType;
+	}
+
+	public void setStoringType(final String storingType) {
+		this.storingType = storingType;
+	}
+
+	public ProcessCountingResultSetFactory getProcessCountingResultSetFactory() {
+		return processCountingResultSetFactory;
+	}
+
+	@Required
+	public void setProcessCountingResultSetFactory(final ProcessCountingResultSetFactory processCountingResultSetFactory) {
+		this.processCountingResultSetFactory = processCountingResultSetFactory;
+	}
+
+	@Override
+	public ProgressProvider getProgressProvider() {
+		return progressProvider;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardSubscriber.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardSubscriber.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/blackboard/BlackboardSubscriber.java	(revision 49538)
@@ -0,0 +1,61 @@
+package eu.dnetlib.msro.workflows.nodes.blackboard;
+
+import javax.annotation.Resource;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import eu.dnetlib.enabling.is.sn.rmi.ISSNException;
+import eu.dnetlib.enabling.is.sn.rmi.ISSNService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.soap.EndpointReferenceBuilder;
+
+public class BlackboardSubscriber {
+
+	/**
+	 * Logger.
+	 */
+	private static final Log log = LogFactory.getLog(BlackboardSubscriber.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	/**
+	 * service locator.
+	 */
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	/**
+	 * injected EPR builder.
+	 */
+	@Resource(name = "jaxwsEndpointReferenceBuilder")
+	private EndpointReferenceBuilder<Endpoint> eprBuilder;
+
+	/**
+	 * notification endpoint (normally the msro service).
+	 */
+	private Endpoint endpoint;
+
+	/**
+	 * performs the subscription.
+	 * 
+	 * @throws ISSNException
+	 *             could happen
+	 */
+	public void subscribeAll() throws ISSNException {
+		log.info("Subscribing msro service");
+
+		final W3CEndpointReference endpointReference = eprBuilder.getEndpointReference(getEndpoint());
+		serviceLocator.getService(ISSNService.class).subscribe(endpointReference, "UPDATE/*/*/RESOURCE_PROFILE/BODY/BLACKBOARD/LAST_RESPONSE", 0);
+	}
+
+	public Endpoint getEndpoint() {
+		return endpoint;
+	}
+
+	@Required
+	public void setEndpoint(final Endpoint endpoint) {
+		this.endpoint = endpoint;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterator.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterator.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterator.java	(revision 49538)
@@ -0,0 +1,103 @@
+package eu.dnetlib.msro.workflows.nodes.mdstore;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.data.mdstore.MDStoreServiceException;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class MultipleMdStoreIterator.
+ */
+public class MultipleMdStoreIterator implements Iterator<String> {
+
+	private static final Log log = LogFactory.getLog(MultipleMdStoreIterator.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	/** The service locator. */
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	/** The current iterator. */
+	private Iterator<String> currentIterator;
+
+	/** The result set client factory. */
+	@Autowired
+	private ResultSetClientFactory resultSetClientFactory;
+
+	/**
+	 * Instantiates a new multiple md store iterator.
+	 *
+	 * @param mdstoreLocator
+	 *            the mdstore locator
+	 * @param mdIds
+	 *            the md ids
+	 */
+	public MultipleMdStoreIterator(final UniqueServiceLocator serviceLocator, final List<String> mdIds, final ResultSetClientFactory resultSetClientFactory) {
+		this.serviceLocator = serviceLocator;
+		this.resultSetClientFactory = resultSetClientFactory;
+
+		log.info(String.format("iterating over mdIds: '%s'", mdIds));
+
+		this.currentIterator = Iterables.concat(Iterables.transform(mdIds, new Function<String, Iterable<String>>() {
+
+			@Override
+			public Iterable<String> apply(final String mdId) {
+
+				log.debug(String.format("current mdId '%s'", mdId));
+				try {
+					W3CEndpointReference epr = serviceLocator.getService(MDStoreService.class, mdId).deliverMDRecords(mdId, "", "", "");
+					return resultSetClientFactory.getClient(epr);
+				} catch (MDStoreServiceException e) {
+					log.error(e);
+					throw new RuntimeException(String.format("unable to iterate over %s", mdId), e);
+				}
+			}
+		})).iterator();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see java.util.Iterator#hasNext()
+	 */
+	@Override
+	public boolean hasNext() {
+		if (currentIterator == null) return false;
+
+		return currentIterator.hasNext();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see java.util.Iterator#next()
+	 */
+	@Override
+	public String next() {
+		return currentIterator.next();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see java.util.Iterator#remove()
+	 */
+	@Override
+	public void remove() {
+		throw new UnsupportedOperationException("Cannot remove");
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMultipleMDStores.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMultipleMDStores.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/FetchMultipleMDStores.java	(revision 49538)
@@ -0,0 +1,76 @@
+package eu.dnetlib.msro.workflows.nodes.mdstore;
+
+import java.util.List;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.google.gson.Gson;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.IterableResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class FetchMultipleMDStores extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(FetchMultipleMDStores.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private List<String> mdId;
+
+	private String eprParam;
+
+	/** The result set factory. */
+	@Resource(name = "iterableResultSetFactory")
+	private IterableResultSetFactory resultSetFactory;
+
+	/** The result set client factory. */
+	@Autowired
+	private ResultSetClientFactory resultSetClientFactory;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+
+		if (getMdId() == null) {
+			final String mdIdsJson = token.getEnv().getAttribute("mdId");
+			@SuppressWarnings("unchecked")
+			final List<String> mdIds = new Gson().fromJson(mdIdsJson, List.class);
+			log.info(String.format("fetching records for %s mdstores", mdIds.size()));
+			if (log.isDebugEnabled()) {
+				log.debug(String.format("fetching records for mdstores: %s", mdIdsJson));
+			}
+			setMdId(mdIds);
+		}
+
+		final MultipleMdStoreIterable iter = new MultipleMdStoreIterable(serviceLocator, getMdId(), resultSetClientFactory);
+		final W3CEndpointReference epr = resultSetFactory.createIterableResultSet(iter);
+		token.getEnv().setAttribute(getEprParam(), epr.toString());
+		return Arc.DEFAULT_ARC;
+	}
+
+	public List<String> getMdId() {
+		return mdId;
+	}
+
+	public void setMdId(final List<String> mdId) {
+		this.mdId = mdId;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterable.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterable.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/mdstore/MultipleMdStoreIterable.java	(revision 49538)
@@ -0,0 +1,50 @@
+package eu.dnetlib.msro.workflows.nodes.mdstore;
+
+import java.util.Iterator;
+import java.util.List;
+
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class MultipleMdStoreIterable.
+ */
+public class MultipleMdStoreIterable implements Iterable<String> {
+
+	/** The service locator. */
+	private UniqueServiceLocator serviceLocator;
+
+	/** The md ids. */
+	private List<String> mdIds;
+
+	/** The result set client factory. */
+	private ResultSetClientFactory resultSetClientFactory;
+
+	/**
+	 * Instantiates a new multiple md store iterable.
+	 *
+	 * @param serviceLocator
+	 *            the service locator
+	 * @param mdIds
+	 *            the md ids
+	 * @param resultSetClientFactory
+	 *            the result set client factory
+	 */
+	public MultipleMdStoreIterable(final UniqueServiceLocator serviceLocator, final List<String> mdIds, final ResultSetClientFactory resultSetClientFactory) {
+		super();
+		this.serviceLocator = serviceLocator;
+		this.mdIds = mdIds;
+		this.resultSetClientFactory = resultSetClientFactory;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see java.lang.Iterable#iterator()
+	 */
+	@Override
+	public Iterator<String> iterator() {
+		return new MultipleMdStoreIterator(serviceLocator, mdIds, resultSetClientFactory);
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/sel/SelectiveNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/sel/SelectiveNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/sel/SelectiveNode.java	(revision 49538)
@@ -0,0 +1,48 @@
+package eu.dnetlib.msro.workflows.nodes.sel;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import eu.dnetlib.msro.workflows.util.WorkflowParam;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+/**
+ * The Class SelectiveNode allows to decide which path a workflow must take.
+ */
+public class SelectiveNode extends SimpleJobNode {
+
+	/** The selection. */
+	private String selection = Arc.DEFAULT_ARC;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see eu.dnetlib.msro.workflows.nodes.SimpleJobNode#execute(com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		token.getEnv().setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "selection", getSelection());
+		return getSelection();
+	}
+
+	/**
+	 * Gets the selection.
+	 *
+	 * @return the selection
+	 */
+	public String getSelection() {
+		return selection;
+	}
+
+	/**
+	 * Sets the selection.
+	 *
+	 * @param selection
+	 *            the new selection
+	 */
+	public void setSelection(final String selection) {
+		this.selection = selection;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/DownloadFromMetadataJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/DownloadFromMetadataJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/DownloadFromMetadataJobNode.java	(revision 49538)
@@ -0,0 +1,269 @@
+package eu.dnetlib.msro.workflows.nodes.download;
+
+import java.util.Map;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+import com.googlecode.sarasvati.env.Env;
+import eu.dnetlib.data.download.rmi.DownloadService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class DownloadFromMetadata is a job node that send a blackboard message to the Download service to start to download file from url
+ * retrieved by Metadata .
+ */
+public class DownloadFromMetadataJobNode extends BlackboardJobNode implements ProgressJobNode {
+
+	private static final Log log = LogFactory.getLog(DownloadFromMetadataJobNode.class);
+
+	protected String regularExpression;
+	/** The inputepr param. */
+	private String inputeprParam;
+	/** The obejct store id. */
+	private String objectStoreID;
+	/** The plugin. */
+	private String plugin;
+	/** The protocol. */
+	private String protocol;
+	/** The mime type. */
+	private String mimeType;
+	private int numberOfThreads = -1;
+	private int connectTimeoutMs = -1;
+	private int readTimeoutMs = -1;
+
+	private int sleepTimeMs = 0;
+	/** The process counting result set factory. */
+	@Autowired
+	private ProcessCountingResultSetFactory processCountingResultSetFactory;
+
+	/** The progress provider. */
+	private ResultsetProgressProvider progressProvider;
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.BlackboardJobNode#obtainServiceId(com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(DownloadService.class);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.BlackboardJobNode#prepareJob(eu.dnetlib.enabling.tools.blackboard.BlackboardJob,
+	 * com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception {
+		job.setAction("DOWNLOAD");
+		final String eprS = token.getEnv().getAttribute(getInputeprParam());
+		this.progressProvider = processCountingResultSetFactory.createProgressProvider(token.getProcess(), eprS);
+		job.getParameters().put("epr", progressProvider.getEpr().toString());
+		job.getParameters().put("protocol", getProtocol());
+		job.getParameters().put("plugin", getPlugin());
+		job.getParameters().put("mimeType", getMimeType());
+		job.getParameters().put("objectStoreID", getObjectStoreID());
+		if (getNumberOfThreads() > 0) {
+			job.getParameters().put("numberOfThreads", "" + getNumberOfThreads());
+		}
+		if (getConnectTimeoutMs() > 0) {
+			job.getParameters().put("connectTimeoutMs", "" + getConnectTimeoutMs());
+		}
+		if (getReadTimeoutMs() > 0) {
+			job.getParameters().put("readTimeoutMs", "" + getReadTimeoutMs());
+		}
+		if (getSleepTimeMs() > 0) {
+			job.getParameters().put("sleepTimeMs", "" + getSleepTimeMs());
+		}
+		if (!StringUtils.isEmpty(getRegularExpression())){
+			job.getParameters().put("regularExpressions", getRegularExpression());
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.BlackboardJobNode#generateBlackboardListener(com.googlecode.sarasvati.Engine,
+	 * com.googlecode.sarasvati.NodeToken)
+	 */
+	@Override
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token) {
+
+			@Override
+			protected void populateEnv(final Env env, final Map<String, String> responseParams) {
+				env.setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "total", responseParams.get("total"));
+
+				final String base64 = responseParams.get("report");
+				if (StringUtils.isNotBlank(base64) && Base64.isBase64(base64.getBytes())) {
+					final String report = new String(Base64.decodeBase64(base64.getBytes()));
+					log.info("found download report");
+					log.debug(report);
+					env.setAttribute(WorkflowsConstants.MAIN_LOG_PREFIX + "report", report);
+				} else {
+					log.warn("unable to find or decode download report");
+				}
+			}
+		};
+	}
+
+	/**
+	 * Gets the inputepr param.
+	 *
+	 * @return the inputeprParam
+	 */
+	public String getInputeprParam() {
+		return inputeprParam;
+	}
+
+	/**
+	 * Sets the inputepr param.
+	 *
+	 * @param inputeprParam
+	 *            the inputeprParam to set
+	 */
+	public void setInputeprParam(final String inputeprParam) {
+		this.inputeprParam = inputeprParam;
+	}
+
+	/**
+	 * Gets the object store id.
+	 *
+	 * @return the objectStoreID
+	 */
+	public String getObjectStoreID() {
+		return objectStoreID;
+	}
+
+	/**
+	 * Sets the object store id.
+	 *
+	 * @param objectStoreID
+	 *            the objectStoreID to set
+	 */
+	public void setObjectStoreID(final String objectStoreID) {
+		this.objectStoreID = objectStoreID;
+	}
+
+	/**
+	 * Gets the plugin.
+	 *
+	 * @return the plugin
+	 */
+	public String getPlugin() {
+		return plugin;
+	}
+
+	/**
+	 * Sets the plugin.
+	 *
+	 * @param plugin
+	 *            the plugin to set
+	 */
+	public void setPlugin(final String plugin) {
+		this.plugin = plugin;
+	}
+
+	/**
+	 * Gets the protocol.
+	 *
+	 * @return the protol
+	 */
+	public String getProtocol() {
+		return protocol;
+	}
+
+	/**
+	 * Sets the protocol.
+	 *
+	 * @param protol
+	 *            the protol to set
+	 */
+	public void setProtocol(final String protol) {
+		this.protocol = protol;
+	}
+
+	/**
+	 * Gets the mime type.
+	 *
+	 * @return the mimeType
+	 */
+	public String getMimeType() {
+		return mimeType;
+	}
+
+	/**
+	 * Sets the mime type.
+	 *
+	 * @param mimeType
+	 *            the mimeType to set
+	 */
+	public void setMimeType(final String mimeType) {
+		this.mimeType = mimeType;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see eu.dnetlib.msro.workflows.nodes.ProgressJobNode#getProgressProvider()
+	 */
+	@Override
+	public ProgressProvider getProgressProvider() {
+		return progressProvider;
+	}
+
+	public String getRegularExpression() {
+		return regularExpression;
+	}
+
+	public void setRegularExpression(final String regularExpression) {
+		this.regularExpression = regularExpression;
+	}
+
+	public int getNumberOfThreads() {
+		return numberOfThreads;
+	}
+
+	public void setNumberOfThreads(final int numberOfThreads) {
+		this.numberOfThreads = numberOfThreads;
+	}
+
+	public int getConnectTimeoutMs() {
+		return connectTimeoutMs;
+	}
+
+	public void setConnectTimeoutMs(final int connectTimeoutMs) {
+		this.connectTimeoutMs = connectTimeoutMs;
+	}
+
+	public int getReadTimeoutMs() {
+		return readTimeoutMs;
+	}
+
+	public void setReadTimeoutMs(final int readTimeoutMs) {
+		this.readTimeoutMs = readTimeoutMs;
+	}
+
+	public int getSleepTimeMs() {
+		return sleepTimeMs;
+	}
+
+	public void setSleepTimeMs(final int sleepTimeMs) {
+		this.sleepTimeMs = sleepTimeMs;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/UrlExtractor.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/UrlExtractor.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/download/UrlExtractor.java	(revision 49538)
@@ -0,0 +1,208 @@
+package eu.dnetlib.msro.workflows.nodes.download;
+
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import com.google.common.base.Function;
+import com.google.gson.Gson;
+
+import eu.dnetlib.data.download.rmi.DownloadItem;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class UrlExtractor.
+ */
+public class UrlExtractor implements Function<String, String> {
+
+	/** The Constant log. */
+	private static final Log log = LogFactory.getLog(UrlExtractor.class);
+
+	/** The xpath url. */
+	private String xpathURL;
+
+	/** The xpath. */
+	private String xpathMetadataID;
+
+	/** The xpath open access. */
+	private String xpathOpenAccess;
+
+	/** The xpath embargo date. */
+	private String xpathEmbargoDate;
+
+	/**
+	 * Instantiates a new url extractor.
+	 *
+	 * @param xpath
+	 *            the xpath
+	 * @param xpathMetadataID
+	 *            the xpath metadata id
+	 */
+	public UrlExtractor(final String xpath, final String xpathMetadataID, final String xpathOpenAccess, final String xpathEmbargoDate) {
+		this.xpathURL = xpath;
+		this.xpathMetadataID = xpathMetadataID;
+		this.xpathOpenAccess = xpathOpenAccess;
+		this.xpathEmbargoDate = xpathEmbargoDate;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see com.google.common.base.Function#apply(java.lang.Object)
+	 */
+	@Override
+	public String apply(final String input) {
+		try {
+			DownloadItem di = new DownloadItem();
+			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+			DocumentBuilder builder;
+			builder = factory.newDocumentBuilder();
+			if (input == null) {
+				log.error("Metadata input is null");
+				return null;
+			}
+			Document doc = builder.parse(new ByteArrayInputStream(input.getBytes()));
+			XPathFactory xPathFactory = XPathFactory.newInstance();
+			XPath myXpath = xPathFactory.newXPath();
+			XPathExpression expression = myXpath.compile(xpathURL);
+			Object values = expression.evaluate(doc, XPathConstants.NODESET);
+			di.setUrl(getNodes((NodeList) values));
+			di.setOriginalUrl(getNodes((NodeList) values));
+
+			if (xpathOpenAccess != null) {
+				expression = myXpath.compile(xpathOpenAccess);
+				String openAccess = expression.evaluate(doc);
+				di.setOpenAccess(openAccess);
+			}
+			if (xpathEmbargoDate != null) {
+				expression = myXpath.compile(xpathEmbargoDate);
+				String embargoDate = expression.evaluate(doc);
+				if (!StringUtils.isEmpty(embargoDate)) {
+					try {
+						DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
+						DateTime dt = fmt.parseDateTime(embargoDate);
+						di.setEmbargoDate(dt.toDate());
+					} catch (Exception pe) {}
+				}
+			}
+			expression = myXpath.compile(xpathMetadataID);
+			String extracted_metadataId = expression.evaluate(doc);
+			di.setIdItemMetadata(extracted_metadataId);
+			return di.toJSON();
+		} catch (Exception e) {
+			log.error("OPSSS... Something bad happen on evaluating ", e);
+			return null;
+		}
+
+	}
+
+	/**
+	 * Gets the nodes.
+	 *
+	 * @param nodes
+	 *            the nodes
+	 * @return the nodes
+	 */
+	private String getNodes(final NodeList nodes) {
+		List<String> extracted_Url = new ArrayList<String>();
+		if (nodes != null) {
+			for (int i = 0; i < nodes.getLength(); i++) {
+				extracted_Url.add(nodes.item(i).getNodeValue());
+			}
+		}
+		return new Gson().toJson(extracted_Url);
+	}
+
+	/**
+	 * Gets the xpath metadata id.
+	 *
+	 * @return the xpathMetadataID
+	 */
+	public String getXpathMetadataID() {
+		return xpathMetadataID;
+	}
+
+	/**
+	 * Sets the xpath metadata id.
+	 *
+	 * @param xpathMetadataID
+	 *            the xpathMetadataID to set
+	 */
+	public void setXpathMetadataID(final String xpathMetadataID) {
+		this.xpathMetadataID = xpathMetadataID;
+	}
+
+	/**
+	 * Gets the xpath url.
+	 *
+	 * @return the xpath url
+	 */
+	public String getXpathURL() {
+		return xpathURL;
+	}
+
+	/**
+	 * Sets the xpath url.
+	 *
+	 * @param xpathURL
+	 *            the new xpath url
+	 */
+	public void setXpathURL(final String xpathURL) {
+		this.xpathURL = xpathURL;
+	}
+
+	/**
+	 * Gets the xpath open access.
+	 *
+	 * @return the xpath open access
+	 */
+	public String getXpathOpenAccess() {
+		return xpathOpenAccess;
+	}
+
+	/**
+	 * Sets the xpath open access.
+	 *
+	 * @param xpathOpenAccess
+	 *            the new xpath open access
+	 */
+	public void setXpathOpenAccess(final String xpathOpenAccess) {
+		this.xpathOpenAccess = xpathOpenAccess;
+	}
+
+	/**
+	 * Gets the xpath embargo date.
+	 *
+	 * @return the xpath embargo date
+	 */
+	public String getXpathEmbargoDate() {
+		return xpathEmbargoDate;
+	}
+
+	/**
+	 * Sets the xpath embargo date.
+	 *
+	 * @param xpathEmbargoDate
+	 *            the new xpath embargo date
+	 */
+	public void setXpathEmbargoDate(final String xpathEmbargoDate) {
+		this.xpathEmbargoDate = xpathEmbargoDate;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflow.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflow.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflow.java	(revision 49538)
@@ -0,0 +1,56 @@
+package eu.dnetlib.msro.workflows.metawf;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.core.io.Resource;
+
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+
+public class DatasourceMetaWorkflow {
+
+	private WorkflowTree tree;
+
+	private Resource destroyWorkflowTemplate;
+
+	@javax.annotation.Resource
+	private UniqueServiceLocator serviceLocator;
+
+	public int registerAllWorkflows(final Map<String, String> params) throws ISRegistryException, IOException {
+		return tree.registerAllWorkflows(params);
+	}
+
+	public String registerDestroyWorkflow(final Map<String, String> params) throws ISRegistryException, IOException {
+		final String profile = WorkflowProfileCreator.generateProfile("Repo BYE", "REPO_BYE", WorkflowStartModeEnum.auto, params, destroyWorkflowTemplate);
+		return serviceLocator.getService(ISRegistryService.class).registerProfile(profile);
+	}
+
+	public String asXML() {
+		final StringWriter sw = new StringWriter();
+		tree.populateMetaWfXml(sw);
+		return sw.toString();
+	}
+
+	public WorkflowTree getTree() {
+		return tree;
+	}
+
+	@Required
+	public void setTree(final WorkflowTree tree) {
+		this.tree = tree;
+	}
+
+	public Resource getDestroyWorkflowTemplate() {
+		return destroyWorkflowTemplate;
+	}
+
+	@Required
+	public void setDestroyWorkflowTemplate(final Resource destroyWorkflowTemplate) {
+		this.destroyWorkflowTemplate = destroyWorkflowTemplate;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowTree.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowTree.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowTree.java	(revision 49538)
@@ -0,0 +1,101 @@
+package eu.dnetlib.msro.workflows.metawf;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.springframework.beans.factory.annotation.Required;
+
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+
+public class WorkflowTree {
+
+	private String id;
+
+	private String name;
+
+	private WorkflowStartModeEnum start = WorkflowStartModeEnum.auto;
+
+	private List<WorkflowTree> children;
+
+	private org.springframework.core.io.Resource template;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	public void populateMetaWfXml(final StringWriter sw) {
+		sw.append("<WORKFLOW id='" + StringEscapeUtils.escapeXml(id) + "' name='" + StringEscapeUtils.escapeXml(name) + "'");
+
+		if (children == null || children.isEmpty()) {
+			sw.append(" />");
+		} else {
+			sw.append(">");
+			for (WorkflowTree child : children) {
+				child.populateMetaWfXml(sw);
+			}
+			sw.append("</WORKFLOW>");
+		}
+	}
+
+	public int registerAllWorkflows(final Map<String, String> params) throws ISRegistryException, IOException {
+		int count = 0;
+
+		if (this.id == null || this.id.isEmpty()) {
+			final String profile = WorkflowProfileCreator.generateProfile(name, "aggregator", start, params, template);
+			this.id = serviceLocator.getService(ISRegistryService.class).registerProfile(profile);
+			count++;
+		}
+
+		if (children != null) {
+			for (WorkflowTree child : children) {
+				count += child.registerAllWorkflows(params);
+			}
+		}
+		return count;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public List<WorkflowTree> getChildren() {
+		return children;
+	}
+
+	public void setChildren(final List<WorkflowTree> children) {
+		this.children = children;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	@Required
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public org.springframework.core.io.Resource getTemplate() {
+		return template;
+	}
+
+	@Required
+	public void setTemplate(final org.springframework.core.io.Resource template) {
+		this.template = template;
+	}
+
+	public WorkflowStartModeEnum getStart() {
+		return start;
+	}
+
+	public void setStart(final WorkflowStartModeEnum start) {
+		this.start = start;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMDStoreJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMDStoreJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/repobye/DeleteMDStoreJobNode.java	(revision 49538)
@@ -0,0 +1,38 @@
+package eu.dnetlib.msro.workflows.nodes.repobye;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+
+public class DeleteMDStoreJobNode extends BlackboardJobNode {
+
+	private static final Log log = LogFactory.getLog(DeleteMDStoreJobNode.class);
+
+	private String mdstoreId;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(MDStoreService.class, mdstoreId);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) {
+		log.info("preparing blackboard job: delete of mdstore " + getMdstoreId());
+		job.setAction("DELETE");
+		job.getParameters().put("id", getMdstoreId());
+	}
+
+	public String getMdstoreId() {
+		return mdstoreId;
+	}
+
+	public void setMdstoreId(final String mdstoreId) {
+		this.mdstoreId = mdstoreId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/MdBuilderJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/MdBuilderJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/MdBuilderJobNode.java	(revision 49538)
@@ -0,0 +1,169 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.List;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.XSLTMappedResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.core.io.Resource;
+
+public class MdBuilderJobNode extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(MdBuilderJobNode.class);
+
+	private Resource mdBuilderTemplateXslt;
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String datasourceId;
+	private String datasourceInterface;
+
+	private XSLTMappedResultSetFactory xsltMappedResultSetFactory;
+
+	@javax.annotation.Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String execute(final NodeToken token) throws MSROException {
+		final String inputEpr = token.getEnv().getAttribute(inputEprParam);
+
+		if ((inputEpr == null) || inputEpr.isEmpty()) throw new MSROException("InputEprParam (" + inputEprParam + ") not found in ENV");
+		StringTemplate st = null;
+		try {
+			st = new StringTemplate(IOUtils.toString(getMdBuilderTemplateXslt().getInputStream()));
+			st.setAttribute("datasourceId", datasourceId);
+			st.setAttribute("xpath", getMetadataIdentifierPath().replace("\"", "'"));
+			st.setAttribute("baseurl", URLEncoder.encode(getBaseUrl(), "UTF-8"));
+			st.setAttribute("metadatanamespace", getMetadataNamespace());
+
+			/*
+			 * If namespacePrefix has been already pushed to env by some custom JobNode e.g. ObtainOpenaireDataSourceParamsJobNode then push
+			 * it to ST. Else: a) try to get it from EXTRAFIELDS of the datasource b) try to get it from DATASOURCE_ORIGINAL_ID of the
+			 * datasource c) if any of the is present, then push to ST the datasourceId
+			 */
+			if (token.getEnv().hasAttribute("namespacePrefix")) {
+				st.setAttribute("namespacePrefix", token.getEnv().getAttribute("namespacePrefix"));
+			} else {
+				List<String> namespacePrefix;
+				String xQuery = "/*[.//RESOURCE_IDENTIFIER/@value='" + datasourceId + "']//EXTRA_FIELDS/FIELD/value[../key='NamespacePrefix']/string()";
+				namespacePrefix = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xQuery);
+				if (namespacePrefix.size() != 0) {
+					st.setAttribute("namespacePrefix", namespacePrefix.get(0));
+				} else {
+					xQuery = "/*[.//RESOURCE_IDENTIFIER/@value='" + datasourceId + "']//DATASOURCE_ORIGINAL_ID/string()";
+					namespacePrefix = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xQuery);
+					if (namespacePrefix.size() != 0) {
+						st.setAttribute("namespacePrefix", namespacePrefix.get(0));
+					} else {
+						st.setAttribute("namespacePrefix", datasourceId);
+					}
+				}
+			}
+
+			final W3CEndpointReference epr = xsltMappedResultSetFactory.createMappedResultSet(new EPRUtils().getEpr(inputEpr), st.toString());
+
+			token.getEnv().setAttribute(outputEprParam, epr.toString());
+
+			return Arc.DEFAULT_ARC;
+		} catch (ISLookUpException e) {
+			throw new MSROException("Error while initializing mdBuilder template (" + getMdBuilderTemplateXslt().getFilename() + ") for datasource "
+					+ datasourceId, e);
+		} catch (IOException e) {
+			throw new MSROException("Error parsing template: " + getMdBuilderTemplateXslt().getFilename(), e);
+		} catch (Exception e) {
+			log.error(st.toString());
+			throw new MSROException(e);
+		}
+	}
+
+	private String getBaseUrl() throws ISLookUpException {
+		String xQuery = "/*[.//RESOURCE_IDENTIFIER/@value='{datasourceId}']//INTERFACE[@id='{interfaceId}']//BASE_URL/string()";
+		xQuery = xQuery.replace("{interfaceId}", datasourceInterface).replace("{datasourceId}", datasourceId);
+		return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xQuery);
+	}
+
+	private String getMetadataIdentifierPath() throws ISLookUpException {
+		String xQuery = "for $x in collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType') "
+				+ "return $x//INTERFACE[@id='{interfaceId}']/INTERFACE_EXTRA_FIELD[@name='metadata_identifier_path']/string()";
+		xQuery = xQuery.replace("{interfaceId}", datasourceInterface);
+		return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xQuery);
+	}
+
+	private String getMetadataNamespace() {
+		try {
+			String xQuery = "let $x := /*[.//RESOURCE_IDENTIFIER/@value='{datasourceId}']//INTERFACE[@id='{interfaceId}']/ACCESS_PROTOCOL/@format/string() "
+					+ "return /*[.//RESOURCE_TYPE/@value='MetadataFormatDSResourceType']//METADATAFORMAT[@Prefix=$x]/@NameSpace/string()";
+			xQuery = xQuery.replace("{interfaceId}", datasourceInterface).replace("{datasourceId}", datasourceId);
+			return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xQuery);
+		} catch (ISLookUpException e) {
+			log.error("The interface is not OAI or the format is not found in the MetadataFormatDSResourceType, thus metadata format in the <about> section "
+					+ "cannot managed here and it will be leaved empty (for the time being)");
+			return "";
+		}
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public XSLTMappedResultSetFactory getXsltMappedResultSetFactory() {
+		return xsltMappedResultSetFactory;
+	}
+
+	@Required
+	public void setXsltMappedResultSetFactory(final XSLTMappedResultSetFactory xsltMappedResultSetFactory) {
+		this.xsltMappedResultSetFactory = xsltMappedResultSetFactory;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+	public Resource getMdBuilderTemplateXslt() {
+		return mdBuilderTemplateXslt;
+	}
+
+	@Required
+	public void setMdBuilderTemplateXslt(final Resource mdBuilderTemplateXslt) {
+		this.mdBuilderTemplateXslt = mdBuilderTemplateXslt;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/GroovyJobNode.java	(revision 49538)
@@ -0,0 +1,140 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.google.common.collect.Maps;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.MappedResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+import groovy.lang.GroovyShell;
+import groovy.util.GroovyScriptEngine;
+
+public class GroovyJobNode extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(GroovyJobNode.class);
+
+	/**
+	 * used to transform the records using Groovy.
+	 */
+
+	private MappedResultSetFactory mappedResultSetFactory;
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String transformationRuleId;
+	// private String groovyParams;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private Map<String, String> retrieveGroovyParameter() {
+		Map<String, String> out = Maps.newHashMap();
+
+		String query = "for $x in collection('/db/DRIVER/GroovyProcessingDSResource/GroovyProcessingDSResourceType')"
+				+ "where $x[.//RESOURCE_IDENTIFIER/@value='" + transformationRuleId + "']"
+				+ "return concat($x//GROOVY_CLASSPATH/text(),':::',$x//GROOVY_DNETCLASS/text())";
+		try {
+			String result = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query).get(0);
+			if (result == null) { return null; }
+			String[] data = result.trim().split(":::");
+			if (data.length == 2) {
+				out.put("classpath", data[0]);
+				out.put("mainClass", data[1]);
+			}
+
+			return out;
+		} catch (Exception e) {
+			log.error(e);
+			return null;
+		}
+	}
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String inputEprString = token.getEnv().getAttribute(inputEprParam);
+		if (inputEprString == null || inputEprString.isEmpty()) { throw new MSROException("InputEprParam (" + inputEprParam + ") not found in ENV"); }
+		final W3CEndpointReference inputEpr = new EPRUtils().getEpr(inputEprString);
+		String groovyClasspath, groovyDnetClass;
+		Map<String, String> prop = retrieveGroovyParameter();
+		groovyClasspath = prop.get("classpath");
+		groovyDnetClass = prop.get("mainClass");
+		W3CEndpointReference epr = transformGroovy(inputEpr, groovyClasspath, groovyDnetClass, parseJsonParameters(token));
+		token.getEnv().setAttribute(outputEprParam, epr.toString());
+		return Arc.DEFAULT_ARC;
+	}
+
+	private W3CEndpointReference transformGroovy(final W3CEndpointReference source,
+			final String groovyClasspath,
+			final String groovyDnetClass,
+			final Map<String, String> params) throws ClassNotFoundException, IOException {
+
+		GroovyScriptEngine gse = new GroovyScriptEngine(groovyClasspath);
+		gse.getGroovyClassLoader().loadClass(groovyDnetClass);
+		log.info("***********************************************");
+		log.info("Loaded Groovy classes:");
+		for (Class<?> c : gse.getGroovyClassLoader().getLoadedClasses()) {
+			log.info(c.getCanonicalName());
+		}
+		log.info("***********************************************");
+		GroovyShell groovyShell = new GroovyShell(gse.getGroovyClassLoader());
+
+		Object go = groovyShell.evaluate("new " + groovyDnetClass + "()");
+		if (go instanceof GroovyUnaryFunction) {
+			GroovyUnaryFunction groovyUnaryFunction = (GroovyUnaryFunction) go;
+			if (params != null) {
+				groovyUnaryFunction.setParams(params);
+			}
+			return mappedResultSetFactory.createMappedResultSet(source, groovyUnaryFunction);
+		} else {
+			throw new RuntimeException("Groovy object " + go + " is not supported");
+		}
+	}
+
+	public MappedResultSetFactory getMappedResultSetFactory() {
+		return mappedResultSetFactory;
+	}
+
+	@Required
+	public void setMappedResultSetFactory(final MappedResultSetFactory mappedResultSetFactory) {
+		this.mappedResultSetFactory = mappedResultSetFactory;
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getTransformationRuleId() {
+		return transformationRuleId;
+	}
+
+	public void setTransformationRuleId(final String transformationRuleId) {
+		this.transformationRuleId = transformationRuleId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/ApplyXsltJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/ApplyXsltJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/transform/ApplyXsltJobNode.java	(revision 49538)
@@ -0,0 +1,84 @@
+package eu.dnetlib.msro.workflows.nodes.transform;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.core.io.ClassPathResource;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.resultset.XSLTMappedResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class ApplyXsltJobNode extends SimpleJobNode {
+
+	private String inputEprParam;
+	private String outputEprParam;
+	private String xsltClasspath;
+
+	private XSLTMappedResultSetFactory xsltMappedResultSetFactory;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String inputEpr = token.getEnv().getAttribute(inputEprParam);
+		if ((inputEpr == null) || inputEpr.isEmpty()) throw new MSROException("InputEprParam (" + inputEprParam + ") not found in ENV");
+
+		final Map<String, String> xsltParams = new HashMap<String, String>();
+
+		for (String name : token.getFullEnv().getAttributeNames()) {
+			xsltParams.put(name.replaceAll(":", "_"), token.getFullEnv().getAttribute(name));
+		}
+		for (String name : token.getEnv().getAttributeNames()) {
+			xsltParams.put(name.replaceAll(":", "_"), token.getEnv().getAttribute(name));
+		}
+
+		xsltParams.putAll(parseJsonParameters(token));
+
+		final W3CEndpointReference epr = xsltMappedResultSetFactory.createMappedResultSet(new EPRUtils().getEpr(inputEpr),
+				(new ClassPathResource(xsltClasspath)), xsltParams);
+
+		token.getEnv().setAttribute(outputEprParam, epr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getInputEprParam() {
+		return inputEprParam;
+	}
+
+	public void setInputEprParam(final String inputEprParam) {
+		this.inputEprParam = inputEprParam;
+	}
+
+	public String getOutputEprParam() {
+		return outputEprParam;
+	}
+
+	public void setOutputEprParam(final String outputEprParam) {
+		this.outputEprParam = outputEprParam;
+	}
+
+	public String getXsltClasspath() {
+		return xsltClasspath;
+	}
+
+	public void setXsltClasspath(final String xsltClasspath) {
+		this.xsltClasspath = xsltClasspath;
+	}
+
+	public XSLTMappedResultSetFactory getXsltMappedResultSetFactory() {
+		return xsltMappedResultSetFactory;
+	}
+
+	@Required
+	public void setXsltMappedResultSetFactory(final XSLTMappedResultSetFactory xsltMappedResultSetFactory) {
+		this.xsltMappedResultSetFactory = xsltMappedResultSetFactory;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/UpdateDbJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/UpdateDbJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/db/UpdateDbJobNode.java	(revision 49538)
@@ -0,0 +1,87 @@
+package eu.dnetlib.msro.workflows.nodes.db;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.database.rmi.DatabaseService;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+
+public class UpdateDbJobNode extends BlackboardJobNode implements ProgressJobNode {
+
+	private String db;
+	private String dbParam;
+	private String eprParam;
+	private ProcessCountingResultSetFactory processCountingResultSetFactory;
+	private ResultsetProgressProvider progressProvider;
+
+	private static final Log log = LogFactory.getLog(UpdateDbJobNode.class);
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(DatabaseService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception {
+		if (db == null || db.isEmpty()) {
+			db = token.getEnv().getAttribute(getDbParam());
+		}
+
+		log.info("preparing blackboard job to update DB: " + db);
+
+		final String epr = token.getEnv().getAttribute(getEprParam());
+
+		this.progressProvider = processCountingResultSetFactory.createProgressProvider(token.getProcess(), epr);
+
+		job.setAction("IMPORT");
+		job.getParameters().put("db", db);
+		job.getParameters().put("epr", this.progressProvider.getEpr().toString());
+	}
+
+	@Override
+	public ProgressProvider getProgressProvider() {
+		return progressProvider;
+	}
+
+	public String getDb() {
+		return db;
+	}
+
+	public void setDb(final String db) {
+		this.db = db;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+	public ProcessCountingResultSetFactory getProcessCountingResultSetFactory() {
+		return processCountingResultSetFactory;
+	}
+
+	@Required
+	public void setProcessCountingResultSetFactory(final ProcessCountingResultSetFactory processCountingResultSetFactory) {
+		this.processCountingResultSetFactory = processCountingResultSetFactory;
+	}
+
+	public String getDbParam() {
+		return dbParam;
+	}
+
+	public void setDbParam(final String dbParam) {
+		this.dbParam = dbParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncher.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncher.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncher.java	(revision 49538)
@@ -0,0 +1,199 @@
+package eu.dnetlib.msro.cron;
+
+import java.util.Date;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.quartz.CronExpression;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.GraphProcess;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor;
+import eu.dnetlib.msro.workflows.sarasvati.registry.GraphProcessRegistry;
+
+public class ScheduledWorkflowLauncher {
+
+	private static final Log log = LogFactory.getLog(ScheduledWorkflowLauncher.class);
+
+	private static final DateUtils dateUtils = new DateUtils();
+
+	private WorkflowExecutor workflowExecutor;
+
+	private GraphProcessRegistry graphProcessRegistry;
+
+	private int windowSize = 1800000; // 30 minutes
+
+	private final static int millisInMinute = 60000;
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	public void verifySheduledWorkflows() {
+		log.debug("Verifying scheduled workflows - START");
+
+		final String query = "for $x in collection('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType') " +
+				"where $x//CONFIGURATION/@status='EXECUTABLE' " +
+				"and $x//SCHEDULING/@enabled='true' " +
+				"return concat($x//RESOURCE_IDENTIFIER/@value, ' @@@ ', $x//SCHEDULING/CRON, ' @@@ ', $x//SCHEDULING/MININTERVAL)";
+
+		try {
+			final int defaultMinInterval = windowSize / millisInMinute;
+			for (final String s : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query)) {
+				final String[] arr = s.split("@@@");
+				final String id = arr[0].trim();
+				final String cron = arr[1].trim();
+				final int minInterval = Math.max(NumberUtils.toInt(arr[2].trim(), 0), defaultMinInterval);
+				final Date lastExecutionDate = calculateLastExecutionDate(id);
+
+				if (isReady(id, cron, minInterval, lastExecutionDate, new Date()) && !isAlreadyRunning(id)) {
+					try {
+						workflowExecutor.startMetaWorkflow(id, false);
+					} catch (final Exception e) {
+						log.debug("Error launching scheduled wf: " + id, e);
+					}
+				}
+			}
+		} catch (final ISLookUpException e) {
+			log.error("Error executing query " + query);
+		}
+
+		log.debug("Verifying scheduled workflows - END");
+	}
+
+	protected boolean isReady(final String id, final String cron, final int minInterval, final Date lastExecutionDate, final Date now) {
+		if (CronExpression.isValidExpression(cron)) {
+			final int minIntervalMillis = minInterval * 60000; // minutes to millis;
+
+			final boolean res;
+			if (lastExecutionDate != null) {
+				final int elapsed = Math.round(now.getTime() - lastExecutionDate.getTime());
+				res = (elapsed > minIntervalMillis) && verifyCron(cron, now);
+			} else {
+				res = verifyCron(cron, now);
+			}
+
+			if (log.isDebugEnabled()) {
+				log.debug("**************************************************************");
+				log.debug("META WORKFLOW ID       : " + id);
+				log.debug("NOW                    : " + now);
+				log.debug("LAST EXECUTION DATE    : " + lastExecutionDate);
+				log.debug("MIN INTERVAL (minutes) : " + minInterval);
+				log.debug("REAL MIN INTERVAL (ms) : " + minIntervalMillis);
+				log.debug("WINDOW SIZE (ms)       : " + windowSize);
+				log.debug("MUST BE EXECUTED       : " + res);
+				log.debug("**************************************************************");
+			}
+
+			return res;
+		}
+
+		return false;
+	}
+
+	private boolean verifyCron(final String cronExpression, final Date now) {
+		try {
+			final CronExpression cron = new CronExpression(cronExpression);
+
+			final Date date = new Date(now.getTime() - windowSize);
+
+			final Date cronDate = cron.getNextValidTimeAfter(date);
+
+			if (log.isDebugEnabled()) {
+				log.debug("NEXT EXECUTION DATE: " + cronDate);
+				log.debug("FIRED              : " + (cronDate.getTime() < now.getTime()));
+			}
+			return cronDate.getTime() < now.getTime();
+		} catch (final Exception e) {
+			log.error("Error calculating next cron event: " + cronExpression, e);
+			return false;
+		}
+	}
+
+	private boolean isAlreadyRunning(final String metaWfId) {
+		final String query = "doc('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType/" + StringUtils.substringBefore(metaWfId, "_")
+				+ "')//WORKFLOW/@id/string()";
+
+		try {
+			for (final String profileId : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query)) {
+				if (profileId.length() > 0) {
+					for (final GraphProcess p : graphProcessRegistry.findProcessesByResource(profileId)) {
+						switch (p.getState()) {
+						case Created:
+							return true;
+						case Executing:
+							return true;
+						default:
+							break;
+						}
+					}
+				}
+			}
+		} catch (final ISLookUpException e) {
+			log.error("Error executing query " + query);
+		}
+		return false;
+	}
+
+	private Date calculateLastExecutionDate(final String id) {
+		final String query = "for $id in doc('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType/" + StringUtils.substringBefore(id, "_")
+				+ "')//WORKFLOW/@id/string() " +
+				"for $x in doc(concat('/db/DRIVER/WorkflowDSResources/WorkflowDSResourceType/', substring-before($id, '_'))) " +
+				"where $x//LAST_EXECUTION_STATUS = 'SUCCESS' " +
+				"return $x//LAST_EXECUTION_DATE/text() ";
+
+		long time = 0;
+		try {
+			for (final String s : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query)) {
+				if (s.length() > 0) {
+					final Date d = dateUtils.parse(s);
+					if (time < d.getTime()) {
+						time = d.getTime();
+					}
+				}
+			}
+		} catch (final ISLookUpException e) {
+			log.error("Error executing query " + query);
+		} catch (final Exception e) {
+			log.error("Error calculating date", e);
+		}
+
+		return time > 0 ? new Date(time) : null;
+	}
+
+	public WorkflowExecutor getWorkflowExecutor() {
+		return workflowExecutor;
+	}
+
+	@Required
+	public void setWorkflowExecutor(final WorkflowExecutor workflowExecutor) {
+		this.workflowExecutor = workflowExecutor;
+	}
+
+	public GraphProcessRegistry getGraphProcessRegistry() {
+		return graphProcessRegistry;
+	}
+
+	@Required
+	public void setGraphProcessRegistry(final GraphProcessRegistry graphProcessRegistry) {
+		this.graphProcessRegistry = graphProcessRegistry;
+	}
+
+	public int getWindowSize() {
+		return windowSize;
+	}
+
+	@Required
+	public void setWindowSize(final int windowSize) {
+		this.windowSize = windowSize;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SuccessFailureNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SuccessFailureNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SuccessFailureNode.java	(revision 49538)
@@ -0,0 +1,119 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import java.util.Map;
+import javax.annotation.Resource;
+
+import com.google.common.collect.Maps;
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+import eu.dnetlib.common.logging.DnetLogger;
+import eu.dnetlib.common.logging.LogMessage;
+import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+/**
+ * The success node sets the "isCompletedSuccessfully" env var.
+ * 
+ */
+public class SuccessFailureNode extends SimpleJobNode {
+
+	private static final Log log = LogFactory.getLog(SuccessFailureNode.class);
+	/**
+	 * is completed successfully.
+	 */
+	private boolean success;
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+	@Resource(name = "msroWorkflowLogger")
+	private DnetLogger dnetLogger;
+
+	@Override
+	protected String execute(final NodeToken token) {
+		final String profileId = token.getFullEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID).trim();
+
+		final long now = DateUtils.now();
+		final String date = DateUtils.calculate_ISO8601(now);
+
+		token.getProcess().getEnv().setAttribute(WorkflowsConstants.SYSTEM_END_DATE, now);
+		token.getProcess().getEnv().setAttribute(WorkflowsConstants.SYSTEM_END_HUMAN_DATE, date);
+
+		final Map<String, String> params = mergeEnvAttributes(token);
+		final LogMessage logMessage = dnetLogger.newLogMessage().addDetails(params);
+
+		try {
+			final String template = IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/msro/workflows/templates/workflow_status.xml.st"));
+			final StringTemplate st = new StringTemplate(template);
+			st.setAttribute("procId", StringEscapeUtils.escapeXml(params.get(WorkflowsConstants.SYSTEM_WF_PROCESS_ID)));
+			st.setAttribute("date", StringEscapeUtils.escapeXml(date));
+			st.setAttribute("params", filterOutputParams(params));
+			if (!isSuccess()) {
+				st.setAttribute("error", StringEscapeUtils.escapeXml(params.get(WorkflowsConstants.SYSTEM_ERROR)));
+			}
+
+			serviceLocator.getService(ISRegistryService.class).updateProfileNode(profileId, "//STATUS", st.toString());
+
+			token.getProcess().getEnv().setAttribute(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY, isSuccess());
+
+			logMessage.addDetail(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY, Boolean.toString(isSuccess()));
+		} catch (Exception e) {
+			log.error("Error updating workflow profile: " + profileId, e);
+			token.getProcess().getEnv().setAttribute(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY, false);
+			logMessage.addDetail(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY, Boolean.toString(false));
+		}
+
+		logMessage.flush();
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	private Map<String, String> filterOutputParams(final Map<String, String> map) {
+		final Map<String, String> res = Maps.newHashMap();
+
+		if (map != null) {
+			for (String k : map.keySet()) {
+				if (!StringUtils.isBlank(k) && (k.startsWith(WorkflowsConstants.DATAPROVIDER_PREFIX) || k.startsWith(WorkflowsConstants.MAIN_LOG_PREFIX))) {
+					final String key = StringEscapeUtils.escapeXml(k);
+					final String v = map.get(k);
+					res.put(key, v != null ? escapeAttribute(StringEscapeUtils.escapeXml(v)) : "null");
+				}
+			}
+		}
+
+		return res;
+	}
+
+	private String escapeAttribute(String s) {
+		return s.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;").replaceAll("\\{", "{{").replaceAll("\\}", "}}");
+	}
+
+	private Map<String, String> mergeEnvAttributes(final NodeToken token) {
+		final Map<String, String> map = Maps.newHashMap();
+
+		for (String s : token.getEnv().getAttributeNames()) {
+			map.put(s, token.getEnv().getAttribute(s));
+		}
+		for (String s : token.getFullEnv().getAttributeNames()) {
+			map.put(s, token.getFullEnv().getAttribute(s));
+		}
+		return map;
+	}
+
+	public boolean isSuccess() {
+		return success;
+	}
+
+	@Required
+	public void setSuccess(final boolean success) {
+		this.success = success;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.xml	(revision 49538)
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:sec="http://cxf.apache.org/configuration/security"
+       xmlns:wsa="http://cxf.apache.org/ws/addressing" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns:t="http://dnetlib.eu/springbeans/t"
+       xmlns:template="http://dnetlib.eu/springbeans/template" xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                                    http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
+                                    http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
+                                    http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
+                            http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
+                            http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd">
+	<!-- beans -->
+	<bean id="msroService" class="eu.dnetlib.msro.MSROServiceImpl"
+		init-method="start" destroy-method="stop" 
+		p:notificationHandler-ref="msroNotificationHandlerChain"
+		p:processRegistry-ref="graphProcessRegistry" />
+
+	<bean id="msroNotificationHandlerChain"
+		class="eu.dnetlib.enabling.tools.blackboard.NotificationHandlerChainImpl">
+		<property name="handlerExecutor">
+			<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"
+				p:corePoolSize="32" p:keepAliveSeconds="3600" p:queueCapacity="0" />
+		</property>
+		<property name="handlers">
+			<list>
+				<ref bean="msroBlackboardNotificationHandler" />
+			</list>
+		</property>
+	</bean>
+
+	<bean id="wfDependencyLauncherNotificationHandler" class="eu.dnetlib.msro.notification.WfDependencyLauncherNotificationHandler"
+		p:enabled="true" p:topicExpression="UPDATE/WorkflowDSResourceType/*/RESOURCE_PROFILE/BODY/STATUS/LAST_EXECUTION_DATE" />
+
+	<alias name="cxfEndpointReferenceBuilder" alias="eprBuilder" />
+	
+	<bean id="msroWfEngine" class="eu.dnetlib.msro.workflows.sarasvati.loader.InjectableMemEngine">
+		<property name="graphFactory">
+			<bean class="eu.dnetlib.msro.workflows.sarasvati.loader.InjectableMemGraphFactory">
+				<property name="nodeFactory">
+					<bean class="eu.dnetlib.msro.workflows.sarasvati.loader.InjectableNodeFactory"
+						p:beanNamePrefix="wfNode" />				
+				</property>
+			</bean>
+		</property>
+	</bean>
+	
+	<bean id="graphProcessRegistry" class="eu.dnetlib.msro.workflows.sarasvati.registry.GraphProcessRegistry" 
+		p:maxSize="${msro.wf.registry.maxSize}" />
+
+	<bean id="sarasvatiGraphLoader" 
+		class="eu.dnetlib.msro.workflows.sarasvati.loader.GraphLoader" 
+		p:engine-ref="msroWfEngine" /> 
+		
+	<bean id="sarasvatiWorkflowExecutor" class="eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor"
+	      p:engine-ref="msroWfEngine"
+	      p:graphLoader-ref="sarasvatiGraphLoader"
+	      p:graphProcessRegistry-ref="graphProcessRegistry"
+	      p:profileToSarasvatiConverter-ref="msroProfileToSarasvatiConverter"
+	      p:maxRunningWorkflows="${msro.wf.max.running}"
+	      init-method="init"/>
+	
+	<bean id="workflowsConstants" class="eu.dnetlib.msro.workflows.util.WorkflowsConstants"
+		init-method="init" 
+		p:dataproviderProtocolsJson="${msro.wf.ui.dataprovider.protocols}" 
+		p:dataproviderTypologiesJson="${msro.wf.ui.dataprovider.typologies}" />
+		
+	<bean id="msroProfileToSarasvatiConverter" class="eu.dnetlib.msro.workflows.sarasvati.loader.ProfileToSarasvatiConverter"
+	 	p:xslt="classpath:/eu/dnetlib/msro/workflows/xslt/wf_profile2sarasvati.xslt" />
+	
+	<bean id="msroBlackboardNotificationHandler"
+		class="eu.dnetlib.enabling.tools.blackboard.DeletingBlackboardNotificationHandler"
+		p:blackboardHandler-ref="blackboardClientHandler" />
+	
+	<bean id="datasourceMetaWorkflowFactory" class="eu.dnetlib.msro.workflows.metawf.DatasourceMetaWorkflowFactory"/>
+	
+	<bean id="msroProcessCountingResultSetFactory" 
+		class="eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory"
+		p:resultSetFactory-ref="openResultSetFactory" p:serviceResolver-ref="serviceResolver" />
+	
+	<bean t:id="msroJobSchedulerAccessor"
+		class="org.springframework.scheduling.quartz.SchedulerAccessorBean"
+		p:scheduler-ref="jobScheduler">
+		<property name="triggers">
+			<list>
+				<bean class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+					p:startDelay="6000" p:repeatCount="0">
+					<property name="jobDetail">
+						<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+							p:targetObject-ref="msroBlackboardSubscriber" p:targetMethod="subscribeAll" />
+					</property>
+				</bean>
+				<bean class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+					p:startDelay="${msro.wf.scheduler.startDelay}" p:repeatInterval="${msro.wf.scheduler.repeatInterval}">
+					<property name="jobDetail">
+						<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+							p:targetObject-ref="msroScheduledWorkflowLauncher" p:targetMethod="verifySheduledWorkflows" />
+					</property>
+				</bean>
+				<bean class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
+					p:startDelay="${msro.wf.mail.thread.startDelay}" p:repeatInterval="${msro.wf.mail.thread.repeatInterval}">
+					<property name="jobDetail">
+						<bean class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
+							p:targetObject-ref="msroMailDispatcher" p:targetMethod="processMailQueue" />
+					</property>
+				</bean>
+			</list>
+		</property>
+	</bean>		
+	
+	<bean id="msroBlackboardSubscriber" class="eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardSubscriber"
+		p:endpoint-ref="msroServiceEndpoint" />
+	
+	<bean id="msroScheduledWorkflowLauncher" class="eu.dnetlib.msro.cron.ScheduledWorkflowLauncher"
+		p:graphProcessRegistry-ref="graphProcessRegistry" p:workflowExecutor-ref="sarasvatiWorkflowExecutor"
+		p:windowSize="${msro.wf.scheduler.window.size}" />
+	
+	
+	<bean id="msroWorkflowLogger" class="eu.dnetlib.common.logging.DnetLogger"
+		p:name="${msro.wf.logger.name}" p:indexConf="${msro.wf.logger.index.conf}" />
+	
+	<bean id="msroMailDispatcher" class="eu.dnetlib.msro.notification.EmailDispatcher"
+		p:from="${msro.wf.mail.from}" p:fromName="${msro.wf.mail.fromName}" p:cc="${msro.wf.mail.cc}"
+		p:smtpHost="${msro.wf.mail.smtp.host}" p:smtpPort="${msro.wf.mail.smtp.port}" p:smtpUser="${msro.wf.mail.smtp.user}" p:smtpPassword="${msro.wf.mail.smtp.password}" 
+		p:baseUrl="${msro.wf.mail.message.baseUrl}" p:infrastructure="${msro.wf.mail.message.infrastructure}"/>
+	
+	<!-- System nodes -->
+	<bean id="wfNodeSuccess" class="eu.dnetlib.msro.workflows.nodes.SuccessFailureNode" p:success="true" scope="prototype" />
+	<bean id="wfNodeFailure" class="eu.dnetlib.msro.workflows.nodes.SuccessFailureNode" p:success="false" scope="prototype" />
+		
+	<!-- REPO_HI and REPO_BYE -->
+	<bean id="wfNodeRegisterMetaWf"	class="eu.dnetlib.msro.workflows.nodes.repohi.RegisterMetaWfJobNode" scope="prototype" />
+	<bean id="wfNodeUpdateMetaWf" class="eu.dnetlib.msro.workflows.nodes.repohi.UpdateMetaWfJobNode" scope="prototype" />
+	<bean id="wfNodeUpdateMetaWfStatus"	class="eu.dnetlib.msro.workflows.nodes.repohi.UpdateMetaWfStatusJobNode" scope="prototype" />
+	<bean id="wfNodeDeleteMetaWf" class="eu.dnetlib.msro.workflows.nodes.repobye.DeleteMetaWfJobNode" scope="prototype" />
+	<bean id="wfNodeDeleteMDStore" class="eu.dnetlib.msro.workflows.nodes.repobye.DeleteMDStoreJobNode" scope="prototype" />
+	
+	<!-- endpoints -->
+	<jaxws:endpoint id="msroServiceEndpoint" implementor="#msroService"
+		implementorClass="eu.dnetlib.msro.rmi.MSROService"
+		address="/msro" />
+
+	<template:instance name="serviceRegistrationManager"
+		t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
+		t:name="msroServiceRegistrationManager" t:service="msroService"
+		t:endpoint="msroServiceEndpoint" t:jobScheduler="jobScheduler" />
+
+</beans>
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/UpdateIndexJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/UpdateIndexJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/index/UpdateIndexJobNode.java	(revision 49538)
@@ -0,0 +1,235 @@
+package eu.dnetlib.msro.workflows.nodes.index;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.annotation.Resource;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.provision.index.rmi.IndexService;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.resultset.XSLTMappedResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.msro.workflows.nodes.BlackboardJobNode;
+import eu.dnetlib.msro.workflows.nodes.ProgressJobNode;
+import eu.dnetlib.msro.workflows.resultset.ProcessCountingResultSetFactory;
+import eu.dnetlib.msro.workflows.util.ProgressProvider;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+
+public class UpdateIndexJobNode extends BlackboardJobNode implements ProgressJobNode {
+
+	private static final Log log = LogFactory.getLog(UpdateIndexJobNode.class);
+
+	private String eprParam;
+	private String indexId;
+	private String format;
+	private String layout;
+	private String feedingType;
+	private String defaultIndexId;
+
+	/**
+	 * xslt mapped resultset factory.
+	 */
+	private XSLTMappedResultSetFactory xsltRSFactory;
+
+	private ProcessCountingResultSetFactory processCountingResultSetFactory;
+	private ResultsetProgressProvider progressProvider;
+
+	/**
+	 * Stylesheet which transforms a layout to another stylesheet which converts a input record to a index record.
+	 */
+	private org.springframework.core.io.Resource layoutToRecordStylesheet;
+
+	/**
+	 * service locator.
+	 */
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Override
+	protected String obtainServiceId(final NodeToken token) {
+		return getServiceLocator().getServiceId(IndexService.class);
+	}
+
+	@Override
+	protected void prepareJob(final BlackboardJob job, final NodeToken token) throws ResultSetException, ISLookUpException, IOException, TransformerException {
+		log.info("preparing blackboard job update index: " + getIndexId());
+
+		final W3CEndpointReference epr = new EPRUtils().getEpr(token.getEnv().getAttribute(getEprParam()));
+
+		final W3CEndpointReference mappedEpr = prepareForIndexing(epr, getFormat(), getLayout());
+
+		progressProvider = processCountingResultSetFactory.createProgressProvider(token.getProcess(), mappedEpr);
+
+		job.setAction("FEED");
+		job.getParameters().put("resultset_epr", encode(progressProvider.getEpr().toString()));
+		job.getParameters().put("id", getIndexId());
+		job.getParameters().put("feeding_type", getFeedingType());
+		job.getParameters().put("backend_Id", defaultIndexId);
+	}
+
+	// helpers
+
+	/**
+	 * Transforms each mdstore record into a index record.
+	 * 
+	 * @param mdStoreRsetEpr
+	 *            mdstore resulsetset
+	 * @param layout
+	 *            layout
+	 * @param format
+	 *            format
+	 * @return resultset with transformed records
+	 * @throws ISLookUpException
+	 *             could happen
+	 * @throws IOException
+	 *             could happen
+	 * @throws TransformerException
+	 *             could happen
+	 */
+	protected W3CEndpointReference prepareForIndexing(final W3CEndpointReference mdStoreRsetEpr, final String format, final String layout)
+			throws ISLookUpException, IOException, TransformerException {
+
+		final TransformerFactory factory = TransformerFactory.newInstance();
+		final Transformer layoutTransformer = factory.newTransformer(new StreamSource(getLayoutToRecordStylesheet().getInputStream()));
+
+		final DOMResult layoutToXsltXslt = new DOMResult();
+		layoutTransformer.setParameter("format", format);
+		layoutTransformer.transform(new StreamSource(new StringReader(getLayoutSource(format, layout))), layoutToXsltXslt);
+
+		dumpXslt(factory, layoutToXsltXslt);
+
+		return getXsltRSFactory().createMappedResultSet(mdStoreRsetEpr, new DOMSource(layoutToXsltXslt.getNode()),
+				"dynamic layout xslt for " + format + ", " + layout);
+	}
+
+	private String getLayoutSource(final String format, final String layout) throws ISLookUpDocumentNotFoundException, ISLookUpException {
+		return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(
+				"collection('')//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'MDFormatDSResourceType' and .//NAME='" + format + "']//LAYOUT[@name='" + layout
+						+ "']");
+	}
+
+	private void dumpXslt(final TransformerFactory factory, final DOMResult layoutToXsltXslt) throws TransformerConfigurationException, TransformerException {
+		if (log.isDebugEnabled()) {
+			final StringWriter buffer = new StringWriter();
+			factory.newTransformer().transform(new DOMSource(layoutToXsltXslt.getNode()), new StreamResult(buffer));
+			log.debug(buffer.toString());
+		}
+	}
+
+	private String encode(final String epr) {
+		return new String(Base64.encodeBase64(epr.getBytes()));
+	}
+
+	// setters and getters
+
+	public String getIndexId() {
+		return indexId;
+	}
+
+	public void setIndexId(final String indexId) {
+		this.indexId = indexId;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+	public String getFeedingType() {
+		return feedingType;
+	}
+
+	public void setFeedingType(final String feedingType) {
+		this.feedingType = feedingType;
+	}
+
+	public ProcessCountingResultSetFactory getProcessCountingResultSetFactory() {
+		return processCountingResultSetFactory;
+	}
+
+	@Required
+	public void setProcessCountingResultSetFactory(final ProcessCountingResultSetFactory processCountingResultSetFactory) {
+		this.processCountingResultSetFactory = processCountingResultSetFactory;
+	}
+
+	@Override
+	public ProgressProvider getProgressProvider() {
+		return progressProvider;
+	}
+
+	public org.springframework.core.io.Resource getLayoutToRecordStylesheet() {
+		return layoutToRecordStylesheet;
+	}
+
+	@Required
+	public void setLayoutToRecordStylesheet(final org.springframework.core.io.Resource layoutToRecordStylesheet) {
+		this.layoutToRecordStylesheet = layoutToRecordStylesheet;
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public void setFormat(final String format) {
+		this.format = format;
+	}
+
+	public String getLayout() {
+		return layout;
+	}
+
+	public void setLayout(final String layout) {
+		this.layout = layout;
+	}
+
+	public XSLTMappedResultSetFactory getXsltRSFactory() {
+		return xsltRSFactory;
+	}
+
+	@Required
+	public void setXsltRSFactory(final XSLTMappedResultSetFactory xsltRSFactory) {
+		this.xsltRSFactory = xsltRSFactory;
+	}
+
+	/**
+	 * @return the defaultIndexId
+	 */
+	public String getDefaultIndexId() {
+		return defaultIndexId;
+	}
+
+	/**
+	 * @param defaultIndexId
+	 *            the defaultIndexId to set
+	 */
+	@Required
+	public void setDefaultIndexId(final String defaultIndexId) {
+		this.defaultIndexId = defaultIndexId;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/meta-workflow.xml.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/meta-workflow.xml.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/meta-workflow.xml.st	(revision 49538)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RESOURCE_PROFILE>
+	<HEADER>
+		<RESOURCE_IDENTIFIER value="" />
+		<RESOURCE_TYPE value="MetaWorkflowDSResourceType" />
+		<RESOURCE_KIND value="MetaWorkflowDSResources" />
+		<RESOURCE_URI value="" />
+		<DATE_OF_CREATION value="2006-05-04T18:13:51.0Z" />
+	</HEADER>
+	<BODY>
+		<DATAPROVIDER id="$dsId$" interface="$ifaceId$">$dsName$</DATAPROVIDER>
+		<METAWORKFLOW_NAME family="$wfFamily$">$wfName$</METAWORKFLOW_NAME>
+		<METAWORKFLOW_DESCRIPTION></METAWORKFLOW_DESCRIPTION>
+		<METAWORKFLOW_SECTION>$section$</METAWORKFLOW_SECTION>
+		<ADMIN_EMAIL>$adminEmail$</ADMIN_EMAIL>
+		<CONFIGURATION status="$status$" />
+		<SCHEDULING enabled="false">
+			<CRON>0 0 0 ? * *</CRON>
+			<MININTERVAL>10080</MININTERVAL>
+		</SCHEDULING>
+	</BODY>
+</RESOURCE_PROFILE>
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetFactory.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetFactory.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetFactory.java	(revision 49538)
@@ -0,0 +1,50 @@
+package eu.dnetlib.msro.workflows.resultset;
+
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.GraphProcess;
+
+import eu.dnetlib.enabling.resultset.ResultSetFactory;
+import eu.dnetlib.enabling.resultset.client.utils.EPRUtils;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
+import eu.dnetlib.enabling.tools.ServiceResolver;
+import eu.dnetlib.msro.workflows.util.ResultsetProgressProvider;
+
+public class ProcessCountingResultSetFactory {
+
+	private ResultSetFactory resultSetFactory;
+	
+	private ServiceResolver serviceResolver;
+	
+	public ResultsetProgressProvider createProgressProvider(final GraphProcess process, final String epr) throws ResultSetException {
+		return createProgressProvider(process, (new EPRUtils()).getEpr(epr));
+	}
+	
+	public ResultsetProgressProvider createProgressProvider(final GraphProcess process, final W3CEndpointReference epr) throws ResultSetException {
+		final ResultSetService service = serviceResolver.getService(ResultSetService.class, epr);
+		final String rsId = serviceResolver.getResourceIdentifier(epr);
+		return new ResultsetProgressProvider(resultSetFactory, new ProcessCountingResultSetListener(process, service, rsId));
+	}
+
+	public ResultSetFactory getResultSetFactory() {
+		return resultSetFactory;
+	}
+
+	@Required
+	public void setResultSetFactory(ResultSetFactory resultSetFactory) {
+		this.resultSetFactory = resultSetFactory;
+	}
+
+
+	public ServiceResolver getServiceResolver() {
+		return serviceResolver;
+	}
+
+	@Required
+	public void setServiceResolver(ServiceResolver serviceResolver) {
+		this.serviceResolver = serviceResolver;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/layoutToRecordStylesheet.xsl
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/layoutToRecordStylesheet.xsl	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/layoutToRecordStylesheet.xsl	(revision 49538)
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:nxsl="http://www.w3.org/1999/XSL/TransformXX"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+	<xsl:output omit-xml-declaration="yes" method="xml"
+		encoding="UTF-8" />
+	<xsl:namespace-alias stylesheet-prefix="nxsl"
+		result-prefix="xsl" />
+
+	<xsl:param name="format" />
+
+	<xsl:template match="/">
+		<xsl:apply-templates select="//LAYOUT" />
+	</xsl:template>
+
+	<xsl:template match="LAYOUT">
+		<nxsl:stylesheet version="1.0"
+			xmlns:dr="http://www.driver-repository.eu/namespace/dr" xmlns:dc="http://purl.org/dc/elements/1.1/"
+			xmlns:dri="http://www.driver-repository.eu/namespace/dri" xmlns:dnet="eu.dnetlib.miscutils.functional.xml.DnetXsltFunctions"
+			xmlns:exsl="http://exslt.org/common"
+      extension-element-prefixes="exsl">
+
+			<nxsl:output version="1.0" omit-xml-declaration="yes"
+				method="xml" encoding="UTF8" />
+
+			<nxsl:variable name="format">
+				<xsl:value-of select="$format" />
+			</nxsl:variable>
+
+			<nxsl:template match="/">
+				<indexRecord>
+					<indexRecordIdentifier>
+						<nxsl:value-of select="//dri:objIdentifier" />
+					</indexRecordIdentifier>
+					<targetFields>
+						<nxsl:if test="count(//*[local-name()='metadata']/*) &gt; 0">
+							<xsl:apply-templates select="FIELDS/FIELD[@indexable='true']" />
+						</nxsl:if>		
+					</targetFields>
+					<result>
+						<header>
+							<dri:objIdentifier>
+								<nxsl:value-of select="//dri:objIdentifier" />
+							</dri:objIdentifier>
+							<dri:repositoryId>
+								<nxsl:value-of select="//dri:repositoryId" />
+							</dri:repositoryId>
+							<dri:dateOfCollection>
+								<nxsl:value-of select="//dri:dateOfCollection" />
+							</dri:dateOfCollection>
+							<xsl:apply-templates select="FIELDS/FIELD"
+								mode="header" />
+						</header>
+						<metadata>
+							<xsl:apply-templates select="FIELDS/FIELD"
+								mode="result" />
+						</metadata>
+					</result>
+				</indexRecord>
+			</nxsl:template>
+		</nxsl:stylesheet>
+	</xsl:template>
+
+	<xsl:template match="FIELD[@indexable='true']">
+		<xsl:choose>
+			<!-- 
+			<xsl:when test="@name = 'description'">
+				<nxsl:for-each select="{@xpath}">
+					<xsl:element name="{@name}">
+						<nxsl:value-of select="substring(.,1,210)" />
+					</xsl:element>
+				</nxsl:for-each>
+			</xsl:when>
+			 -->
+			<xsl:when test="@constant">
+				<xsl:element name="{@name}">
+					<xsl:value-of select="@constant" />
+				</xsl:element>
+			</xsl:when>
+			<xsl:when test="@value and not(@xpath)">
+				<nxsl:element name="{@name}">
+					<nxsl:value-of select="{@value}" />
+				</nxsl:element>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:variable name="value">
+					<xsl:choose>
+						<xsl:when test="@value">
+							<xsl:value-of select="@value" />
+						</xsl:when>
+						<xsl:otherwise>
+							.
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:variable>
+				<nxsl:for-each select="{@xpath}">
+					<xsl:element name="{@name}">
+						<xsl:if test="@external='true'">
+							<xsl:attribute name="external">true</xsl:attribute>
+						</xsl:if>
+						<xsl:choose>
+							<xsl:when test="@tokenizable='false'">
+								<nxsl:value-of select="normalize-space({normalize-space($value)})" />
+							</xsl:when>
+							<xsl:otherwise>
+								<nxsl:value-of select="{normalize-space($value)}" />
+							</xsl:otherwise>
+						</xsl:choose>
+					</xsl:element>
+				</nxsl:for-each>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
+
+	<xsl:template match="FIELD" mode="result">
+		<xsl:if test="@result='true'">
+			<nxsl:copy-of select="{@xpath}" />
+		</xsl:if>
+	</xsl:template>
+
+	<xsl:template match="FIELD" mode="header">
+		<xsl:if test="@header='true'">
+			<nxsl:copy-of select="{@xpath}" />
+		</xsl:if>
+	</xsl:template>
+
+</xsl:stylesheet>
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/BlackboardJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/BlackboardJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/BlackboardJobNode.java	(revision 49538)
@@ -0,0 +1,91 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardClientHandler;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJobImpl;
+import eu.dnetlib.enabling.tools.blackboard.BlackboardJobRegistry;
+import eu.dnetlib.msro.workflows.nodes.blackboard.BlackboardWorkflowJobListener;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public abstract class BlackboardJobNode extends SarasvatiJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(BlackboardJobNode.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	/**
+	 * blackboard handler.
+	 */
+	@Resource
+	private BlackboardClientHandler blackboardClientHandler;
+
+	/**
+	 * blackboard job registry.
+	 */
+	@Resource
+	private BlackboardJobRegistry jobRegistry;
+
+	@Override
+	public void execute(final Engine engine, final NodeToken token) {
+		super.execute(engine, token);
+
+		log.info("executing blackboard node");
+
+		try {
+			token.getEnv().setAttribute(WorkflowsConstants.BLACKBOARD_IS_BLACKBOARD, true);
+
+			final String serviceId = obtainServiceId(token);
+			if (StringUtils.isBlank(serviceId)) {
+				token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
+				final String msg = "cannot locate target service profile: " + serviceId;
+				token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, msg);
+				log.error(msg);
+				engine.complete(token, "failed");
+				return;
+			}
+
+			final BlackboardJob job = blackboardClientHandler.newJob(serviceId);
+
+			token.getEnv().setTransientAttribute(WorkflowsConstants.BLACKBOARD_JOB, job);
+			token.getEnv().setAttribute(WorkflowsConstants.BLACKBOARD_SERVICE_ID, ((BlackboardJobImpl) job).getServiceId());
+			prepareJob(job, token);
+
+			jobRegistry.registerJobListener(job, generateBlackboardListener(engine, token));
+
+			blackboardClientHandler.assign(job);
+
+		} catch (final Throwable e) {
+			token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
+			token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, "cannot prepare blackboard job: " + e);
+			engine.complete(token, "failed");
+			log.error("cannot prepare blackboard job", e);
+		}
+	}
+
+	abstract protected String obtainServiceId(NodeToken token);
+
+	abstract protected void prepareJob(final BlackboardJob job, final NodeToken token) throws Exception;
+
+	protected BlackboardWorkflowJobListener generateBlackboardListener(final Engine engine, final NodeToken token) {
+		return new BlackboardWorkflowJobListener(engine, token);
+	}
+
+	public UniqueServiceLocator getServiceLocator() {
+		return serviceLocator;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/MetaWorkflowDSResourceType.xsd
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/MetaWorkflowDSResourceType.xsd	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/MetaWorkflowDSResourceType.xsd	(revision 49538)
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+	<xs:element name="RESOURCE_PROFILE">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="HEADER" type="HEADERType" />
+				<xs:element name="BODY" type="BODYType" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:complexType name="HEADERType">
+		<xs:all>
+			<xs:element name="RESOURCE_IDENTIFIER" type="RESOURCE_IDENTIFIERType" />
+			<xs:element name="RESOURCE_TYPE" type="RESOURCE_TYPEType" />
+			<xs:element name="RESOURCE_KIND" type="RESOURCE_KINDType" />
+			<xs:element name="RESOURCE_URI" type="RESOURCE_URIType" />
+			<xs:element name="DATE_OF_CREATION" type="DATEType" />
+		</xs:all>
+	</xs:complexType>
+	<xs:complexType name="BODYType">
+		<xs:sequence>
+			<xs:element name="DATAPROVIDER" minOccurs="0" maxOccurs="1">
+				<xs:complexType>
+					<xs:simpleContent>
+						<xs:extension base="xs:string">
+							<xs:attribute name="id" type="xs:string" use="required" />
+							<xs:attribute name="interface" type="xs:string" use="required" />
+						</xs:extension>
+					</xs:simpleContent>
+				</xs:complexType>			
+			</xs:element>
+			
+			<xs:element name="METAWORKFLOW_NAME">
+				<xs:complexType>
+					<xs:simpleContent>
+						<xs:extension base="xs:string">
+	        				<xs:attribute name="family" type="xs:string" use="required"/>
+	        			</xs:extension>
+	        		</xs:simpleContent>
+        		</xs:complexType>
+			</xs:element>
+			<xs:element name="METAWORKFLOW_DESCRIPTION" type="xs:string" />
+			<xs:element name="METAWORKFLOW_SECTION" type="xs:string"/>
+			<xs:element name="ADMIN_EMAIL" type="xs:string"/>
+			<xs:element name="CONFIGURATION" type="CONFIGURATIONType" />
+			<xs:element name="SCHEDULING" type="SCHEDULINGType" />
+		</xs:sequence>
+	</xs:complexType>
+	<xs:complexType name="RESOURCE_IDENTIFIERType">
+		<xs:attribute name="value" type="xs:string" use="required" />
+	</xs:complexType>
+	<xs:complexType name="RESOURCE_TYPEType">
+		<xs:attribute name="value" use="required">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="MetaWorkflowDSResourceType" />
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="RESOURCE_KINDType">
+		<xs:attribute name="value" use="required">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="MetaWorkflowDSResources" />
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+	</xs:complexType>
+	<xs:complexType name="RESOURCE_URIType">
+		<xs:attribute name="value" type="xs:string" use="required" />
+	</xs:complexType>
+	<xs:complexType name="DATEType">
+		<xs:attribute name="value" type="xs:dateTime" use="required" />
+	</xs:complexType>
+
+	<xs:complexType name="CONFIGURATIONType">
+		<xs:sequence minOccurs="0" maxOccurs="unbounded">
+			<xs:any processContents="skip"/>
+		</xs:sequence>
+		<xs:attribute name="status" use="required">
+			<xs:simpleType>
+				<xs:restriction base="xs:string">
+					<xs:enumeration value="EXECUTABLE" />
+					<xs:enumeration value="WAIT_USER_SETTINGS" />
+					<xs:enumeration value="WAIT_SYS_SETTINGS" />
+					<xs:enumeration value="ASSIGNED" />
+					<xs:enumeration value="MISSING" />
+				</xs:restriction>
+			</xs:simpleType>
+		</xs:attribute>
+		<xs:attribute name="destroyWorkflow" use="optional" type="xs:string" />
+	</xs:complexType>
+	
+	<xs:complexType name="SCHEDULINGType">
+		<xs:sequence>
+			<xs:element name="CRON" type="xs:string" />
+			<xs:element name="MININTERVAL" type="xs:int" />
+		</xs:sequence>
+		<xs:attribute name="enabled" use="required" type="xs:boolean" />
+	</xs:complexType>
+
+</xs:schema>
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/DateRangeCollectRecordsJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/DateRangeCollectRecordsJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/DateRangeCollectRecordsJobNode.java	(revision 49538)
@@ -0,0 +1,89 @@
+package eu.dnetlib.msro.workflows.nodes.collect;
+
+import java.io.StringReader;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.collector.rmi.CollectorService;
+import eu.dnetlib.data.collector.rmi.InterfaceDescriptor;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class DateRangeCollectRecordsJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private String datasourceId;
+	private String datasourceInterface;
+	private String eprParam;
+	private String fromDateParam;
+	private String untilDateParam;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(datasourceId);
+		final Document doc = new SAXReader().read(new StringReader(profile));
+		final Node ifcNode = doc.selectSingleNode("//INTERFACE[@id='" + datasourceInterface + "']");
+		final String fromDate = token.getEnv().getAttribute(getFromDateParam());
+		final String untilDate = token.getEnv().getAttribute(getUntilDateParam());
+
+		final InterfaceDescriptor interfaceDescriptor = InterfaceDescriptor.newInstance(ifcNode);
+
+		final W3CEndpointReference epr = serviceLocator.getService(CollectorService.class).dateRangeCollect(interfaceDescriptor, fromDate, untilDate);
+
+		token.getEnv().setAttribute(getEprParam(), epr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getFromDateParam() {
+		return fromDateParam;
+	}
+
+	public void setFromDateParam(final String fromDateParam) {
+		this.fromDateParam = fromDateParam;
+	}
+
+	public String getUntilDateParam() {
+		return untilDateParam;
+	}
+
+	public void setUntilDateParam(final String untilDateParam) {
+		this.untilDateParam = untilDateParam;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/workflows/xslt/LayoutToRecordStylesheetTest.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/workflows/xslt/LayoutToRecordStylesheetTest.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/workflows/xslt/LayoutToRecordStylesheetTest.java	(revision 49538)
@@ -0,0 +1,87 @@
+package eu.dnetlib.msro.workflows.xslt;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
+import eu.dnetlib.miscutils.functional.xml.IndentXmlString;
+
+public class LayoutToRecordStylesheetTest {
+
+	private static final String LAYOUT_TO_RECORD_STYLESHEET_XSL = "/eu/dnetlib/msro/workflows/xslt/layoutToRecordStylesheet.xsl";
+
+	private static final String MDFORMAT_FIELDS = "/eu/dnetlib/msro/workflows/xslt/fields.xml";
+
+	private static final String OAF_RECORD = "/eu/dnetlib/msro/workflows/xslt/exampleRecord.xml";
+
+	@Test
+	public void test1() throws ISLookUpException, IOException, TransformerException {
+		String xsl = prepareXslt("DMF");
+		assertNotNull(xsl);
+		assertFalse(xsl.isEmpty());
+
+		System.out.println(xsl);
+
+		ApplyXslt xslt = new ApplyXslt(xsl);
+
+		String indexRecord = xslt.evaluate(readFromClasspath(OAF_RECORD));
+
+		assertNotNull(indexRecord);
+		assertFalse(indexRecord.isEmpty());
+
+		System.out.println(IndentXmlString.apply(indexRecord));
+
+		// StreamingInputDocumentFactory factory = new StreamingInputDocumentFactory();
+		//
+		// SolrInputDocument doc = factory.parseDocument(DateUtils.now_ISO8601(), indexRecord, "dsId", "dnetResult");
+		// assertNotNull(doc);
+		// assertFalse(doc.isEmpty());
+
+		// System.out.println(doc);
+
+	}
+
+	protected String prepareXslt(final String format) throws ISLookUpException, IOException, TransformerException {
+
+		final TransformerFactory factory = TransformerFactory.newInstance();
+
+		final Transformer layoutTransformer = factory.newTransformer(streamSource(LAYOUT_TO_RECORD_STYLESHEET_XSL));
+
+		final StreamResult layoutToXsltXslt = new StreamResult(new StringWriter());
+
+		layoutTransformer.setParameter("format", format);
+		layoutTransformer.transform(streamSource(MDFORMAT_FIELDS), layoutToXsltXslt);
+
+		String layoutToXsltXsltString = layoutToXsltXslt.getWriter().toString();
+		System.out.println(IndentXmlString.apply(layoutToXsltXsltString) + "\n\n\n");
+
+		return layoutToXsltXsltString;
+	}
+
+	private StreamSource streamSource(final String s) throws IOException {
+		return new StreamSource(new StringReader(readFromClasspath(s)));
+	}
+
+	private String readFromClasspath(final String s) throws IOException {
+		ClassPathResource resource = new ClassPathResource(s);
+		InputStream inputStream = resource.getInputStream();
+		return IOUtils.toString(inputStream);
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/AsyncJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/AsyncJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/AsyncJobNode.java	(revision 49538)
@@ -0,0 +1,59 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public abstract class AsyncJobNode extends SarasvatiJobNode {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(AsyncJobNode.class);
+
+	private final ExecutorService executor = Executors.newCachedThreadPool();
+
+	@Override
+	public void execute(final Engine engine, final NodeToken token) {
+		super.execute(engine, token);
+
+		log.info("executing async node");
+
+		executor.execute(new Runnable() {
+
+			@Override
+			public void run() {
+				try {
+					log.debug("START NODE: " + getBeanName());
+					beforeStart(token);
+					String arc = execute(token);
+					beforeCompleted(token);
+					log.debug("END NODE (SUCCESS): " + getBeanName());
+					engine.complete(token, arc);
+				} catch (Throwable e) {
+					log.error("got exception while executing workflow node", e);
+					log.debug("END NODE (FAILED): " + getBeanName());
+					beforeFailed(token);
+					token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
+					token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, e.getMessage());
+					engine.complete(token, "failed");
+				}
+			}
+		});
+	}
+
+	abstract protected String execute(final NodeToken token) throws Exception;
+
+	protected void beforeStart(final NodeToken token) {}
+
+	protected void beforeCompleted(final NodeToken token) {}
+
+	protected void beforeFailed(final NodeToken token) {}
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/fields.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/fields.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/fields.xml	(revision 49538)
@@ -0,0 +1,36 @@
+<LAYOUT name="index">
+     <FIELDS>
+         <FIELD indexable="true" name="objIdentifier" result="false" stat="false" tokenizable="false" xpath="//dri:objIdentifier"/>
+         <FIELD indexable="true" name="CobjContentSynthesis" result="true" stat="false" xpath="//dr:CobjContentSynthesis"/>
+         <FIELD indexable="true" name="CobjTypology" result="true" stat="false" tokenizable="false" xpath="//dr:CobjTypology"/>
+         <FIELD indexable="true" name="CobjIdentifier" result="true" stat="false" tokenizable="false" xpath="//dr:CobjIdentifier"/>
+         <FIELD indexable="true" name="CobjModel" result="true" stat="false" tokenizable="false" xpath="//dr:CobjModel"/>
+         <FIELD indexable="true" name="CobjMDFormats" result="true" stat="false" tokenizable="false" xpath="//dr:CobjMDFormats"/>
+         <FIELD indexable="true" name="CobjDescriptionSynthesis" result="true" stat="false" xpath="//dr:CobjDescriptionSynthesis"/>
+         <FIELD indexable="true" name="aggregatorName" result="true" stat="false" xpath="//dr:aggregatorName"/>
+         <FIELD indexable="true" name="aggregatorInstitution" result="true" stat="false" xpath="//dr:aggregatorInstitution"/>
+         <FIELD indexable="true" name="repositoryName" tokenizable="true" result="true" stat="true" xpath="//dr:repositoryName"/>
+         <FIELD indexable="true" name="repositoryLink" result="true" stat="false" tokenizable="false" xpath="//dr:repositoryLink"/>
+         <FIELD indexable="true" name="repositoryCountry" result="true" stat="false" tokenizable="false" xpath="//dr:repositoryCountry"/>
+         <FIELD indexable="true" name="repositoryInstitution" result="true" stat="false" xpath="//dr:repositoryInstitution"/>
+         <FIELD indexable="true" name="repositoryId" result="false" stat="false" xpath="//dri:repositoryId"/>
+         <FIELD indexable="true" name="creator" result="true" stat="false" xpath="//dc:creator"/>
+         <FIELD indexable="true" name="title" result="true" stat="false" xpath="//dc:title"/>
+         <FIELD indexable="true" name="subject" tokenizable="true" result="true" stat="true" xpath="//dc:subject"/>
+         <FIELD indexable="true" name="CobjCategory" result="true" stat="false" tokenizable="false" xpath="//dr:CobjCategory"/>
+         <FIELD indexable="true" name="language" result="true" stat="false" tokenizable="false" xpath="//dc:language"/>
+         <FIELD indexable="true" name="dateAccepted" result="true" stat="false" tokenizable="false" xpath="//*[local-name()='dateAccepted']"/>
+         <FIELD indexable="true" name="identifier" result="true" stat="false" tokenizable="false" xpath="//dc:identifier"/>
+         <FIELD indexable="true" name="publisher" tokenizable="true" result="true" stat="true" xpath="//dc:publisher"/>
+         <FIELD indexable="true" name="source" tokenizable="true" result="true" stat="true" xpath="//dc:source"/>
+         <FIELD indexable="true" name="contributor" tokenizable="true" result="true" stat="true" xpath="//dc:contributor"/>
+         <FIELD indexable="true" name="relation" result="true" stat="false" tokenizable="false" xpath="//dc:relation"/>
+         <FIELD indexable="true" name="description" result="true" stat="false" xpath="//dc:description"/>
+		<!-- Browsing Fields -->
+        <FIELD indexable="true" name="subjectforbrowsing" browsingAliasFor="subject" tokenizable="false" result="false" stat="false" xpath="//dc:subject"/>
+        <FIELD indexable="true" name="contributorforbrowsing" browsingAliasFor="contributor" tokenizable="false" result="false" stat="false" xpath="//dc:contributor"/>
+        <FIELD indexable="true" name="publisherforbrowsing" browsingAliasFor="publisher" tokenizable="false" result="false" stat="false" xpath="//dc:publisher"/>
+        <FIELD indexable="true" name="sourceforbrowsing" browsingAliasFor="source" tokenizable="false" result="false" stat="false" xpath="//dc:source"/>
+        <FIELD indexable="true" name="repositorynameforbrowsing" browsingAliasFor="repositoryName" tokenizable="false" result="false" stat="false" xpath="//dr:repositoryName"/>
+    </FIELDS>
+</LAYOUT>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/CollectRecordsJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/CollectRecordsJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/collect/CollectRecordsJobNode.java	(revision 49538)
@@ -0,0 +1,69 @@
+package eu.dnetlib.msro.workflows.nodes.collect;
+
+import java.io.StringReader;
+
+import javax.annotation.Resource;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import com.googlecode.sarasvati.Arc;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.data.collector.rmi.CollectorService;
+import eu.dnetlib.data.collector.rmi.InterfaceDescriptor;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.nodes.SimpleJobNode;
+
+public class CollectRecordsJobNode extends SimpleJobNode {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private String datasourceId;
+	private String datasourceInterface;
+	private String eprParam;
+
+	@Override
+	protected String execute(final NodeToken token) throws Exception {
+		final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(datasourceId);
+		final Document doc = new SAXReader().read(new StringReader(profile));
+		final Node ifcNode = doc.selectSingleNode("//INTERFACE[@id='" + datasourceInterface + "']");
+
+		final InterfaceDescriptor interfaceDescriptor = InterfaceDescriptor.newInstance(ifcNode);
+
+		final W3CEndpointReference epr = serviceLocator.getService(CollectorService.class).collect(interfaceDescriptor);
+
+		token.getEnv().setAttribute(getEprParam(), epr.toString());
+
+		return Arc.DEFAULT_ARC;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public void setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+	}
+
+	public String getDatasourceInterface() {
+		return datasourceInterface;
+	}
+
+	public void setDatasourceInterface(final String datasourceInterface) {
+		this.datasourceInterface = datasourceInterface;
+	}
+
+	public String getEprParam() {
+		return eprParam;
+	}
+
+	public void setEprParam(final String eprParam) {
+		this.eprParam = eprParam;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/deploy.info
===================================================================
--- modules/dnet-msro-service/branches/dsm/deploy.info	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/deploy.info	(revision 49538)
@@ -0,0 +1,2 @@
+{"type_source": "SVN", "goal": "package -U source:jar", 
+"url": "http://svn-public.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-msro-service/trunk/", "deploy_repository": "dnet45-snapshots", "version": "4", "mail": "sandro.labruzzo@isti.cnr.it,michele.artini@isti.cnr.it, claudio.atzori@isti.cnr.it, alessia.bardi@isti.cnr.it", "deploy_repository_url": "http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-snapshots", "name": "dnet-msro-service"}
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SimpleJobNode.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SimpleJobNode.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/nodes/SimpleJobNode.java	(revision 49538)
@@ -0,0 +1,51 @@
+package eu.dnetlib.msro.workflows.nodes;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.Engine;
+import com.googlecode.sarasvati.NodeToken;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public abstract class SimpleJobNode extends SarasvatiJobNode {
+
+	private static final Log log = LogFactory.getLog(SarasvatiJobNode.class);
+
+	@Override
+	public final void execute(final Engine engine, final NodeToken token) {
+		super.execute(engine, token);
+
+		try {
+			log.debug("START NODE: " + getBeanName());
+			beforeStart(token);
+			String arc = execute(token);
+			beforeCompleted(token);
+			log.debug("END NODE (SUCCESS): " + getBeanName());
+
+			engine.complete(token, arc);
+		} catch (Throwable e) {
+			log.error("got exception while executing workflow node", e);
+			log.debug("END NODE (FAILED): " + getBeanName());
+			beforeFailed(token);
+			token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_HAS_FAILED, true);
+			token.getEnv().setAttribute(WorkflowsConstants.SYSTEM_ERROR, e.getMessage());
+			engine.complete(token, "failed");
+		}
+	}
+
+	abstract protected String execute(final NodeToken token) throws Exception;
+
+	protected void beforeStart(final NodeToken token) {
+		// For optional overwrites
+	}
+
+	protected void beforeCompleted(final NodeToken token) {
+		// For optional overwrites
+	}
+
+	protected void beforeFailed(final NodeToken token) {
+		// For optional overwrites
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WorkflowExecutor.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WorkflowExecutor.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/WorkflowExecutor.java	(revision 49538)
@@ -0,0 +1,239 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Resource;
+
+import com.googlecode.sarasvati.Graph;
+import com.googlecode.sarasvati.GraphProcess;
+import com.googlecode.sarasvati.mem.MemEngine;
+import com.googlecode.sarasvati.mem.MemGraphProcess;
+import eu.dnetlib.enabling.common.Stoppable;
+import eu.dnetlib.enabling.common.StoppableDetails;
+import eu.dnetlib.enabling.common.StoppableDetails.StopStatus;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.sarasvati.registry.GraphProcessRegistry;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+public class WorkflowExecutor implements Stoppable {
+
+	private static final Log log = LogFactory.getLog(WorkflowExecutor.class);
+	private MemEngine engine;
+	private GraphLoader graphLoader;
+	private GraphProcessRegistry graphProcessRegistry;
+	private ProfileToSarasvatiConverter profileToSarasvatiConverter;
+	private ScheduledExecutorService queueConsumers;
+	private boolean paused = false;
+	private int maxRunningWorkflows = WorkflowsConstants.MAX_WF_THREADS;
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+	private PriorityBlockingQueue<GraphProcess> pendingProcs = new PriorityBlockingQueue<GraphProcess>(20, new Comparator<GraphProcess>() {
+
+		@Override
+		public int compare(final GraphProcess p1, final GraphProcess p2) {
+			int n1 = NumberUtils.toInt(p1.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PRIORITY), WorkflowsConstants.DEFAULT_WF_PRIORITY);
+			int n2 = NumberUtils.toInt(p2.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PRIORITY), WorkflowsConstants.DEFAULT_WF_PRIORITY);
+			return NumberUtils.compare(n1, n2);
+		}
+	});
+
+	public boolean isPaused() {
+		return paused;
+	}
+
+	public void setPaused(final boolean paused) {
+		this.paused = paused;
+	}
+
+	public void init() {
+		this.queueConsumers = Executors.newScheduledThreadPool(WorkflowsConstants.MAX_WF_THREADS);
+		final int period = 60;
+		final int step = period / WorkflowsConstants.MAX_WF_THREADS;
+
+		for (int i = 0; i < WorkflowsConstants.MAX_WF_THREADS; i++) {
+			this.queueConsumers.scheduleAtFixedRate(new Runnable() {
+
+				@Override
+				public void run() {
+					if (isPaused()) {
+						return;
+					}
+					int running = graphProcessRegistry.countRunningWfs(false);
+					if (running >= getMaxRunningWorkflows()) {
+						if (log.isDebugEnabled()) {
+							log.debug("reached max running workflows: " + running);
+						}
+						return;
+					}
+
+					final GraphProcess process = pendingProcs.poll();
+					if (process != null) {
+						log.info("Starting workflow: " + process);
+						final long now = DateUtils.now();
+						process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_START_DATE, now);
+						process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_START_HUMAN_DATE, DateUtils.calculate_ISO8601(now));
+						engine.startProcess(process);
+					} else {
+						log.debug("Process queue is empty");
+					}
+				}
+			}, i * step, period, TimeUnit.SECONDS);
+		}
+	}
+
+	public String startProcess(final String profileId) throws Exception {
+		return startProcess(profileId, null);
+	}
+
+	public String startProcess(final String profileId, final Map<String, Object> params) throws Exception {
+		final WfProfileDescriptor desc = profileToSarasvatiConverter.getSarasvatiWorkflow(profileId);
+
+		if (isPaused()) {
+			log.warn("Wf " + profileId + " not launched, because WorkflowExecutor is preparing for shutdown");
+			throw new MSROException("WorkflowExecutor is preparing for shutdown");
+		}
+		if (!desc.isReady()) {
+			log.warn("Wf " + profileId + " not launched, because it is not ready to start");
+			throw new MSROException("Workflow " + profileId + " is not ready to start");
+		}
+		if (pendingProcs.size() > WorkflowsConstants.MAX_PENDING_PROCS_SIZE) {
+			log.warn("Wf " + profileId + " not launched, Max number of pending procs reached: " + WorkflowsConstants.MAX_PENDING_PROCS_SIZE);
+			throw new MSROException("Max number of pending procs reached: " + WorkflowsConstants.MAX_PENDING_PROCS_SIZE);
+		}
+
+		final File tmpFile = File.createTempFile("wftfs", null);
+		try {
+			final Graph graph = graphLoader.loadGraph(desc.getWorkflowXml());
+			final GraphProcess process = new MemGraphProcess(graph);
+			final String procId = graphProcessRegistry.registerProcess(process);
+
+			graphProcessRegistry.associateProcessWithResource(process, profileId);
+
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_PROCESS_ID, procId);
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID, profileId);
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_NAME, desc.getName());
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_NAME, graph.getName());
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_FAMILY, desc.getType());
+			process.getEnv().setAttribute(WorkflowsConstants.SYSTEM_WF_PRIORITY, desc.getPriority());
+
+			if (params != null) {
+				for (Map.Entry<String, Object> e : params.entrySet()) {
+					process.getEnv().setAttribute(e.getKey(), e.getValue());
+				}
+			}
+
+			log.info("Process " + process + " in queue, priority=" + desc.getPriority());
+			pendingProcs.put(process);
+
+			return procId;
+		} catch (Exception e) {
+			log.error("Error parsing workflow xml: " + desc.getWorkflowXml(), e);
+			throw new IllegalArgumentException("Error parsing workflow");
+		} finally {
+			tmpFile.delete();
+		}
+	}
+
+	public void startMetaWorkflow(final String id, final boolean manual) throws Exception {
+		final String query = "/*[.//RESOURCE_IDENTIFIER/@value='" + id + "']//CONFIGURATION[@status='EXECUTABLE']/WORKFLOW/@id/string()";
+
+		final ISLookUpService lookup = serviceLocator.getService(ISLookUpService.class);
+
+		final List<String> list = lookup.quickSearchProfile(query);
+
+		if (list == null || list.isEmpty()) { throw new MSROException("Metaworkflow " + id + " not launched"); }
+
+		for (String wfId : list) {
+			final String q = "/*[.//RESOURCE_IDENTIFIER/@value='" + wfId + "']//CONFIGURATION/@start/string()";
+			if (manual || lookup.getResourceProfileByQuery(q).equals("auto")) {
+				startProcess(wfId);
+			} else {
+				log.debug("Worflow " + wfId + " can not be launched AUTOMATICALLY");
+			}
+		}
+	}
+
+	public GraphLoader getGraphLoader() {
+		return graphLoader;
+	}
+
+	@Required
+	public void setGraphLoader(final GraphLoader graphLoader) {
+		this.graphLoader = graphLoader;
+	}
+
+	public MemEngine getEngine() {
+		return engine;
+	}
+
+	@Required
+	public void setEngine(final MemEngine engine) {
+		this.engine = engine;
+	}
+
+	public GraphProcessRegistry getGraphProcessRegistry() {
+		return graphProcessRegistry;
+	}
+
+	@Required
+	public void setGraphProcessRegistry(final GraphProcessRegistry graphProcessRegistry) {
+		this.graphProcessRegistry = graphProcessRegistry;
+	}
+
+	public ProfileToSarasvatiConverter getProfileToSarasvatiConverter() {
+		return profileToSarasvatiConverter;
+	}
+
+	@Required
+	public void setProfileToSarasvatiConverter(final ProfileToSarasvatiConverter profileToSarasvatiConverter) {
+		this.profileToSarasvatiConverter = profileToSarasvatiConverter;
+	}
+
+	@Override
+	public void stop() {
+		this.paused = true;
+	}
+
+	@Override
+	public void resume() {
+		this.paused = false;
+	}
+
+	@Override
+	public StoppableDetails getStopDetails() {
+		final int count = graphProcessRegistry.countRunningWfs();
+
+		StoppableDetails.StopStatus status = StopStatus.RUNNING;
+		if (isPaused()) {
+			if (count == 0) {
+				status = StopStatus.STOPPED;
+			} else {
+				status = StopStatus.STOPPING;
+			}
+		}
+		graphProcessRegistry.listIdentifiers();
+
+		return new StoppableDetails("D-NET workflow manager", "Running workflows: " + count, status);
+	}
+
+	public int getMaxRunningWorkflows() {
+		return maxRunningWorkflows;
+	}
+
+	public void setMaxRunningWorkflows(final int maxRunningWorkflows) {
+		this.maxRunningWorkflows = maxRunningWorkflows;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProfileToSarasvatiConverter.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProfileToSarasvatiConverter.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/ProfileToSarasvatiConverter.java	(revision 49538)
@@ -0,0 +1,59 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import java.io.StringReader;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Required;
+
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class ProfileToSarasvatiConverter {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	private org.springframework.core.io.Resource xslt;
+
+	private static final Log log = LogFactory.getLog(ProfileToSarasvatiConverter.class);
+
+	public WfProfileDescriptor getSarasvatiWorkflow(final String id) throws DocumentException {
+		final String s = getProfile(id);
+		final Document doc = new SAXReader().read(new StringReader(s));
+		final WfProfileDescriptor desc = new WfProfileDescriptor();
+		desc.setName(doc.valueOf("//WORKFLOW_NAME"));
+		desc.setType(doc.valueOf("//WORKFLOW_TYPE"));
+		desc.setPriority(NumberUtils.toInt("//WORKFLOW_PRIORITY", WorkflowsConstants.DEFAULT_WF_PRIORITY));
+		desc.setWorkflowXml(new ApplyXslt(xslt).evaluate(s));
+		desc.setReady(doc.selectNodes("//PARAM[@required='true' and string-length(normalize-space(.)) = 0]").isEmpty());
+		return desc;
+	}
+
+	public String getProfile(final String id) {
+		try {
+			return serviceLocator.getService(ISLookUpService.class).getResourceProfile(id);
+		} catch (ISLookUpException e) {
+			log.error("Error finding profile: " + id, e);
+			return null;
+		}
+	}
+
+	public org.springframework.core.io.Resource getXslt() {
+		return xslt;
+	}
+
+	@Required
+	public void setXslt(final org.springframework.core.io.Resource xslt) {
+		this.xslt = xslt;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemEngine.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemEngine.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/InjectableMemEngine.java	(revision 49538)
@@ -0,0 +1,40 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.load.GraphLoader;
+import com.googlecode.sarasvati.load.GraphLoaderImpl;
+import com.googlecode.sarasvati.load.GraphValidatorAdapter;
+import com.googlecode.sarasvati.mem.MemEngine;
+import com.googlecode.sarasvati.mem.MemGraph;
+import com.googlecode.sarasvati.mem.MemGraphFactory;
+
+public class InjectableMemEngine extends MemEngine{
+	/**
+	 * custom graph factory.
+	 */
+	private MemGraphFactory graphFactory;
+
+	@Override
+	public MemGraphFactory getFactory() {
+		return graphFactory;
+	}
+
+	@Override
+	public GraphLoader<MemGraph> getLoader() {
+		return new GraphLoaderImpl<MemGraph>(getFactory(), getRepository(), new GraphValidatorAdapter());
+	}
+
+	public boolean isArcExecutionStarted() {
+		return arcExecutionStarted;
+	}
+
+	@Required
+	public void setGraphFactory(final MemGraphFactory graphFactory) {
+		this.graphFactory = graphFactory;
+	}
+
+	public MemGraphFactory getGraphFactory() {
+		return graphFactory;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/registry/GraphProcessRegistry.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/registry/GraphProcessRegistry.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/registry/GraphProcessRegistry.java	(revision 49538)
@@ -0,0 +1,136 @@
+package eu.dnetlib.msro.workflows.sarasvati.registry;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.googlecode.sarasvati.GraphProcess;
+import com.googlecode.sarasvati.ProcessState;
+import eu.dnetlib.msro.workflows.util.ProcessUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+public class GraphProcessRegistry {
+	private static final Log log = LogFactory.getLog(GraphProcessRegistry.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	private BiMap<String, GraphProcess> procs = HashBiMap.create();
+	private Map<String, Collection<GraphProcess>> byResource = new HashMap<String, Collection<GraphProcess>>();
+
+	private int maxSize;
+	
+	public GraphProcess findProcess(final String identifier) {
+		return procs.get(identifier);
+	}
+
+	public Collection<GraphProcess> findProcessesByResource(final String identifier) {
+		synchronized (this) {
+			final Collection<GraphProcess> res = byResource.get(identifier);
+			if (res == null) {
+				return new ArrayList<GraphProcess>();
+			}
+			return res;
+		}
+	}
+
+	public String associateProcessWithResource(final GraphProcess process, final String identifier) {
+		registerProcess(process);
+		synchronized (this) {
+			final Collection<GraphProcess> processes = findProcessesByResource(identifier);
+			processes.add(process);
+			byResource.put(identifier, processes);
+		}
+		return identifier;
+	}
+
+	public String registerProcess(final GraphProcess process) {
+		if (procs.containsValue(process)) {
+			return procs.inverse().get(process);
+		}
+		final String id = ProcessUtils.generateProcessId();
+		
+		if (procs.size() >= maxSize) {
+			removeOldestProcess();
+		}
+		
+		procs.put(id, process);
+		log.info("Registered proc " + process.getGraph().getName() + " with id " + id);
+		
+		return id;
+	}
+	
+	public int countRunningWfs() {
+		return countRunningWfs(true);
+	}
+
+	public int countRunningWfs(boolean includeCreated) {
+		synchronized (this) {
+			int count = 0;
+
+			for (Entry<String, GraphProcess> e : procs.entrySet()) {
+				final GraphProcess proc = e.getValue();
+				final ProcessState state = proc.getState();
+
+				if (!proc.isComplete() && !proc.isCanceled()) {
+					if (includeCreated) {
+						count++;
+					} else if (!state.equals(ProcessState.Created)) {
+						count++;
+					}
+				}
+			}
+
+			return count;
+		}
+	}
+
+	private void removeOldestProcess() {
+		Date oldDate = new Date();
+		String oldId = null;
+		
+		for (Entry<String, GraphProcess> e : procs.entrySet()) {
+			final GraphProcess proc = e.getValue();
+			
+			if (proc.isComplete() || proc.isCanceled()) {
+				final Date date = ProcessUtils.calculateLastActivityDate(proc);
+				if (date.before(oldDate)) {
+					oldDate = date;
+					oldId = e.getKey();
+				}
+			}
+		}
+		
+		if (oldId != null) {
+			unregisterProcess(oldId);
+		}
+		
+	}
+
+	public void unregisterProcess(final String identifier) {
+		final GraphProcess process = findProcess(identifier); // NOPMD
+		procs.remove(identifier);
+
+		for (final Collection<GraphProcess> processes : byResource.values()) {
+			processes.remove(process);
+		}
+	}
+
+	public Collection<String> listIdentifiers() {
+		return procs.keySet();
+	}
+	
+	public Map<String, Collection<GraphProcess>> getByResource() {
+		return byResource;
+	}
+
+	public int getMaxSize() {
+		return maxSize;
+	}
+
+	@Required
+	public void setMaxSize(int maxSize) {
+		this.maxSize = maxSize;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProcessUtils.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProcessUtils.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ProcessUtils.java	(revision 49538)
@@ -0,0 +1,76 @@
+package eu.dnetlib.msro.workflows.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.googlecode.sarasvati.GraphProcess;
+import com.googlecode.sarasvati.NodeToken;
+
+public class ProcessUtils {
+	
+	private static String oldGeneratedId = "";	
+	
+	private static final Log log = LogFactory.getLog(ProcessUtils.class); 
+	
+	public static String calculateName(final GraphProcess process) {
+		return process.getGraph().getName();
+	}
+
+	public static String calculateFamily(final GraphProcess process) {
+		return process.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_FAMILY);
+	}
+	
+	public static String calculateWfId(final GraphProcess process) {
+		return  process.getEnv().getAttribute(WorkflowsConstants.SYSTEM_WF_PROFILE_ID);
+	}
+	
+	public static String calculateStatus(final GraphProcess process) {
+		if (!process.isComplete()) {
+			return process.getState().toString().toUpperCase();
+		} else if ("true".equals(process.getEnv().getAttribute(WorkflowsConstants.SYSTEM_COMPLETED_SUCCESSFULLY))) {
+			return "SUCCESS";
+		} else {
+			return "FAILURE";
+		}
+	}
+	
+	public static Date calculateLastActivityDate(final GraphProcess process) {
+		Date date = null;
+		for (final NodeToken token : process.getNodeTokens()) {
+			Date activity = token.getCompleteDate();
+			if (activity == null)
+				activity = token.getCreateDate();
+
+			if (date == null)
+				date = activity;
+
+			if (activity != null && date != null && activity.compareTo(date) > 0)
+				date = activity;
+		}
+		return date;
+	}
+
+	public static String calculateRepo(final GraphProcess process) {
+		if (process.getEnv().hasAttribute(WorkflowsConstants.DATAPROVIDER_NAME)) {
+			return process.getEnv().getAttribute(WorkflowsConstants.DATAPROVIDER_NAME);
+		}
+		return "";
+	}
+
+	
+	public static synchronized String generateProcessId() {
+		String id = "";
+		do {
+			id = "wf_" + (new SimpleDateFormat("yyyyMMdd_HHmmss_S")).format(new Date());
+			log.info("Generated processID " + id);
+		} while (id.equals(oldGeneratedId));
+		
+		oldGeneratedId = id;
+		
+		return id;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowProfileCreator.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowProfileCreator.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowProfileCreator.java	(revision 49538)
@@ -0,0 +1,46 @@
+package eu.dnetlib.msro.workflows.metawf;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+import eu.dnetlib.msro.workflows.util.WorkflowsConstants;
+
+public class WorkflowProfileCreator {
+
+	private static final Resource wfTemplate = new ClassPathResource("/eu/dnetlib/msro/workflows/templates/workflow.xml.st");
+
+	public static String generateProfile(final String name,
+			final String type,
+			final WorkflowStartModeEnum startMode,
+			final Map<String, String> params,
+			final Resource confTemplate)
+			throws IOException {
+
+		final StringTemplate conf = new StringTemplate(IOUtils.toString(confTemplate.getInputStream()));
+		conf.setAttribute("params", Maps.transformValues(params, new Function<String, String>() {
+
+			@Override
+			public String apply(final String s) {
+				return StringEscapeUtils.escapeXml(s);
+			}
+		}));
+
+		final StringTemplate profile = new StringTemplate(IOUtils.toString(wfTemplate.getInputStream()));
+		profile.setAttribute("name", name);
+		profile.setAttribute("type", type);
+		profile.setAttribute("priority", WorkflowsConstants.DEFAULT_WF_PRIORITY);
+		profile.setAttribute("conf", conf.toString());
+		profile.setAttribute("startMode", startMode);
+
+		return profile.toString();
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflowFactory.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflowFactory.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/DatasourceMetaWorkflowFactory.java	(revision 49538)
@@ -0,0 +1,25 @@
+package eu.dnetlib.msro.workflows.metawf;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class DatasourceMetaWorkflowFactory implements ApplicationContextAware {
+
+	private transient ApplicationContext applicationContext;
+
+	public DatasourceMetaWorkflow newMetaWorkflow(final String beanName) {
+		final DatasourceMetaWorkflow prototypeMetaWf = (DatasourceMetaWorkflow) applicationContext.getBean(beanName, DatasourceMetaWorkflow.class);
+
+		if (prototypeMetaWf != null) {
+			return prototypeMetaWf;
+		} else {
+			throw new IllegalArgumentException("cannot find bean " + beanName);
+		}
+	}
+
+	@Override
+	public void setApplicationContext(final ApplicationContext context) {
+		this.applicationContext = context;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/MSROServiceImpl.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/MSROServiceImpl.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/MSROServiceImpl.java	(revision 49538)
@@ -0,0 +1,59 @@
+package eu.dnetlib.msro;
+
+import javax.jws.WebService;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import eu.dnetlib.enabling.tools.AbstractBaseService;
+import eu.dnetlib.enabling.tools.blackboard.NotificationHandler;
+import eu.dnetlib.msro.rmi.MSROService;
+import eu.dnetlib.msro.workflows.sarasvati.registry.GraphProcessRegistry;
+
+@WebService(targetNamespace = "http://services.dnetlib.eu/")
+public class MSROServiceImpl extends AbstractBaseService implements MSROService {
+
+	/**
+	 * logger.
+	 */
+	private static final Log log = LogFactory.getLog(MSROServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	/**
+	 * notification handler.
+	 */
+	private NotificationHandler notificationHandler;
+
+	/**
+	 * graph process registry.
+	 */
+	private GraphProcessRegistry processRegistry;
+
+	@Override
+	public void notify(final String subscriptionId, final String topic, final String isId, final String message) {
+		super.notify(subscriptionId, topic, isId, message);
+
+		log.debug("got notification: " + topic);
+
+		getNotificationHandler().notified(subscriptionId, topic, isId, message);
+	}
+
+	@Required
+	public void setNotificationHandler(final NotificationHandler notHandler) {
+		this.notificationHandler = notHandler;
+	}
+
+	public NotificationHandler getNotificationHandler() {
+		return notificationHandler;
+	}
+
+	@Required
+	public void setProcessRegistry(final GraphProcessRegistry processRegistry) {
+		this.processRegistry = processRegistry;
+	}
+
+	public GraphProcessRegistry getProcessRegistry() {
+		return processRegistry;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/logIndex.conf
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/logIndex.conf	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/logIndex.conf	(revision 49538)
@@ -0,0 +1 @@
+dnet.log.index.conf { "system:profileId" {}, "system:processId" {}, "system:isCompletedSuccessfully" {}, "system:profileFamily" {} }
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/EmailDispatcher.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/EmailDispatcher.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/EmailDispatcher.java	(revision 49538)
@@ -0,0 +1,255 @@
+package eu.dnetlib.msro.notification;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Maps;
+
+public class EmailDispatcher {
+
+	private String from;
+	private String fromName;
+	private String cc;
+	private String smtpHost;
+	private int smtpPort = 587;
+	private String smtpUser;
+	private String smtpPassword;
+	private String baseUrl;
+	private String infrastructure;
+
+	private static final Log log = LogFactory.getLog(EmailDispatcher.class);
+
+	private final BlockingQueue<Message> queue = new LinkedBlockingQueue<Message>();
+
+	public StringTemplate prepareMessage(final String template, final Map<String, Object> tmplParams) {
+		final StringTemplate st = new StringTemplate(template);
+		st.setAttributes(tmplParams);
+		st.setAttribute("baseUrl", baseUrl);
+		st.setAttribute("infrastructure", infrastructure);
+		return st;
+	}
+
+	public void sendMail(final Set<String> to, final String subject, final String template, final Map<String, Object> tmplParams) {
+		try {
+			final StringTemplate st = prepareMessage(template, tmplParams);
+
+			final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator());
+
+			final MimeMessage message = new MimeMessage(session);
+			message.setFrom(new InternetAddress(from, fromName));
+			message.setSubject(subject);
+			message.setContent(st.toString(), "text/html; charset=utf-8");
+			message.setSentDate(new Date());
+
+			for (String s : to) {
+				message.addRecipient(Message.RecipientType.TO, new InternetAddress(s));
+			}
+			if ((cc != null) && !cc.isEmpty()) {
+				for (String aCC : Splitter.on(",").omitEmptyStrings().trimResults().split(getCc())) {
+					message.addRecipient(Message.RecipientType.CC, new InternetAddress(aCC));
+				}
+			}
+
+			queue.add(message);
+
+			log.info("Mail to " + Arrays.toString(to.toArray()) + " in queue");
+		} catch (Exception e) {
+			log.error("Error sending mail", e);
+		}
+	}
+
+	public void processMailQueue() {
+		while (true) {
+			final Message message = queue.poll();
+			if (message == null) return;
+			else {
+				try {
+					log.info("Sending mail...");
+					Transport.send(message);
+					log.info("...sent");
+				} catch (MessagingException e) {
+					log.error("Error sending email", e);
+					queue.add(message);
+					return;
+				}
+			}
+		}
+	}
+
+	private void sendWfStatusMail(final boolean success,
+			final Set<String> to,
+			final String wfId,
+			final String procId,
+			final String wfName,
+			final Map<String, String> pendingWfs,
+			final Map<String, String> responses,
+			final String error) {
+		try {
+			final Map<String, Object> map = Maps.newHashMap();
+			map.put("wfId", wfId);
+			map.put("wfName", wfName);
+			map.put("procId", procId);
+			if ((pendingWfs != null) && !pendingWfs.isEmpty()) {
+				map.put("pendingWfs", pendingWfs);
+			}
+			if ((responses != null) && !responses.isEmpty()) {
+				map.put("responses", responses);
+			}
+			if ((error != null) && !error.isEmpty()) {
+				map.put("error", error);
+			}
+
+			String subject = success ? "[D-NET WORKFLOW] -- SUCCESS: " : "WF FAILURE: ";
+			subject += wfName + " on " + infrastructure;
+			final String tmplName = success ? "wf_success.mail.st" : "wf_failed.mail.st";
+			final String template = IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/msro/mail/" + tmplName));
+
+			sendMail(to, subject, template, map);
+		} catch (Exception e) {
+			log.error("Error generating success-mail", e);
+		}
+	}
+
+	public void sendSuccessMail(final Set<String> to,
+			final String wfId,
+			final String procId,
+			final String wfName,
+			final Map<String, String> pendingWfs,
+			final Map<String, String> responses) {
+		sendWfStatusMail(true, to, wfId, procId, wfName, pendingWfs, responses, "");
+	}
+
+	public void sendFailedMail(final Set<String> to,
+			final String wfId,
+			final String procId,
+			final String wfName,
+			final Map<String, String> pendingWfs,
+			final Map<String, String> responses,
+			final String error) {
+		sendWfStatusMail(false, to, wfId, procId, wfName, pendingWfs, responses, error);
+	}
+
+	private Properties obtainProperties() {
+		final Properties props = new Properties();
+		props.put("mail.transport.protocol", "smtp");
+		props.put("mail.smtp.host", smtpHost);
+		props.put("mail.smtp.port", smtpPort);
+		props.put("mail.smtp.auth", Boolean.toString((smtpUser != null) && !smtpUser.isEmpty()));
+		return props;
+	}
+
+	private Authenticator obtainAuthenticator() {
+		if ((smtpUser == null) || smtpUser.isEmpty()) return null;
+
+		return new Authenticator() {
+
+			private final PasswordAuthentication authentication = new PasswordAuthentication(smtpUser, smtpPassword);
+
+			@Override
+			protected PasswordAuthentication getPasswordAuthentication() {
+				return authentication;
+			}
+
+		};
+	}
+
+	public String getFrom() {
+		return from;
+	}
+
+	@Required
+	public void setFrom(final String from) {
+		this.from = from;
+	}
+
+	public String getFromName() {
+		return fromName;
+	}
+
+	@Required
+	public void setFromName(final String fromName) {
+		this.fromName = fromName;
+	}
+
+	public String getCc() {
+		return cc;
+	}
+
+	@Required
+	public void setCc(final String cc) {
+		this.cc = cc;
+	}
+
+	public String getSmtpHost() {
+		return smtpHost;
+	}
+
+	@Required
+	public void setSmtpHost(final String smtpHost) {
+		this.smtpHost = smtpHost;
+	}
+
+	public int getSmtpPort() {
+		return smtpPort;
+	}
+
+	public void setSmtpPort(final int smtpPort) {
+		this.smtpPort = smtpPort;
+	}
+
+	public String getSmtpUser() {
+		return smtpUser;
+	}
+
+	public void setSmtpUser(final String smtpUser) {
+		this.smtpUser = smtpUser;
+	}
+
+	public String getSmtpPassword() {
+		return smtpPassword;
+	}
+
+	public void setSmtpPassword(final String smtpPassword) {
+		this.smtpPassword = smtpPassword;
+	}
+
+	public String getBaseUrl() {
+		return baseUrl;
+	}
+
+	@Required
+	public void setBaseUrl(final String baseUrl) {
+		this.baseUrl = baseUrl;
+	}
+
+	public String getInfrastructure() {
+		return infrastructure;
+	}
+
+	@Required
+	public void setInfrastructure(final String infrastructure) {
+		this.infrastructure = infrastructure;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.properties
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.properties	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-service.properties	(revision 49538)
@@ -0,0 +1,31 @@
+msro.wf.ui.dataprovider.protocols = [ {name: 'OAI', value: 'OAI', icon: 'icon-book'}, {name: 'FTP', value: 'FTP', icon: 'icon-download-alt'}, {name: 'local dir', value: 'filesystem', icon: 'icon-folder-open'}, {name: 'local file', value: 'file', icon: 'icon-file'}, {name: 'http', value: 'http', icon: 'icon-arrow-down'} ]
+msro.wf.ui.dataprovider.typologies= [ {name: 'Publication repository', value: 'pubsrepository', icon: 'icon-hdd'}, {name: 'Dataset repository', value: 'datarepository', icon: 'icon-hdd'}, {name: 'Aggregator', value: 'AGGREGATOR', icon: 'icon-hdd'}, {name: 'Entity registry', value: 'entityregistry', icon: 'icon-hdd'} ]
+msro.wf.logger.name = wf_logs
+msro.wf.logger.index.conf = classpath:/eu/dnetlib/msro/service/logIndex.conf
+msro.wf.registry.maxSize = 20
+msro.wf.max.running = 5
+msro.wf.scheduler.startDelay = 60000
+msro.wf.scheduler.repeatInterval = 600000
+msro.wf.scheduler.window.size = 1800000
+
+msro.wf.mail.thread.startDelay = 60000
+msro.wf.mail.thread.repeatInterval = 60000
+
+msro.wf.mail.from = dnet-noreply@research-infrastructures.eu
+msro.wf.mail.fromName = D-NET Workflow Manager
+msro.wf.mail.cc = michele.artini@isti.cnr.it
+msro.wf.mail.smtp.host = localhost
+msro.wf.mail.smtp.port = 587
+msro.wf.mail.smtp.user = 
+msro.wf.mail.smtp.password =
+msro.wf.nodes.mdstoreSearch.format = DMF
+msro.wf.nodes.mdstoreSearch.interpretation = cleaned
+msro.wf.nodes.download.xpathMetadataId = //*[local-name()='objIdentifier']
+service.msro.index.defaultIndex = solr
+
+msro.wf.mail.message.baseUrl = http://localhost:8280/app/mvc/ui
+msro.wf.mail.message.infrastructure= ${container.hostname}
+
+#This property is the default value used by the bean 'mdBuilderTemplateXslt' and injected in MdBuilderJobNode node ~ A.M.
+msro.wf.nodes.mdbuilder.xslt.template = classpath:/eu/dnetlib/msro/workflows/xslt/mdBuilder.xslt.st
+
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow.xml.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow.xml.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow.xml.st	(revision 49538)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RESOURCE_PROFILE>
+    <HEADER>
+        <RESOURCE_IDENTIFIER value=""/>
+        <RESOURCE_TYPE value="WorkflowDSResourceType"/>
+        <RESOURCE_KIND value="WorkflowDSResources"/>
+        <RESOURCE_URI value=""/>
+        <DATE_OF_CREATION value="2006-05-04T18:13:51.0Z"/>
+    </HEADER>
+    <BODY>
+        <WORKFLOW_NAME>$name$</WORKFLOW_NAME>
+		<WORKFLOW_TYPE>$type$</WORKFLOW_TYPE>
+		<WORKFLOW_PRIORITY>$priority$</WORKFLOW_PRIORITY>
+        <CONFIGURATION start="$startMode$">
+        	$conf$
+        </CONFIGURATION>
+        <STATUS />
+    </BODY>
+</RESOURCE_PROFILE>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/GraphLoader.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/GraphLoader.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/sarasvati/loader/GraphLoader.java	(revision 49538)
@@ -0,0 +1,57 @@
+package eu.dnetlib.msro.workflows.sarasvati.loader;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.StringReader;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.googlecode.sarasvati.Graph;
+import com.googlecode.sarasvati.mem.MemEngine;
+
+public class GraphLoader {
+	private MemEngine engine;
+	
+	private static final Log log = LogFactory.getLog(GraphLoader.class);
+	
+	public Graph loadGraph(String xml) throws Exception {
+		final File tmpFile = File.createTempFile("wftfs", null);
+		try {
+			IOUtils.copy(new StringReader(xml), new FileOutputStream(tmpFile));
+			
+			SAXReader reader = new SAXReader();
+			Document doc = reader.read(tmpFile);
+			String graphName = doc.valueOf("/process-definition/@name");
+			
+			getEngine().getLoader().load(tmpFile);
+
+			final Graph graph = getEngine().getRepository().getLatestGraph(graphName);
+			if (graph == null) {
+				throw new IllegalArgumentException("graph called " + graphName + " doesn't exist");
+			}
+			return graph;
+		} catch (DocumentException e) {
+			log.error("Error parsing xml: " + xml, e);
+			throw e;
+		} finally {
+			tmpFile.delete();
+		}
+	}
+	
+
+	public MemEngine getEngine() {
+		return engine;
+	}
+
+	@Required
+	public void setEngine(MemEngine engine) {
+		this.engine = engine;
+	}
+	
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/wf_profile2sarasvati.xslt
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/wf_profile2sarasvati.xslt	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/wf_profile2sarasvati.xslt	(revision 49538)
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version="1.0"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+	<xsl:template match="/">
+		<xsl:variable name="wfname" select="translate(.//WORKFLOW_NAME, ' ', '_')" />
+
+		<process-definition name="{$wfname}" xmlns="http://sarasvati.googlecode.com/ProcessDefinition">
+			<xsl:apply-templates select=".//NODE"/>            
+			
+			<node name="success" type="Success" />
+			<node name="failure" type="Failure" />
+		</process-definition>
+	</xsl:template>
+
+	<xsl:template match="NODE">
+		<xsl:element name="node" namespace="http://sarasvati.googlecode.com/ProcessDefinition">
+			<xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
+			<xsl:if test="@isJoin = 'true'">
+				<xsl:attribute name="joinType">and</xsl:attribute>
+			</xsl:if>
+			<xsl:if test="@isStart = 'true'">
+				<xsl:attribute name="isStart">true</xsl:attribute>
+			</xsl:if>
+			<xsl:if test="string-length(@type) &gt; 0">
+				<xsl:attribute name="type"><xsl:value-of select="@type" /></xsl:attribute>
+			</xsl:if>
+			
+			<xsl:apply-templates select=".//ARC"/>
+			
+			<arc xmlns="http://sarasvati.googlecode.com/ProcessDefinition" name="failed" to="failure" />
+			
+			<xsl:if test="count(.//PARAM[string-length(normalize-space(text())) &gt; 0]) &gt; 0">
+				<custom xmlns="http://sarasvati.googlecode.com/ProcessDefinition">
+					<xsl:apply-templates select=".//PARAM"/>
+				</custom>
+			</xsl:if>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ARC">
+		<xsl:element name="arc" namespace="http://sarasvati.googlecode.com/ProcessDefinition">
+			<xsl:attribute name="to"><xsl:value-of select="@to" /></xsl:attribute>
+			<xsl:if test="string-length(@name) &gt; 0">
+				<xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
+			</xsl:if>
+		</xsl:element> 
+	</xsl:template>
+	
+	<xsl:template match="PARAM">
+		<xsl:if test="string-length(normalize-space(text())) &gt; 0">
+			<xsl:element name="{@name}" namespace="http://sarasvati.googlecode.com/ProcessDefinition"><xsl:value-of select="text()" /></xsl:element>
+		</xsl:if>
+	</xsl:template>
+	
+</xsl:stylesheet>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/WorkflowDSResourceType.xsd
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/WorkflowDSResourceType.xsd	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/test/schemas/WorkflowDSResourceType.xsd	(revision 49538)
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	elementFormDefault="qualified">
+	<xs:element name="RESOURCE_PROFILE">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="HEADER" />
+				<xs:element ref="BODY" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="HEADER">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="RESOURCE_IDENTIFIER" />
+				<xs:element ref="RESOURCE_TYPE" />
+				<xs:element ref="RESOURCE_KIND" />
+				<xs:element ref="RESOURCE_URI" />
+				<xs:element ref="DATE_OF_CREATION" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="RESOURCE_IDENTIFIER">
+		<xs:complexType>
+			<xs:attribute name="value" use="required" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="RESOURCE_TYPE">
+		<xs:complexType>
+			<xs:attribute name="value" use="required" fixed="WorkflowDSResourceType" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="RESOURCE_KIND">
+		<xs:complexType>
+			<xs:attribute name="value" use="required" fixed="WorkflowDSResources" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="RESOURCE_URI">
+		<xs:complexType>
+			<xs:attribute name="value" use="required" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="DATE_OF_CREATION">
+		<xs:complexType>
+			<xs:attribute name="value" use="required" type="xs:dateTime" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="BODY">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="WORKFLOW_NAME" type="xs:string" />
+				<xs:element name="WORKFLOW_INFO" minOccurs="0" maxOccurs="1">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="FIELD" minOccurs="0" maxOccurs="unbounded">
+								<xs:complexType>
+									<xs:simpleContent>
+										<xs:extension base="xs:string">
+											<xs:attribute name="name" use="required" type="xs:string"/>
+										</xs:extension>
+									</xs:simpleContent>
+								</xs:complexType>
+							</xs:element>
+						</xs:sequence>	
+					</xs:complexType>
+				</xs:element>
+				<xs:element name="WORKFLOW_TYPE" type="xs:string" />
+				<xs:element name="WORKFLOW_PRIORITY">
+					<xs:simpleType>
+						<xs:restriction base="xs:integer">
+							<xs:minInclusive value="0" />
+							<xs:maxInclusive value="100" />
+						</xs:restriction>
+					</xs:simpleType>
+				</xs:element>
+				<xs:element ref="CONFIGURATION" />
+				<xs:element ref="STATUS" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="WORKFLOW_NAME" type="xs:string" />
+	<xs:element name="CONFIGURATION">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element maxOccurs="unbounded" ref="NODE" />
+			</xs:sequence>
+			<xs:attribute name="start" use="required">
+				<xs:simpleType>
+					<xs:restriction base="xs:NCName">
+						<xs:enumeration value="auto" />
+						<xs:enumeration value="manual" />
+						<xs:enumeration value="disabled" />
+					</xs:restriction>
+				</xs:simpleType>
+			</xs:attribute>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="NODE">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="DESCRIPTION" />
+				<xs:element ref="PARAMETERS" />
+				<xs:element ref="ARCS" />
+			</xs:sequence>
+			<xs:attribute name="isStart" use="optional" type="xs:boolean" />
+			<xs:attribute name="isJoin" use="optional" type="xs:boolean" />
+			<xs:attribute name="name" use="required" type="xs:NCName" />
+			<xs:attribute name="type" use="optional" type="xs:NCName" />
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="DESCRIPTION" type="xs:string" />
+	<xs:element name="PARAMETERS">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element minOccurs="0" maxOccurs="unbounded" ref="PARAM" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="PARAM">
+		<xs:complexType mixed="true">
+			<xs:simpleContent>
+				<xs:extension base="xs:string">
+					<xs:attribute name="name" use="required" type="xs:NCName" />
+					<xs:attribute name="required" use="optional" type="xs:boolean" />
+					<xs:attribute name="managedBy" use="required">
+						<xs:simpleType>
+							<xs:restriction base="xs:NCName">
+								<xs:enumeration value="user" />
+								<xs:enumeration value="system" />
+							</xs:restriction>
+						</xs:simpleType>
+					</xs:attribute>
+					<xs:attribute name="type" use="optional">
+						<xs:simpleType>
+							<xs:restriction base="xs:NCName">
+								<xs:enumeration value="int" />
+								<xs:enumeration value="boolean" />
+								<xs:enumeration value="float" />
+								<xs:enumeration value="string" />
+								<xs:enumeration value="date" />
+								<xs:enumeration value="datetime" />
+								<xs:enumeration value="property" />
+							</xs:restriction>
+						</xs:simpleType>
+					</xs:attribute>
+					<xs:attribute name="function" use="optional" type="xs:string" />
+					<xs:attribute name="category" use="optional" type="xs:string" />
+				</xs:extension>
+			</xs:simpleContent>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="ARCS">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element maxOccurs="unbounded" ref="ARC" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="ARC">
+		<xs:complexType>
+			<xs:attribute name="name" use="optional" type="xs:string" />
+			<xs:attribute name="to" use="required" type="xs:NCName" />
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="STATUS">
+		<xs:complexType>
+			<xs:sequence minOccurs="0">
+				<xs:element name="LAST_EXECUTION_ID" type="xs:string" />
+				<xs:element name="LAST_EXECUTION_DATE" type="xs:dateTime" />
+				<xs:element name="LAST_EXECUTION_STATUS" type="xs:NCName" />
+				<xs:element name="LAST_EXECUTION_ERROR" type="xs:string" />
+				<xs:element name="LAST_EXECUTION_OUTPUT" minOccurs="0" maxOccurs="unbounded">
+					<xs:complexType>
+						<xs:simpleContent>
+							<xs:extension base="xs:string">
+								<xs:attribute name="name" type="xs:string" use="required" />
+							</xs:extension>
+						</xs:simpleContent>
+					</xs:complexType>
+				</xs:element>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+</xs:schema>
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowsConstants.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowsConstants.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/WorkflowsConstants.java	(revision 49538)
@@ -0,0 +1,115 @@
+package eu.dnetlib.msro.workflows.util;
+
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import org.springframework.beans.factory.annotation.Required;
+
+public class WorkflowsConstants {
+
+	public static final String SYSTEM_WF_NAME = "system:wfName";
+	public static final String SYSTEM_WF_PROFILE_ID = "system:profileId";
+	public static final String SYSTEM_WF_PROFILE_NAME = "system:profileName";
+	public static final String SYSTEM_WF_PROFILE_FAMILY = "system:profileFamily";
+	public static final String SYSTEM_WF_PRIORITY = "system:priority";
+	public static final String SYSTEM_WF_PROCESS_ID = "system:processId";
+	public static final String SYSTEM_ERROR = "system:error";
+	public static final String SYSTEM_HAS_FAILED = "system:hasFailed";
+	public static final String SYSTEM_START_HUMAN_DATE = "system:startHumanDate";
+	public static final String SYSTEM_START_DATE = "system:startDate";
+	public static final String SYSTEM_END_HUMAN_DATE = "system:endHumanDate";
+	public static final String SYSTEM_END_DATE = "system:endDate";
+
+	public static final String SYSTEM_COMPLETED_SUCCESSFULLY = "system:isCompletedSuccessfully";
+	public static final String BLACKBOARD_IS_BLACKBOARD = "blackboard:isBlackboard";
+	public static final String BLACKBOARD_JOB = "blackboard:job";
+	public static final String BLACKBOARD_SERVICE_ID = "blackboard:serviceId";
+	public static final String BLACKBOARD_IS_GOING = "blackboard:isOngoing";
+	public static final String BLACKBOARD_PARAM_PREFIX = "blackboard:param:";
+
+	public static final String DATAPROVIDER_PREFIX = "dataprovider:";
+	public static final String DATAPROVIDER_ID = WorkflowsConstants.DATAPROVIDER_PREFIX + "id";
+	public static final String DATAPROVIDER_NAME = WorkflowsConstants.DATAPROVIDER_PREFIX + "name";
+	public static final String DATAPROVIDER_ACRONYM = WorkflowsConstants.DATAPROVIDER_PREFIX + "acronym";
+	public static final String DATAPROVIDER_URL = WorkflowsConstants.DATAPROVIDER_PREFIX + "url";
+	public static final String DATAPROVIDER_INTERFACE = WorkflowsConstants.DATAPROVIDER_PREFIX + "interface";
+	public static final String DATAPROVIDER_INTERFACE_COMPLIANCE = DATAPROVIDER_INTERFACE + ":compliance";
+	public static final String DATAPROVIDER_INTERFACE_BASEURL = DATAPROVIDER_INTERFACE + ":baseUrl";
+	public static final String DATAPROVIDER_ORIGINALID = DATAPROVIDER_PREFIX + "originalid";
+	public static final String DATAPROVIDER_NAMESPACE_PREFIX = WorkflowsConstants.DATAPROVIDER_PREFIX + "nsPrefix";
+
+	public static final int MIN_WF_PRIORITY = 0;
+	public static final int MAX_WF_PRIORITY = 100;
+	public static final int DEFAULT_WF_PRIORITY = 50;
+	public static final int MAX_PENDING_PROCS_SIZE = 100;
+	public static final int MAX_WF_THREADS = 10;
+	public static final String MAIN_LOG_PREFIX = "mainlog:";
+
+	public enum WorkflowStatus {
+		EXECUTABLE("Executable", "icon-ok"), WAIT_USER_SETTINGS("Waiting user settings", "icon-edit"), WAIT_SYS_SETTINGS("Waiting system settings",
+				"icon-refresh"), ASSIGNED("Assigned", "icon-ok-circle"), MISSING("Missing workflow", "icon-warning-sign");
+
+		public String displayName;
+		public String icon;
+
+		WorkflowStatus(final String displayName, final String icon) {
+			this.displayName = displayName;
+			this.icon = icon;
+		}
+	}
+
+	private String dataproviderProtocolsJson;
+	private String dataproviderTypologiesJson;
+	private List<Map<String, String>> dataproviderProtocols;
+	private List<Map<String, String>> dataproviderTypologies;
+	private List<Map<String, String>> dataproviderWorkflowStatuses;
+
+	@SuppressWarnings("unchecked")
+	public void init() {
+		Gson gson = new Gson();
+		dataproviderProtocols = gson.fromJson(dataproviderProtocolsJson, List.class);
+		dataproviderTypologies = gson.fromJson(dataproviderTypologiesJson, List.class);
+		dataproviderWorkflowStatuses = Lists.newArrayList();
+		for (WorkflowStatus s : WorkflowStatus.values()) {
+			Map<String, String> map = Maps.newHashMap();
+			map.put("name", s.displayName);
+			map.put("icon", s.icon);
+			map.put("value", s.toString());
+			dataproviderWorkflowStatuses.add(map);
+		}
+	}
+
+	public String getDataproviderProtocolsJson() {
+		return dataproviderProtocolsJson;
+	}
+
+	@Required
+	public void setDataproviderProtocolsJson(final String dataproviderProtocolsJson) {
+		this.dataproviderProtocolsJson = dataproviderProtocolsJson;
+	}
+
+	public String getDataproviderTypologiesJson() {
+		return dataproviderTypologiesJson;
+	}
+
+	@Required
+	public void setDataproviderTypologiesJson(final String dataproviderTypologiesJson) {
+		this.dataproviderTypologiesJson = dataproviderTypologiesJson;
+	}
+
+	public List<Map<String, String>> getDataproviderProtocols() {
+		return dataproviderProtocols;
+	}
+
+	public List<Map<String, String>> getDataproviderTypologies() {
+		return dataproviderTypologies;
+	}
+
+	public List<Map<String, String>> getDataproviderWorkflowStatuses() {
+		return dataproviderWorkflowStatuses;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/notification/EmailDispatcherTest.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/notification/EmailDispatcherTest.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/notification/EmailDispatcherTest.java	(revision 49538)
@@ -0,0 +1,51 @@
+package eu.dnetlib.msro.notification;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.Maps;
+
+public class EmailDispatcherTest {
+
+	private String successTemplatePath = "/eu/dnetlib/msro/mail/wf_success.mail.st";
+	private String failureTemplatePath = "/eu/dnetlib/msro/mail/wf_failed.mail.st";
+	private EmailDispatcher dispatcher;
+
+	@Before
+	public void setUp() throws Exception {
+		dispatcher = new EmailDispatcher();
+		dispatcher.setBaseUrl("http://the.base.url");
+		dispatcher.setInfrastructure("container.hostname");
+	}
+
+	@Test
+	public void testPrepareMessageSuccess() throws IOException {
+
+		final String template = IOUtils.toString(getClass().getResourceAsStream(successTemplatePath));
+		final Map<String, Object> map = Maps.newHashMap();
+		map.put("wfId", "WF_ID");
+		map.put("wfName", "WF_NAME");
+		map.put("procId", "PROC_ID");
+
+		StringTemplate st = dispatcher.prepareMessage(template, map);
+		System.out.println(st.toString());
+	}
+
+	@Test
+	public void testPrepareMessageFailure() throws IOException {
+
+		final String template = IOUtils.toString(getClass().getResourceAsStream(failureTemplatePath));
+		final Map<String, Object> map = Maps.newHashMap();
+		map.put("wfId", "WF_ID");
+		map.put("wfName", "WF_NAME");
+		map.put("procId", "PROC_ID");
+
+		StringTemplate st = dispatcher.prepareMessage(template, map);
+		System.out.println(st.toString());
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ValidNodeValuesFetcher.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ValidNodeValuesFetcher.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/util/ValidNodeValuesFetcher.java	(revision 49538)
@@ -0,0 +1,72 @@
+package eu.dnetlib.msro.workflows.util;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Required;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.miscutils.functional.UnaryFunction;
+import eu.dnetlib.msro.rmi.MSROException;
+import eu.dnetlib.msro.workflows.util.ValidNodeValuesFetcher.DnetParamValue;
+
+public abstract class ValidNodeValuesFetcher implements UnaryFunction<List<DnetParamValue>, Map<String, String>> {
+
+	private String name;
+
+	private static final Log log = LogFactory.getLog(ValidNodeValuesFetcher.class);
+
+	public class DnetParamValue implements Comparable<DnetParamValue> {
+
+		private String id;
+		private String name;
+
+		public DnetParamValue(final String id, final String name) {
+			this.id = id;
+			this.name = name;
+		}
+
+		public String getId() {
+			return id;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		@Override
+		public int compareTo(final DnetParamValue o) {
+			return getName().compareTo(o.getName());
+		}
+	}
+
+	@Override
+	final public List<DnetParamValue> evaluate(final Map<String, String> params) {
+		try {
+			return obtainValues(params);
+		} catch (Throwable e) {
+			log.error("Error obtaing values", e);
+			return Lists.newArrayList();
+		}
+	}
+
+	abstract protected List<DnetParamValue> obtainValues(Map<String, String> params) throws Exception;
+
+	public String getName() {
+		return name;
+	}
+
+	@Required
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	protected void verifyParams(final Map<String, String> params, final String... pnames) throws MSROException {
+		for (String s : pnames) {
+			if (!params.containsKey(s)) { throw new MSROException("Parameter not found: " + s); }
+		}
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/exampleRecord.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/exampleRecord.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/msro/workflows/xslt/exampleRecord.xml	(revision 49538)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<record xmlns:dc="http://purl.org/dc/elements/1.1/"
+  xmlns:dr="http://www.driver-repository.eu/namespace/dr"
+  xmlns:dri="http://www.driver-repository.eu/namespace/dri"
+  xmlns:oaf="http://namespace.openaire.eu/oaf"
+  xmlns:prov="http://www.openarchives.org/OAI/2.0/provenance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <header xmlns="http://namespace.openaire.eu/">
+    <dri:objIdentifier>PUMA::017b981f757dec43ff5d691bed64f36f</dri:objIdentifier>
+    <dri:recordIdentifier>oai:pumaoai.isti.cnr.it:cnr.isti/cnr.cnuce/1975-B4-019</dri:recordIdentifier>
+    <dri:dateOfCollection/>
+    <dri:mdFormat/>
+    <dri:mdFormatInterpretation/>
+    <dri:repositoryId>2c8bf258-251a-4cdc-b735-bbb4e651cae9_UmVwb3NpdG9yeVNlcnZpY2VSZXNvdXJjZXMvUmVwb3NpdG9yeVNlcnZpY2VSZXNvdXJjZVR5cGU=</dri:repositoryId>
+    <dr:objectIdentifier/>
+    <dr:dateOfCollection>2014-11-18T11:22:35Z</dr:dateOfCollection>
+  </header>
+  <metadata xmlns="http://namespace.openaire.eu/">
+    <dc:creator>Bracci, Edoardo</dc:creator>
+    <dc:creator>Medves, Riccardo</dc:creator>
+    <dc:title>Foo</dc:title>
+    <dc:date>1975-07-01</dc:date>
+    <dc:description>No abstract available.</dc:description>
+    <dc:identifier>http://puma.isti.cnr.it/dfdownloadnew.php?ident=cnr.isti/cnr.cnuce/1975-B4-019</dc:identifier>
+    <dc:identifier>http://puma.isti.cnr.it/rmydownload.php?filename=cnr.isti/cnr.cnuce/1975-B4-019/1975-B4-019.pdf</dc:identifier>
+    <dc:language>it</dc:language>
+    <dc:source>Internal note CNUCE-Manuali-91-1975, 1975.</dc:source>
+    <dc:subject>Utilities</dc:subject>
+    <dr:CobjCategory>Otro</dr:CobjCategory>
+    <oaf:dateAccepted>1975-07-01</oaf:dateAccepted>
+    <oaf:collectedDatasourceid/>
+    <oaf:accessrights>OPEN</oaf:accessrights>
+    <oaf:hostedBy id="" name="PUblication MAnagement"/>
+    <oaf:collectedFrom id="" name="PUblication MAnagement"/>
+  </metadata>
+</record>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowStartModeEnum.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowStartModeEnum.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/metawf/WorkflowStartModeEnum.java	(revision 49538)
@@ -0,0 +1,5 @@
+package eu.dnetlib.msro.workflows.metawf;
+
+public enum WorkflowStartModeEnum {
+	auto, manual, disabled
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetListener.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetListener.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/workflows/resultset/ProcessCountingResultSetListener.java	(revision 49538)
@@ -0,0 +1,119 @@
+package eu.dnetlib.msro.workflows.resultset;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.collect.Lists;
+import com.googlecode.sarasvati.GraphProcess;
+
+import eu.dnetlib.enabling.resultset.ResultSet;
+import eu.dnetlib.enabling.resultset.ResultSetAware;
+import eu.dnetlib.enabling.resultset.ResultSetListener;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
+import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
+
+public class ProcessCountingResultSetListener implements ResultSetListener, ResultSetAware {
+
+	private int count;
+
+	private GraphProcess process;
+	private ResultSetService inputService;
+	private String inputRsId;
+	private ResultSet outputResulset;
+	private int inputSize;
+	private boolean inaccurate = false;
+
+	private final static String RS_CLOSED = "closed";
+	/**
+	 * Logger.
+	 */
+	private static final Log log = LogFactory.getLog(ProcessCountingResultSetListener.class);
+
+	public ProcessCountingResultSetListener(final GraphProcess process, final ResultSetService inputService, final String inputRsId) throws ResultSetException {
+		super();
+		this.process = process;
+		this.inputService = inputService;
+		this.inputRsId = inputRsId;
+		this.inputSize = inputService.getNumberOfElements(inputRsId);
+		this.count = 0;
+	}
+
+	@Override
+	public List<String> getResult(final int from, final int to) {
+		if (process.isCanceled()) {
+			this.outputResulset.close();
+			return Lists.newArrayList();
+		}
+		try {
+			this.count = to;
+			if (count >= this.inputSize) {
+				closeRSIfNeeded();
+			}
+			return inputService.getResult(inputRsId, from, to, "WAITING");
+		} catch (ResultSetException e) {
+			log.error("Error fetching records from resultset: " + inputRsId);
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public int getSize() {
+		if (process.isCanceled()) {
+			this.outputResulset.close();
+			return count;
+		}
+		try {
+			int size = inputService.getNumberOfElements(inputRsId);
+			if (this.inputSize != size) {
+				this.inputSize = size;
+				this.inaccurate = true;
+			}
+			this.inputSize = size;
+			if (count >= this.inputSize) {
+				this.inaccurate = false;
+				closeRSIfNeeded();
+
+			}
+			return this.inputSize;
+		} catch (ResultSetException e) {
+			log.error("Error fetching records from resultset: " + inputRsId);
+			throw new RuntimeException(e);
+		}
+
+	}
+
+	private void closeRSIfNeeded() throws ResultSetException {
+		String inputClassName = inputService.getProperty(inputRsId, "classSimpleName");
+		if (StringUtils.isNotBlank(inputClassName) && inputClassName.equalsIgnoreCase("TransientPushResultSetImpl")) {
+			// Push result set has inaccurate progress
+			this.inaccurate = true;
+			log.info("Not closing the counting resultset unless the underlying push result is already closed ");
+			if (inputService.getRSStatus(inputRsId).equals(RS_CLOSED)) {
+				outputResulset.close();
+			}
+		} else {
+			outputResulset.close();
+		}
+	}
+
+	@Override
+	public void setResultSet(final ResultSet outputResulset) {
+		this.outputResulset = outputResulset;
+	}
+
+	public int getCount() {
+		return count;
+	}
+
+	public void setCount(final int count) {
+		this.count = count;
+	}
+
+	public boolean isInaccurate() {
+		return inaccurate;
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/WfDependencyLauncherNotificationHandler.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/WfDependencyLauncherNotificationHandler.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/java/eu/dnetlib/msro/notification/WfDependencyLauncherNotificationHandler.java	(revision 49538)
@@ -0,0 +1,115 @@
+package eu.dnetlib.msro.notification;
+
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Resource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.enabling.actions.AbstractSubscriptionAction;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.enabling.locators.UniqueServiceLocator;
+import eu.dnetlib.msro.workflows.metawf.WorkflowStartModeEnum;
+import eu.dnetlib.msro.workflows.sarasvati.loader.WorkflowExecutor;
+
+public class WfDependencyLauncherNotificationHandler extends AbstractSubscriptionAction {
+
+	@Resource
+	private UniqueServiceLocator serviceLocator;
+
+	@Resource
+	private WorkflowExecutor workflowExecutor;
+
+	@Resource
+	private EmailDispatcher emailDispatcher;
+
+	private static final Log log = LogFactory.getLog(WorkflowExecutor.class);
+
+	@Override
+	public void notified(final String subscrId, final String topic, final String rsId, final String profile) {
+
+		final SAXReader reader = new SAXReader();
+		try {
+			final Document doc = reader.read(new StringReader(profile));
+
+			final Set<String> emails = calculateEmails(rsId);
+			final String procId = doc.valueOf("//LAST_EXECUTION_ID");
+			final String wfName = doc.valueOf("//WORKFLOW_NAME");
+			final boolean success = doc.valueOf("//LAST_EXECUTION_STATUS").equals("SUCCESS");
+			final Map<String, String> responses = Maps.newHashMap();
+
+			for (Object o : doc.selectNodes("//LAST_EXECUTION_OUTPUT")) {
+				Node n = (Node) o;
+				responses.put(n.valueOf("@name"), n.getText());
+			}
+
+			if (!success) {
+				log.info("Last execution of " + rsId + " failed, dependencies NOT STARTED");
+			}
+
+			final String query = "for $x in collection('/db/DRIVER/MetaWorkflowDSResources/MetaWorkflowDSResourceType')//WORKFLOW[@id='" + rsId
+					+ "']/WORKFLOW let $y := /RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $x/@id] "
+					+ "where $y//CONFIGURATION/@start != 'disabled' return concat ($x/@id , ' @@@ ', $x/@name , ' @@@ ', $y//CONFIGURATION/@start)";
+
+			try {
+				final Map<String, String> pendingWfs = Maps.newHashMap();
+
+				for (String s : serviceLocator.getService(ISLookUpService.class).quickSearchProfile(query)) {
+					final String[] arr = s.split("@@@");
+					final String id = arr[0].trim();
+					final String name = arr[1].trim();
+					final boolean manual = arr[2].trim().equalsIgnoreCase(WorkflowStartModeEnum.manual.toString());
+					if (success && !manual) {
+						try {
+							String pid = workflowExecutor.startProcess(id);
+							log.info("PROC " + pid + " of WF " + id + " STARTED AS CHILD OF " + rsId);
+						} catch (Exception e) {
+							log.error("Error starting wf: " + id);
+						}
+					} else {
+						pendingWfs.put(id, name);
+					}
+				}
+
+				if (!emails.isEmpty()) {
+					if (success) {
+						emailDispatcher.sendSuccessMail(emails, rsId, procId, wfName, pendingWfs, responses);
+					} else {
+						final String error = doc.valueOf("//LAST_EXECUTION_ERROR");
+						emailDispatcher.sendFailedMail(emails, rsId, procId, wfName, pendingWfs, responses, error);
+					}
+				}
+			} catch (ISLookUpException e) {
+				log.error("Error executing xquery: " + query, e);
+			}
+		} catch (DocumentException e) {
+			log.error("Error parsing profile with id " + rsId + ": " + profile);
+		}
+	}
+
+	private Set<String> calculateEmails(final String id) {
+		final Set<String> list = Sets.newHashSet();
+		try {
+			for (String val : serviceLocator.getService(ISLookUpService.class).quickSearchProfile("//ADMIN_EMAIL[..//WORKFLOW/@id='" + id + "']/text()")) {
+				for (String s : Splitter.on(",").trimResults().omitEmptyStrings().split(val)) {
+					list.add(s);
+				}
+			}
+		} catch (Exception e) {
+			log.error("Error searching email adresses", e);
+		}
+		return list;
+	}
+}
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-nodes.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-nodes.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/service/applicationContext-msro-nodes.xml	(revision 49538)
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:http="http://cxf.apache.org/transports/http/configuration" xmlns="http://www.springframework.org/schema/beans"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+
+
+                                    http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">
+
+	<bean id="wfNodeSelection" class="eu.dnetlib.msro.workflows.nodes.sel.SelectiveNode"
+		scope="prototype" />
+		
+	<!-- IS -->
+	<bean id="wfNodeValidateProfiles"
+		class="eu.dnetlib.msro.workflows.nodes.is.ValidateProfilesJobNode"
+		scope="prototype" />
+
+	<!-- Datasources -->
+	<bean id="wfNodeSetProviderInfo"
+		class="eu.dnetlib.msro.workflows.nodes.info.SetProviderInfoJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeValidateDatasource"
+		class="eu.dnetlib.msro.workflows.nodes.repohi.ValidateDatasourceJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeVerifyDatasource"
+		class="eu.dnetlib.msro.workflows.nodes.repohi.VerifyDatasourceJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeCreateObjectStore"
+		class="eu.dnetlib.msro.workflows.nodes.repohi.CreateObjectStoreJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeDropContentObjectStore"
+	      class="eu.dnetlib.msro.workflows.nodes.objectStore.DropContentObjectStoreJobNode"
+	      scope="prototype"/>
+		
+	<!-- Unpack -->
+	<bean id="wfNodeUnpack" 
+		class="eu.dnetlib.msro.workflows.nodes.unpack.UnpackJobNode"
+		p:resultSetClientFactory-ref="resultSetClientFactory"
+		p:iterableResultSetFactory-ref="iterableResultSetFactory" 
+		scope="prototype" />
+	
+	<!--  ObjectStore -->
+	<bean id="wfNodeDownloadIntoObjectStore"
+		class="eu.dnetlib.msro.workflows.nodes.objectStore.DownloadIntoObjectStoreJobNode"
+		scope="prototype" 
+		p:processCountingResultSetFactory-ref="msroProcessCountingResultSetFactory"
+		p:resultSetClientFactory-ref="resultSetClientFactory"
+		p:iterableResultSetFactory-ref="iterableResultSetFactory"  />
+	<bean id ="wfNodeDeleteObjectStore" class= "eu.dnetlib.msro.workflows.nodes.repobye.DeleteObjectStoreJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeRetrieveURLS"
+		class="eu.dnetlib.msro.workflows.nodes.objectStore.RetrieveURLSJobNode"
+		p:xpathMetadataId="${msro.wf.nodes.download.xpathMetadataId}"
+		scope="prototype" />
+		
+	<!-- Download Service -->
+	<bean id="wfNodeRetrieveMdStoreId" class ="eu.dnetlib.msro.workflows.nodes.objectStore.RetrieveMdStoreId"
+		p:metadataFormat="${msro.wf.nodes.mdstoreSearch.format}"
+		p:interpretation="${msro.wf.nodes.mdstoreSearch.interpretation}"
+		scope="prototype"
+	/>
+	
+	<bean id ="wfNodeDownloadFromMetadata" class="eu.dnetlib.msro.workflows.nodes.download.DownloadFromMetadataJobNode"		
+		scope="prototype" />
+		
+	<bean id ="wfNodeUpdateObjectStoreSize" class="eu.dnetlib.msro.workflows.nodes.objectStore.UpdateObjectStoreSizeJobNode"		
+		scope="prototype" />
+	
+	<!-- Collector service -->
+	<bean id="wfNodeCollectRecords"
+		class="eu.dnetlib.msro.workflows.nodes.collect.CollectRecordsJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeDateRangeCollectRecords"
+		class="eu.dnetlib.msro.workflows.nodes.collect.DateRangeCollectRecordsJobNode"
+		scope="prototype" />
+	
+	<bean id="wfNodeFindDateRangeForIncrementalHarvesting" 
+		class="eu.dnetlib.msro.workflows.nodes.collect.FindDateRangeForIncrementalHarvestingJobNode" 
+		scope="prototype"/>
+	
+	<bean id="wfNodeMdBuilder"
+		class="eu.dnetlib.msro.workflows.nodes.transform.MdBuilderJobNode"
+		p:xsltMappedResultSetFactory-ref="xsltResultSetFactory"
+		p:mdBuilderTemplateXslt="${msro.wf.nodes.mdbuilder.xslt.template}"
+		scope="prototype" />
+
+	<!-- Transform -->
+	<bean id="wfNodeTransform"
+		class="eu.dnetlib.msro.workflows.nodes.transform.TransformJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeApplyXslt"
+		class="eu.dnetlib.msro.workflows.nodes.transform.ApplyXsltJobNode"
+		p:xsltMappedResultSetFactory-ref="xsltResultSetFactory"
+		scope="prototype" />	
+		
+	<bean id="wfNodeGroovy"
+		class="eu.dnetlib.msro.workflows.nodes.transform.GroovyJobNode"
+		p:mappedResultSetFactory-ref="xsltResultSetFactory"
+		scope="prototype" />
+	
+		
+	<bean id="wfNodeClean"
+		class="eu.dnetlib.msro.workflows.nodes.transform.CleanJobNode"
+		scope="prototype" />		
+	
+	<!-- Index -->
+	<bean id="wfNodeUpdateIndex" class="eu.dnetlib.msro.workflows.nodes.index.UpdateIndexJobNode"
+		scope="prototype" 
+		p:layoutToRecordStylesheet="classpath:/eu/dnetlib/msro/workflows/xslt/layoutToRecordStylesheet.xsl"
+		p:xsltRSFactory-ref="xsltResultSetFactory"
+		p:processCountingResultSetFactory-ref="msroProcessCountingResultSetFactory"
+		p:defaultIndexId="${service.msro.index.defaultIndex}"  />
+
+	<bean id="wfNodeCreateIndex" class="eu.dnetlib.msro.workflows.nodes.index.CreateIndexJobNode"
+		scope="prototype" p:defaultBackendId="${service.msro.index.defaultIndex}" />
+		
+	<bean id="wfNodeDeleteIndex" class="eu.dnetlib.msro.workflows.nodes.index.DeleteIndexJobNode"
+		scope="prototype" p:defaultIndexId="${service.msro.index.defaultIndex}" />	
+		
+	<bean id="wfNodePrepareCreateIndex"
+		class="eu.dnetlib.msro.workflows.nodes.index.PrepareCreateIndexJobNode"
+		scope="prototype" />
+	
+	<!-- Database -->
+	<bean id="wfNodeUpdateDb" class="eu.dnetlib.msro.workflows.nodes.db.UpdateDbJobNode"
+		scope="prototype" p:processCountingResultSetFactory-ref="msroProcessCountingResultSetFactory" />
+
+	<bean id="wfNodeQueryDb" class="eu.dnetlib.msro.workflows.nodes.db.QueryDbJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeExecuteSql" class="eu.dnetlib.msro.workflows.nodes.db.ExecuteSqlJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeExecuteSqlFromEnv" class="eu.dnetlib.msro.workflows.nodes.db.ExecuteSqlFromEnvJobNode"
+	      scope="prototype"/>
+
+	<!-- MDStore -->
+	<bean id="wfNodeCreateMDStore"
+		class="eu.dnetlib.msro.workflows.nodes.repohi.CreateMDStoreJobNode"
+		scope="prototype" />
+
+	<bean id="wfNodeStoreMDStoreRecords"
+		class="eu.dnetlib.msro.workflows.nodes.mdstore.StoreMDStoreRecordsJobNode"
+		scope="prototype" p:processCountingResultSetFactory-ref="msroProcessCountingResultSetFactory" />
+
+	<bean id="wfNodeFetchMDStoreRecords"
+		class="eu.dnetlib.msro.workflows.nodes.mdstore.FetchMDStoreRecordsJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeFetchMultipleMDStoreRecords"
+		class="eu.dnetlib.msro.workflows.nodes.mdstore.FetchMultipleMDStores"
+		scope="prototype" />
+
+	<bean id="wfNodeMDStoreToApiExtraField"
+		class="eu.dnetlib.msro.workflows.nodes.info.MDStoreToApiExtraFieldJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeObjectStoreToApiExtraField"
+		class="eu.dnetlib.msro.workflows.nodes.info.ObjectStoreToApiExtraFieldJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeRemoveApiExtraFields"
+		class="eu.dnetlib.msro.workflows.nodes.info.RemoveApiExtraFieldsJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeSetFormatInfo"
+		class="eu.dnetlib.msro.workflows.nodes.SetFormatInfoJobNode"
+		scope="prototype" />
+		
+	<bean id="wfNodeSetEnvParameter"
+		class="eu.dnetlib.msro.workflows.nodes.SetEnvParameterJobNode"
+		scope="prototype" />
+		
+</beans>
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow_status.xml.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow_status.xml.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/templates/workflow_status.xml.st	(revision 49538)
@@ -0,0 +1,12 @@
+<STATUS>
+	<LAST_EXECUTION_ID>$procId$</LAST_EXECUTION_ID>
+	<LAST_EXECUTION_DATE>$date$</LAST_EXECUTION_DATE>
+	$if(error)$
+		<LAST_EXECUTION_STATUS>FAILURE</LAST_EXECUTION_STATUS>
+		<LAST_EXECUTION_ERROR>$error$</LAST_EXECUTION_ERROR>
+	$else$
+		<LAST_EXECUTION_STATUS>SUCCESS</LAST_EXECUTION_STATUS>
+		<LAST_EXECUTION_ERROR />
+	$endif$
+	$params.keys:{k|<LAST_EXECUTION_OUTPUT name='$k$'>$params.(k)$</LAST_EXECUTION_OUTPUT>}$
+</STATUS>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_failed.mail.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_failed.mail.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_failed.mail.st	(revision 49538)
@@ -0,0 +1,30 @@
+<div>
+	<p>**** This mail has been generated automatically by D-NET Manager Service, please don't reply ****</p>
+	<h3>Infrastructure: $infrastructure$ </h3>
+	<p>Workflow: <b>$wfName$</b></p>
+	<p>Status: <b>FAILURE</b></p>
+	<p>
+		Error message: <i>$error$</i><br /><br />
+		You can relaunch it clicking <a href="$baseUrl$/workflows.do?wfId=$wfId$">HERE</a>
+	</p>
+	
+	<hr />
+	
+	<p>
+		<b>Workflow details:</b><br /><br />
+		<table>
+			<tr><td>Process ID: </td><td><a href="$baseUrl$/workflow_journal.do?procId=$procId$">$procId$</a></td></tr>
+			$if(responses)$
+				$responses.keys:{k|<tr><td>$k$: </td><td><i>$responses.(k)$</i></td></tr>}$
+			$endif$
+		</table>
+	</p>
+	<hr />
+	
+	$if(pendingWfs)$
+		<p>
+			If it's OK, you can launch manually its dependencies:
+			<ul>$pendingWfs.keys:{k|<li><a href="$baseUrl$/workflows.do?wfId=$k$">$pendingWfs.(k)$</a></li>}$</ul>
+		</p>
+	$endif$
+</div>
Index: modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/enabling/resultset/ResultSetClientTest.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/enabling/resultset/ResultSetClientTest.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/enabling/resultset/ResultSetClientTest.java	(revision 49538)
@@ -0,0 +1,60 @@
+package eu.dnetlib.enabling.resultset;
+
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+
+import eu.dnetlib.data.mdstore.MDStoreService;
+import eu.dnetlib.data.mdstore.MDStoreServiceException;
+import eu.dnetlib.enabling.resultset.client.IterableResultSetClient;
+import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
+import eu.dnetlib.enabling.tools.ServiceResolver;
+import junit.framework.Assert;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * Created by claudio on 15/11/2016.
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "/eu/dnetlib/enabling/resultset/applicationContext-test-locators.xml"})
+public class ResultSetClientTest {
+
+	private static final Log log = LogFactory.getLog(ResultSetClientTest.class);
+	public static final String MDID = "9f6d4071-ffa5-407d-a3d6-8eba1aa12cbc_TURTdG9yZURTUmVzb3VyY2VzL01EU3RvcmVEU1Jlc291cmNlVHlwZQ==";
+
+	private ResultSetClientFactory rsClientFactory;
+
+	@Autowired
+	private MDStoreService mdStoreService;
+
+	@Autowired
+	private ServiceResolver serviceResolver;
+
+	@Before
+	public void setUp() {
+		rsClientFactory = new ResultSetClientFactory();
+		rsClientFactory.setTimeout(12000);
+		rsClientFactory.setConnectTimeout(5000);
+		rsClientFactory.setServiceResolver(serviceResolver);
+	}
+
+	@Ignore
+	@Test
+	public void testMDStore() throws MDStoreServiceException {
+
+		final W3CEndpointReference epr = mdStoreService.deliverMDRecords(MDID, null, null, null);
+		final IterableResultSetClient client = rsClientFactory.getClient(epr);
+
+		for(String xml : client) {
+			Assert.assertTrue(StringUtils.isNotBlank(xml));
+		}
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/AppTest.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/AppTest.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/AppTest.java	(revision 49538)
@@ -0,0 +1,90 @@
+package eu.dnetlib;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.io.SAXReader;
+import org.junit.Test;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest {
+
+	@Test
+	public void testXslt() {
+		String res = new ApplyXslt(getXslt()).evaluate(getXml());
+		System.out.println("******************");
+		System.out.println(res);
+		System.out.println("******************");
+	}
+
+	@Test
+	public void testXpath() throws DocumentException {
+		SAXReader reader = new SAXReader();
+		Document doc = reader.read(new StringReader("<a><b>test</b></a>"));
+		assertEquals("", doc.valueOf("//c"));
+		assertEquals("test", doc.valueOf("//b"));
+	}
+
+	public static String javaMethod(final NodeList list) {
+		System.out.println("******************");
+		System.out.println("TYPE   : " + list.toString());
+		System.out.println("LENGTH : " + list.getLength());
+		for (int i = 0; i < list.getLength(); i++) {
+			Node node = list.item(i);
+
+			System.out.println("ELEM " + i + ": " + node.getLocalName());
+		}
+
+		System.out.println("******************");
+		return "ACUS";
+	}
+
+	private String getXml() {
+		final StringWriter sw = new StringWriter();
+		sw.append("<?xml version='1.0' encoding='UTF-8'?>\n");
+		sw.append("<record>\n");
+		sw.append("<metadata>\n");
+		sw.append("<a>A text value</a>\n");
+		sw.append("<b attr='attribute value'/>\n");
+		sw.append("</metadata>\n");
+		sw.append("</record>\n");
+
+		return sw.toString();
+	}
+
+	private String getXslt() {
+		final StringWriter sw = new StringWriter();
+
+		sw.append("<?xml version='1.0' encoding='UTF-8'?>\n");
+		sw.append("<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:dnet='eu.dnetlib.AppTest' exclude-result-prefixes='xsl dnet'>\n");
+		sw.append("<xsl:output omit-xml-declaration='yes' indent='yes'/>\n");
+		sw.append("<xsl:template match='/*'>\n");
+		sw.append("<xsl:variable name='metadata' select=\"//*[local-name()='metadata']/*\" />\n");
+		sw.append("<ROWS>\n");
+		sw.append("<xsl:value-of select='dnet:javaMethod($metadata)'/>\n");
+		sw.append("</ROWS>\n");
+		sw.append("</xsl:template>\n");
+		sw.append("</xsl:stylesheet>\n");
+		return sw.toString();
+	}
+
+	@Test
+	public void encodetest() throws UnsupportedEncodingException {
+		String theUrl = "http://europepmc.org/GrantLookup/grants.php?&f%5B%5D=WT&range=all&format=xml&output=export";
+		String encoded = URLEncoder.encode(theUrl, "UTF-8");
+		System.out.println(encoded);
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/resources/log4j.properties
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/resources/log4j.properties	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/resources/log4j.properties	(revision 49538)
@@ -0,0 +1,21 @@
+### Root Level ###
+log4j.rootLogger=WARN, CONSOLE
+
+### Configuration for the CONSOLE appender ###
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d %c - %m%n
+
+org.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger
+
+
+org.apache.cxf.Logger=org.apache.cxf.common.logging.Log4jLogger
+
+### Application Level ###
+log4j.logger.eu.dnetlib=INFO
+eu.dnetlib.enabling.resultset.ResultSetClientTest=DEBUG
+
+### Spring ###
+log4j.logger.org.springframework=ERROR
+
+
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/mdBuilder.xslt.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/mdBuilder.xslt.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/workflows/xslt/mdBuilder.xslt.st	(revision 49538)
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+    xmlns:datetime="http://exslt.org/dates-and-times" xmlns:exslt="http://exslt.org/common"
+    xmlns:oai="http://www.openarchives.org/OAI/2.0/"
+    xmlns:dnet="eu.dnetlib.miscutils.functional.xml.DnetXsltFunctions"
+    xmlns:dri="http://www.driver-repository.eu/namespace/dri"
+    exclude-result-prefixes="xsl datetime exslt dnet">
+    
+    <xsl:variable name="status" select="/*[local-name() = 'record']/*[local-name() = 'header']/@status" />
+    
+    <xsl:template match="/">
+        <oai:record xmlns:oai="http://www.openarchives.org/OAI/2.0/"
+            xmlns:dri="http://www.driver-repository.eu/namespace/dri"
+            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+            
+            <xsl:variable name="datestamp" select="datetime:dateTime()" />
+            <xsl:variable name="evaluatedMetadataId" select="normalize-space($xpath$)" />
+            
+			<!-- Patch OAI header or create ex-novo if not oai -->
+            <oai:header>
+                <xsl:if test="\$status">
+                    <xsl:attribute name="status" >
+                        <xsl:value-of select="\$status"/>
+                    </xsl:attribute>
+                </xsl:if>
+                <xsl:if test="not(.//dri:objIdentifier)">
+                	<xsl:if test="\$evaluatedMetadataId != ''">
+	                    <dri:objIdentifier><xsl:value-of select="concat('$namespacePrefix$::', dnet:md5(\$evaluatedMetadataId))"/></dri:objIdentifier>
+                	</xsl:if>
+                </xsl:if>
+                <xsl:if test="not(.//dri:recordIdentifier)">
+                    <dri:recordIdentifier><xsl:value-of select="\$evaluatedMetadataId"/></dri:recordIdentifier>
+                </xsl:if>
+                <xsl:if test="not(.//dri:dateOfCollection)">
+                    <dri:dateOfCollection><xsl:value-of select="\$datestamp"/></dri:dateOfCollection>
+                </xsl:if>
+				<xsl:if test="not(.//dri:repositoryId)">
+                    <dri:repositoryId>$datasourceId$</dri:repositoryId>
+                </xsl:if>
+                <xsl:if test="not(.//dri:datasourceprefix)">
+                    <dri:datasourceprefix>$namespacePrefix$</dri:datasourceprefix>
+                </xsl:if>
+                
+				<!-- Bulk copy of old header -->
+                <xsl:for-each select="/*[local-name() = 'record']/*[local-name() = 'header']/*">
+                    <xsl:copy-of select="."/>
+                </xsl:for-each>
+            </oai:header>
+            
+			<!-- Handle metadata block -->
+            <xsl:choose>
+            	<!-- If OAI then copy copy the metadata block along -->
+                <xsl:when test="count(/*[local-name() = 'record']/*[local-name() = 'metadata']) &gt; 0">
+                    <xsl:copy-of select="/*[local-name() = 'record']/*[local-name() = 'metadata']"/>
+                </xsl:when>
+                <!-- If OAI copy in bulk the metadata block -->
+                <xsl:when test="\$status = 'deleted'" />
+                <!-- If not-OAI copy ALL the record inside metadata block -->
+                <xsl:otherwise>
+                    <oai:metadata>
+                        <xsl:copy-of select="."/>
+                    </oai:metadata>
+                </xsl:otherwise>
+            </xsl:choose>
+            
+            <!-- Handle oai:about block -->
+            <oai:about>
+                <provenance xmlns="http://www.openarchives.org/OAI/2.0/provenance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/provenance http://www.openarchives.org/OAI/2.0/provenance.xsd">
+  					<originDescription harvestDate="{\$datestamp}" altered="true">
+	    				<baseURL>$baseurl$</baseURL>
+	    				<identifier><xsl:value-of select="//*[local-name()='header']/*[local-name()='identifier']"/></identifier>
+	    				<datestamp><xsl:value-of select="//*[local-name()='header']/*[local-name()='datestamp']"/></datestamp>
+	    				<metadataNamespace>$metadatanamespace$</metadataNamespace>
+	    				<xsl:copy-of select="//*[local-name()='provenance']/*[local-name() = 'originDescription']"/>
+  					</originDescription>
+				</provenance>
+			</oai:about>
+        </oai:record>
+    </xsl:template>
+    
+</xsl:stylesheet>
Index: modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_success.mail.st
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_success.mail.st	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/main/resources/eu/dnetlib/msro/mail/wf_success.mail.st	(revision 49538)
@@ -0,0 +1,25 @@
+<div>
+	<p>**** This mail has been generated automatically by D-NET Manager Service, please don't reply ****</p>
+	<h3>Infrastructure: $infrastructure$ </h3>
+	<p>Workflow: <b>$wfName$</b></p>
+	<p>Status: <b>SUCCESS</b></p>
+	
+	<p>
+		<b>Workflow details:</b><br /><br />
+		<table>
+			<tr><td>Process ID: </td><td><a href="$baseUrl$/workflow_journal.do?procId=$procId$">$procId$</a></td></tr>
+			$if(responses)$
+				$responses.keys:{k|<tr><td>$k$: </td><td><i>$responses.(k)$</i></td></tr>}$
+			$endif$
+		</table>
+	</p>
+	<hr />
+	
+	$if(pendingWfs)$
+		<p>
+			These dependency workflows need to be launched manually:
+			<ul>$pendingWfs.keys:{k|<li><a href="$baseUrl$/workflows.do?wfId=$k$">$pendingWfs.(k)$</a></li>}$</ul>
+			Please launch them if necessary!!!
+		</p>
+	$endif$
+</div>
\ No newline at end of file
Index: modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncherTest.java
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncherTest.java	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/java/eu/dnetlib/msro/cron/ScheduledWorkflowLauncherTest.java	(revision 49538)
@@ -0,0 +1,43 @@
+package eu.dnetlib.msro.cron;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+
+import org.junit.Test;
+
+import eu.dnetlib.miscutils.datetime.DateUtils;
+
+public class ScheduledWorkflowLauncherTest {
+
+	private ScheduledWorkflowLauncher launcher = new ScheduledWorkflowLauncher();
+
+	private static final String WF_ID = "wf-1234567890";
+	private static final String CRON_EXPR = "0 15 9 ? * SAT";
+	private static final int ALMOST_TWO_WEEKS = 20000;
+
+	private static final DateUtils dateUtils = new DateUtils();
+	private static final Date date = dateUtils.parse("2016-10-29T09:16:00+02:00"); // Saturday
+	private static final Date oneDayBefore = dateUtils.parse("2016-10-28T09:16:00+02:00");
+	private static final Date oneWeekBefore = dateUtils.parse("2016-10-22T09:16:00+02:00");
+	private static final Date twoWeekBefore = dateUtils.parse("2016-10-15T09:16:00+02:00");
+	private static final Date tenMinutesAfter = dateUtils.parse("2016-10-29T09:26:00+02:00");
+	private static final Date oneHourAfter = dateUtils.parse("2016-10-29T10:16:00+02:00");
+
+	@Test
+	public void testVerifyScheduled() {
+		assertTrue(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, null, date));
+		assertTrue(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, twoWeekBefore, date));
+		assertTrue(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, null, tenMinutesAfter));
+		assertTrue(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, twoWeekBefore, tenMinutesAfter));
+
+		assertFalse(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, null, oneDayBefore));
+		assertFalse(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, oneDayBefore, date));
+		assertFalse(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, oneWeekBefore, date));
+
+		assertFalse(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, null, oneHourAfter));
+		assertFalse(launcher.isReady(WF_ID, CRON_EXPR, ALMOST_TWO_WEEKS, twoWeekBefore, oneHourAfter));
+	}
+
+}
Index: modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/enabling/resultset/applicationContext-test-locators.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/enabling/resultset/applicationContext-test-locators.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/src/test/resources/eu/dnetlib/enabling/resultset/applicationContext-test-locators.xml	(revision 49538)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
+	xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:wsa="http://cxf.apache.org/ws/addressing"
+	xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://cxf.apache.org/transports/http/configuration"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+                        http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
+                        http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
+                        http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
+                        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
+
+	<!-- common service resolution chain -->
+	<bean id="serviceResolver" class="eu.dnetlib.enabling.tools.ServiceResolverChain">
+		<property name="resolvers">
+			<list>
+				<bean id="jaxwsServiceResolver" class="eu.dnetlib.enabling.tools.JaxwsServiceResolverImpl" />
+			</list>
+		</property>
+	</bean>
+
+	<bean id="jobScheduler"
+		class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
+		destroy-method="destroy">
+		<property name="jobFactory">
+			<bean id="jobSchedulerFactory"
+				class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
+		</property>
+	</bean>
+
+	<jaxws:client id="mdStoreService"
+	              serviceClass="eu.dnetlib.data.mdstore.MDStoreService"
+	              address="http://localhost:8280/app/services/mdStore" />
+
+	<bean id="uuidGenerator" class="eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl" />
+
+	<alias name="cxfEndpointReferenceBuilder" alias="eprBuilder" />
+
+
+
+
+</beans>
Index: modules/dnet-msro-service/branches/dsm/pom.xml
===================================================================
--- modules/dnet-msro-service/branches/dsm/pom.xml	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm/pom.xml	(revision 49538)
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>eu.dnetlib</groupId>
+		<artifactId>dnet45-parent</artifactId>
+		<version>1.0.0</version>
+		<relativePath />
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>eu.dnetlib</groupId>
+	<artifactId>dnet-msro-service</artifactId>
+	<packaging>jar</packaging>
+	<version>3.1.24-SNAPSHOT</version>
+	<scm>
+		<developerConnection>scm:svn:https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-msro-service/trunk</developerConnection>
+	</scm>
+	<dependencies>
+		<dependency>
+			<groupId>org.quartz-scheduler</groupId>
+			<artifactId>quartz</artifactId>
+			<version>${quartz.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-msro-service-api</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-resultset-service</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-data-utility-cleaner-rmi</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-resultset-client</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-download-service-rmi</artifactId>
+			<version>[1.1.0,2.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-datasource-manager-common</artifactId>
+			<version>[4.0.0,5.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-blackboard-common</artifactId>
+			<version>[2.1.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-mongo-logging</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>com.googlecode</groupId>
+			<artifactId>sarasvati</artifactId>
+			<version>1.0.3</version>
+		</dependency>
+		<dependency>
+			<groupId>com.googlecode</groupId>
+			<artifactId>sarasvati-visual</artifactId>
+			<version>1.0.3</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-modular-collector-service-rmi</artifactId>
+			<version>[1.3.0,2.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-enabling-database-api</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-objectstore-rmi</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-data-transformation-service-rmi</artifactId>
+			<version>[1.0.0,2.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-data-provision-rmi</artifactId>
+			<version>[1.0.0,2.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-runtime</artifactId>
+			<version>[1.0.0,2.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.mail</groupId>
+			<artifactId>mail</artifactId>
+			<version>1.4</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.codehaus.groovy</groupId>
+			<artifactId>groovy</artifactId>
+			<version>2.1.6</version>
+			<exclusions>
+				<exclusion>
+					<artifactId>antlr</artifactId>
+					<groupId>antlr</groupId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>${junit.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>joda-time</groupId>
+			<artifactId>joda-time</artifactId>
+			<version>2.3</version>
+		</dependency>
+	</dependencies>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+</project>
Index: modules/dnet-msro-service/branches/dsm
===================================================================
--- modules/dnet-msro-service/branches/dsm	(nonexistent)
+++ modules/dnet-msro-service/branches/dsm	(revision 49538)

Property changes on: modules/dnet-msro-service/branches/dsm
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,5 ##
+target
+.settings
+.classpath
+.project
+*.iml
