Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/pom.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/pom.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/pom.xml	(revision 1843)
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+	<groupId>clarin.cmdi</groupId>
+	<artifactId>componentRegistry.parent</artifactId>
+	<version>1.0</version>
+    </parent>
+    <groupId>clarin.cmdi</groupId>
+    <artifactId>cmd-validate</artifactId>
+    <version>1.0</version>
+    <name>CMDValidate</name>
+    <build>
+	<plugins>
+	    <plugin>
+		<groupId>org.apache.maven.plugins</groupId>
+		<artifactId>maven-compiler-plugin</artifactId>
+		<version>2.3.2</version>
+		<configuration>
+		    <source>1.6</source>
+		    <target>1.6</target>
+		</configuration>
+	    </plugin>
+	    <plugin>
+		<groupId>org.codehaus.mojo</groupId>
+		<artifactId>exec-maven-plugin</artifactId>
+		<version>1.2.1</version>
+		<executions>
+		    <execution>
+			<goals>
+			    <goal>java</goal>
+			</goals>
+		    </execution>
+		</executions>
+		<configuration>
+		    <mainClass>clarin.cmdi.schema.cmd.Validator</mainClass>
+		</configuration>
+	    </plugin>
+	</plugins>
+    </build>
+    <dependencies>
+	<dependency>
+	    <groupId>junit</groupId>
+	    <artifactId>junit</artifactId>
+	    <version>4.10</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>net.sf.saxon</groupId>
+	    <artifactId>Saxon-HE</artifactId>
+	    <version>9.4</version>
+	</dependency>
+    </dependencies>
+    <properties>
+	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <repositories>
+	<repository>
+	    <id>sonatype</id>
+	    <url>https://oss.sonatype.org/content/groups/public</url>
+	</repository>
+    </repositories>
+    <distributionManagement>
+	<snapshotRepository>
+	    <id>MPI-Snapshots</id>
+	    <url>http://lux15.mpi.nl/nexus/content/repositories/MPI-Snapshots</url>
+	</snapshotRepository>
+    </distributionManagement>
+</project>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/Validator.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/Validator.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/Validator.java	(revision 1843)
@@ -0,0 +1,436 @@
+package clarin.cmdi.schema.cmd;
+
+import clarin.cmdi.xml.Saxon;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import net.sf.saxon.s9api.DOMDestination;
+import net.sf.saxon.s9api.QName;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XdmDestination;
+import net.sf.saxon.s9api.XdmItem;
+import net.sf.saxon.s9api.XdmNode;
+import net.sf.saxon.s9api.XsltExecutable;
+import net.sf.saxon.s9api.XsltTransformer;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * The Validator class handles the XSD and Schematron validation of CMD profile and component specifications.
+ *
+ * The class caches thread safe versions of the XSD Schema and the Schematron XSLT.
+ * So multiple instances of this Validator class can be used in parallel and use the same cached schema and transformer.
+ * Although a single instance of the Validator class can't be accessed in parallel it can be used to validate multiple CMD
+ * profiles/components in sequence.
+ *
+ * @author menwin
+ * @author twagoo
+ */
+public class Validator {
+
+    /**
+     * Default location of the CMD schema
+     */
+    static final String CMD_SCHEMA_URL = "http://www.clarin.eu/cmd/general-component-schema.xsd";
+    /**
+     * The immutable location of the CMD schema that is used in this instance
+     */
+    private final URL cmdSchemaUri;
+    /**
+     * The "immutable, and therefore thread-safe," "compiled form of [the Schematron] stylesheet".
+     */
+    private XsltExecutable cmdSchematron = null;
+    /**
+     * The "immutable in-memory representation of [the XSD] grammar".
+     */
+    private Schema cmdSchema = null;
+    /**
+     * The list of validation messages compiled a the last run of the validator.
+     */
+    private List<Message> msgList = null;
+    /**
+     * The Schematron SVRL validation report
+     */
+    private XdmNode validationReport = null;
+
+    /**
+     * Creates a Validator that uses a specific schema specified by its URL
+     *
+     * @param cmdSchemaUri Schema URI to use
+     * @see #CMD_SCHEMA_URL
+     */
+    public Validator(URL cmdSchemaUri) {
+	this.cmdSchemaUri = cmdSchemaUri;
+    }
+
+    /**
+     * Convenience method to build a XSLT transformer from a resource.
+     *
+     * @param uri The location of the resource
+     * @return An executable XSLT
+     * @throws Exception
+     */
+    static XsltExecutable buildTransformer(File file) throws ValidatorException {
+	try {
+	    XdmNode xslDoc = Saxon.buildDocument(new javax.xml.transform.stream.StreamSource(file));
+	    return Saxon.buildTransformer(xslDoc);
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	}
+    }
+
+    /**
+     * Convenience method to build a XSLT transformer from a resource.
+     *
+     * @param uri The location of the resource
+     * @return An executable XSLT
+     * @throws Exception
+     */
+    static XsltExecutable buildTransformer(URL url) throws ValidatorException {
+	try {
+	    XdmNode xslDoc = Saxon.buildDocument(new javax.xml.transform.stream.StreamSource(url.toExternalForm()));
+	    return Saxon.buildTransformer(xslDoc);
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	}
+
+    }
+
+    /**
+     * Convenience method to build a XSLT transformer from a resource.
+     *
+     * @param uri The location of the resource
+     * @return An executable XSLT
+     * @throws Exception
+     */
+    static XsltExecutable buildTransformer(InputStream stream) throws ValidatorException {
+	try {
+	    XdmNode xslDoc = Saxon.buildDocument(new javax.xml.transform.stream.StreamSource(stream));
+	    return Saxon.buildTransformer(xslDoc);
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	}
+
+    }
+
+    /**
+     * Returns the CMD XSD schema, and loads it just-in-time.
+     *
+     * @return An in-memory representation of the grammar
+     * @throws Exception
+     */
+    private synchronized Schema getSchema() throws ValidatorException, IOException {
+	if (cmdSchema == null) {
+	    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+
+	    // Load the CMD XSD.
+	    Source schemaFile = new StreamSource(cmdSchemaUri.openStream());
+	    try {
+		cmdSchema = factory.newSchema(schemaFile);
+	    } catch (SAXException ex) {
+		throw new ValidatorException(ex);
+	    }
+	}
+	return cmdSchema;
+    }
+
+    /**
+     * Validation of a loaded CMD profile/component against the XSD schema.
+     *
+     * Unfortunately we can't use the Saxon XSD validator as that is limited to a commercial version of Saxon.
+     *
+     * @param src The loaded CMD profile/component
+     * @return Is the CMD profile/component valid or not?
+     * @throws Exception
+     */
+    public boolean validateXSD(XdmNode src) throws ValidatorException, IOException {
+	try {
+	    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+	    DOMDestination dst = new DOMDestination(doc);
+	    Saxon.getProcessor().writeXdmValue(src, dst);
+
+	    try {
+		// Create a Validator object, which can be used to validate
+		// an instance document.
+		javax.xml.validation.Validator validator = getSchema().newValidator();
+
+		// Validate the DOM tree.
+		validator.validate(new DOMSource(doc));
+
+	    } catch (SAXException e) {
+		Message msg = new Message();
+		msg.error = true;
+		msg.text = e.getMessage();
+		msgList.add(msg);
+		return false;
+	    }
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	} catch (ParserConfigurationException ex) {
+	    throw new ValidatorException(ex);
+	}
+
+	return true;
+    }
+
+    /**
+     * Returns the CMD Schematron XSLT, and loads it just-in-time.
+     *
+     * @return The compiled Schematron XSLT
+     * @throws Exception
+     */
+    private synchronized XsltExecutable getSchematron() throws ValidatorException, IOException {
+	if (cmdSchematron == null) {
+	    try {
+		// Load the schema
+		XdmNode schema = Saxon.buildDocument(new javax.xml.transform.stream.StreamSource(cmdSchemaUri.openStream()));
+		// Load the Schematron XSL to extract the Schematron rules;
+		XsltTransformer extractSchXsl = buildTransformer(Validator.class.getResource("/schematron/ExtractSchFromXSD-2.xsl")).load();
+		// Load the Schematron XSLs to 'compile' Schematron rules;
+		XsltTransformer includeSchXsl = buildTransformer(Validator.class.getResource("/schematron/iso_dsdl_include.xsl")).load();
+		XsltTransformer expandSchXsl = buildTransformer(Validator.class.getResource("/schematron/iso_abstract_expand.xsl")).load();
+		XsltTransformer compileSchXsl = buildTransformer(Validator.class.getResource("/schematron/iso_svrl_for_xslt2.xsl")).load();
+		// Setup the pipeline
+		XdmDestination destination = new XdmDestination();
+		extractSchXsl.setSource(schema.asSource());
+		extractSchXsl.setDestination(includeSchXsl);
+		includeSchXsl.setDestination(expandSchXsl);
+		expandSchXsl.setDestination(compileSchXsl);
+		compileSchXsl.setDestination(destination);
+		// Extract the Schematron rules from the schema        
+		extractSchXsl.transform();
+		// Compile the Schematron rules XSL
+		cmdSchematron = Saxon.buildTransformer(destination.getXdmNode());
+	    } catch (SaxonApiException ex) {
+		throw new ValidatorException(ex);
+	    }
+	}
+	return cmdSchematron;
+    }
+
+    /**
+     * Validation of a loaded CMD profile/component against the Schematron XSLT
+     *
+     * @param src The loaded CMD profile/component
+     * @return Is the CMD profile/component valid or not?
+     * @throws Exception
+     */
+    public boolean validateSchematron(XdmNode src) throws ValidatorException, IOException {
+	try {
+	    XsltTransformer schematronXsl = getSchematron().load();
+	    schematronXsl.setSource(src.asSource());
+	    XdmDestination destination = new XdmDestination();
+	    schematronXsl.setDestination(destination);
+	    schematronXsl.transform();
+
+	    validationReport = destination.getXdmNode();
+
+	    Saxon.declareXPathNamespace("svrl", "http://purl.oclc.org/dsdl/svrl");
+	    return ((net.sf.saxon.value.BooleanValue) Saxon.evaluateXPath(validationReport, "empty(//svrl:failed-assert[(preceding-sibling::svrl:fired-rule)[last()][empty(@role) or @role!='warning']])").evaluateSingle().getUnderlyingValue()).getBooleanValue();
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	}
+    }
+
+    /**
+     * Validation of a loaded CMD profile/component against both the XSD and the Schematron XSLT
+     *
+     * After validation any messages can be accessed using the {@link getMessages()} method.
+     * Notice that even if a CMD profile/component is valid there might be warning messages.
+     *
+     * @param prof The CMD profile/component
+     * @return Is the CMD profile/component valid or not?
+     * @throws Exception
+     */
+    public boolean validateProfile(Source prof) throws ValidatorException, IOException {
+	// Initalize
+	msgList = new java.util.ArrayList<Message>();
+	validationReport = null;
+
+	try {
+	    // load the document
+	    XdmNode doc = Saxon.buildDocument(prof);
+
+	    // step 1: validate against XML Schema
+	    if (!this.validateXSD(doc)) {
+		return false;
+	    }
+
+	    // step 2: validate Schematron rules
+	    return validateSchematron(doc);
+	} catch (SaxonApiException ex) {
+	    throw new ValidatorException(ex);
+	}
+
+    }
+
+    /**
+     * Get the list of messages accumulated in the last validation run.
+     *
+     * @return The list of messages
+     * @throws Exception
+     */
+    public List<Message> getMessages() throws ValidatorException {
+	if (validationReport != null) {
+	    try {
+		for (XdmItem assertion : Saxon.evaluateXPath(validationReport, "//svrl:failed-assert")) {
+		    Message msg = new Message();
+		    msg.context = Saxon.evaluateXPath(assertion, "(preceding-sibling::svrl:fired-rule)[last()]/@context").evaluateSingle().getStringValue();
+		    msg.test = ((XdmNode) assertion).getAttributeValue(new QName("test"));
+		    msg.location = ((XdmNode) assertion).getAttributeValue(new QName("location"));
+		    msg.error = !((net.sf.saxon.value.BooleanValue) Saxon.evaluateXPath(assertion, "(preceding-sibling::svrl:fired-rule)[last()]/@role='warning'").evaluateSingle().getUnderlyingValue()).getBooleanValue();
+		    msg.text = assertion.getStringValue();
+		    msgList.add(msg);
+		}
+		validationReport = null;
+	    } catch (SaxonApiException ex) {
+		throw new ValidatorException(ex);
+	    }
+	}
+	return msgList;
+    }
+
+    /**
+     * Print the list of messages accumulated in the last validation run.
+     *
+     * @param out
+     * @throws Exception
+     */
+    public void printMessages(java.io.PrintStream out) throws Exception {
+	for (Message msg : getMessages()) {
+	    out.println("" + (msg.isError() ? "ERROR" : "WARNING") + (msg.getLocation() != null ? " at " + msg.getLocation() : ""));
+	    out.println("  " + msg.getText());
+	}
+    }
+
+    /**
+     * @param args One or more CMD profile/component files to validate.
+     */
+    public static void main(String[] args) {
+	try {
+
+	    URL schemaURL = null;
+
+	    int startArg = 0;
+	    if (args.length > 0) {
+		if ("-s".equals(args[0].trim())) {
+		    if (args.length > 1) {
+			String schemaArg = args[1];
+			System.err.println("Using schema URL" + schemaArg);
+			schemaURL = new URL(schemaArg);
+			startArg = 2;
+		    } else {
+			printUsage(args);
+			return;
+		    }
+		}
+	    } else {
+		printUsage(args);
+		return;
+	    }
+
+	    if (schemaURL == null) {
+		schemaURL = new URL(CMD_SCHEMA_URL);
+	    }
+
+	    final Validator cmdValidator = new Validator(schemaURL);
+
+	    for (int i = startArg; i < args.length; i++) {
+		String f = args[i];
+		System.out.print("CMD validate[" + f + "] ");
+		try {
+		    Source src = new javax.xml.transform.stream.StreamSource(new java.io.File(f));
+		    if (cmdValidator.validateProfile(src)) {
+			System.out.println("valid");
+		    } else {
+			System.out.println("invalid");
+		    }
+		    cmdValidator.printMessages(System.out);
+		} catch (Exception e) {
+		    System.err.println("failed:");
+		    e.printStackTrace(System.out);
+		}
+	    }
+	} catch (MalformedURLException e) {
+	    System.err.println("failed:");
+	    e.printStackTrace(System.out);
+	}
+    }
+
+    private static void printUsage(String[] args) {
+	System.err.println("Arguments: [-s schemafileURL] files...");
+    }
+
+    /**
+     * Public inner class to represent validation messages.
+     */
+    public final static class Message {
+
+	/**
+	 * Is the message and error or an warning?
+	 */
+	boolean error = false;
+	/**
+	 * The context of the message (might be null).
+	 */
+	String context = null;
+	/**
+	 * The test that triggered the message (might be null).
+	 */
+	String test = null;
+	/**
+	 * The location that triggered the test (might be null).
+	 */
+	String location = null;
+	/**
+	 * The actual message.
+	 */
+	String text = null;
+
+	/**
+	 * @return the error
+	 */
+	public boolean isError() {
+	    return error;
+	}
+
+	/**
+	 * @return the context
+	 */
+	public String getContext() {
+	    return context;
+	}
+
+	/**
+	 * @return the test
+	 */
+	public String getTest() {
+	    return test;
+	}
+
+	/**
+	 * @return the location
+	 */
+	public String getLocation() {
+	    return location;
+	}
+
+	/**
+	 * @return the text
+	 */
+	public String getText() {
+	    return text;
+	}
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/ValidatorException.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/ValidatorException.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/schema/cmd/ValidatorException.java	(revision 1843)
@@ -0,0 +1,28 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package clarin.cmdi.schema.cmd;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ValidatorException extends Exception {
+
+    public ValidatorException() {
+    }
+
+    public ValidatorException(String message) {
+	super(message);
+    }
+
+    public ValidatorException(Throwable cause) {
+	super(cause);
+    }
+
+    public ValidatorException(String message, Throwable cause) {
+	super(message, cause);
+    }
+    
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/xml/Saxon.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/xml/Saxon.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/java/clarin/cmdi/xml/Saxon.java	(revision 1843)
@@ -0,0 +1,118 @@
+package clarin.cmdi.xml;
+
+import javax.xml.transform.Source;
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XPathCompiler;
+import net.sf.saxon.s9api.XPathSelector;
+import net.sf.saxon.s9api.XdmItem;
+import net.sf.saxon.s9api.XdmNode;
+import net.sf.saxon.s9api.XsltCompiler;
+import net.sf.saxon.s9api.XsltExecutable;
+
+/**
+ * This class contains some convenience methods for Saxon.
+ *
+ * @author menwin
+ */
+public class Saxon {
+
+    /**
+     * The Saxon processor from which there should be only one.
+     * Any Saxon related instance, e.g., an XML document or an XSLT transform, should share this processor.
+     * Otherwise Saxon will complain as it can't used shared constructs, like the NamePool.
+     */
+    static private Processor sxProcessor = null;
+    /**
+     * The Saxon XSLT compiler.
+     */
+    static private XsltCompiler sxXsltCompiler = null;
+    /**
+     * The Saxon XPath compiler.
+     */
+    static private XPathCompiler sxXPathCompiler = null;
+
+    /**
+     * Get a Saxon processor, i.e., just-in-time create the Singleton.
+     *
+     * @return The Saxon processor
+     */
+    public static synchronized Processor getProcessor() {
+	if (sxProcessor == null) {
+	    sxProcessor = new Processor(false);
+	}
+	return sxProcessor;
+    }
+
+    private static synchronized XsltCompiler getXsltCompiler() {
+	if (sxXsltCompiler == null) {
+	    sxXsltCompiler = getProcessor().newXsltCompiler();
+	}
+	return sxXsltCompiler;
+    }
+
+    private static synchronized XPathCompiler getXPathCompiler() {
+	if (sxXPathCompiler == null) {
+	    sxXPathCompiler = getProcessor().newXPathCompiler();
+	}
+	return sxXPathCompiler;
+    }
+
+    /**
+     * Load an XML document.
+     *
+     * @param src The source of the document.
+     * @return A Saxon XDM node
+     * @throws SaxonApiException
+     */
+    static public XdmNode buildDocument(Source src) throws SaxonApiException {
+	return getProcessor().newDocumentBuilder().build(src);
+    }
+
+    /**
+     * Compile an XLST document. To use compiled XSLT document use the load() method to turn it into a XsltTransformer.
+     *
+     * @param xslStylesheet
+     * @return An Saxon XSLT executable, which can be shared.
+     * @throws SaxonApiException
+     */
+    static public XsltExecutable buildTransformer(XdmNode xslStylesheet) throws SaxonApiException {
+	return getXsltCompiler().compile(xslStylesheet.asSource());
+    }
+
+    /**
+     * Declare an XML namespace to be used in XPath expressions.
+     *
+     * @param nsPrefix The prefix used by the XPath expression to refer to the namespace.
+     * @param nsUri The actual namespace URI.
+     */
+    static public void declareXPathNamespace(String nsPrefix, String nsUri) {
+	getXPathCompiler().declareNamespace(nsPrefix, nsUri);
+    }
+
+    /**
+     * Compile an XPath expression. Use evaluate(), evaluateSingle() or iterator() to actually execute the XPath expression.
+     *
+     * @param xp The XPath expression.
+     * @return A compiled XPath expression.
+     * @throws SaxonApiException
+     */
+    static public XPathSelector compileXPath(String xp) throws SaxonApiException {
+	return getXPathCompiler().compile(xp).load();
+    }
+
+    /**
+     * Compile an XPath expression and set the context item. Use evaluate(), evaluateSingle() or iterator() to actually execute the XPath
+     * expression.
+     *
+     * @param ctxt The context item.
+     * @param xp The XPath expression.
+     * @return A compiled XPath expression.
+     * @throws SaxonApiException
+     */
+    static public XPathSelector evaluateXPath(XdmItem ctxt, String xp) throws SaxonApiException {
+	XPathSelector sxXPathSelector = compileXPath(xp);
+	sxXPathSelector.setContextItem(ctxt);
+	return sxXPathSelector;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromRNG-2.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromRNG-2.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromRNG-2.xsl	(revision 1843)
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Stylesheet for extracting Schematron information from a RELAX-NG schema.
+	Based on the stylesheet for extracting Schematron information from W3C XML Schema.
+	Created by Eddie Robertsson 2002/06/01
+	Update for ISO Schematron using XSLT2 Rick Jelliffe 2010/04/14
+-->
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:rng="http://relaxng.org/ns/structure/1.0">
+	<!-- Set the output to be XML with an XML declaration and use indentation -->
+	<xsl:output method="xml" omit-xml-declaration="no" indent="yes" standalone="yes"/>
+	<!-- -->
+	<!-- match schema and call recursive template to extract included schemas -->
+	<!-- -->
+	<xsl:template match="/rng:grammar | /rng:element">
+		<!-- call the schema definition template ... -->
+		<xsl:call-template name="gatherSchema">
+			<!-- ... with current node as the $schemas parameter ... -->
+			<xsl:with-param name="schemas" select="."/>
+			<!-- ... and any includes in the $include parameter -->
+			<xsl:with-param name="includes" select="document(/rng:grammar/rng:include/@href
+| //rng:externalRef/@href)"/>
+		</xsl:call-template>
+	</xsl:template>
+	<!-- -->
+	<!-- gather all included schemas into a single parameter variable -->
+	<!-- -->
+	<xsl:template name="gatherSchema">
+		<xsl:param name="schemas"/>
+		<xsl:param name="includes"/>
+		<xsl:choose>
+			<xsl:when test="count($schemas) &lt; count($schemas | $includes)">
+				<!-- when $includes includes something new, recurse ... -->
+				<xsl:call-template name="gatherSchema">
+					<!-- ... with current $includes added to the $schemas parameter ... -->
+					<xsl:with-param name="schemas" select="$schemas | $includes"/>
+					<!-- ... and any *new* includes in the $include parameter -->
+					<xsl:with-param name="includes" select="document($includes/rng:grammar/rng:include/@href
+| $includes//rng:externalRef/@href)"/>
+				</xsl:call-template>
+			</xsl:when>
+			<xsl:otherwise>
+				<!-- we have the complete set of included schemas, so now let's output the embedded schematron -->
+				<xsl:call-template name="output">
+					<xsl:with-param name="schemas" select="$schemas"/>
+				</xsl:call-template>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+	<!-- -->
+	<!-- output the schematron information -->
+	<!-- -->
+	<xsl:template name="output">
+		<xsl:param name="schemas"/>
+		<!-- -->
+		<sch:schema  queryBinding="xslt2" >
+			<!-- get header-type elements - eg title and especially ns -->
+			<!-- title (just one) -->
+			<xsl:copy-of select="$schemas//sch:title[1]"/>
+			<!-- get remaining schematron schema children -->
+			<!-- get non-blank namespace elements, dropping duplicates -->
+			<xsl:for-each select="$schemas//sch:ns">
+				<xsl:if test="generate-id(.) = generate-id($schemas//sch:ns[@prefix = current()/@prefix][1])">
+					<xsl:copy-of select="."/>
+				</xsl:if>
+			</xsl:for-each>
+			<xsl:copy-of select="$schemas//sch:phase"/>
+			<xsl:copy-of select="$schemas//sch:pattern"/>
+			<!-- get XSLT keys and functions -->
+			<xsl:copy-of select="$schemas//xsl:key"/>
+			<xsl:copy-of select="$schemas//xsl:function"/>
+			<sch:diagnostics>
+				<xsl:copy-of select="$schemas//sch:diagnostics/*"/>
+			</sch:diagnostics>
+		</sch:schema>
+	</xsl:template>
+	<!-- -->
+</xsl:transform>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromXSD-2.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromXSD-2.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/ExtractSchFromXSD-2.xsl	(revision 1843)
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+        based on an original transform by Eddie Robertsson
+        2001/04/21      fn: added support for included schemas
+        2001/06/27      er: changed XMl Schema prefix from xsd: to xs: and changed to the Rec namespace
+        2010/04/14    	rj: Update for ISO Schematron using xslt2
+-->
+<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+xmlns:sch="http://purl.oclc.org/dsdl/schematron" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+        <!-- Set the output to be XML with an XML declaration and use indentation -->
+        <xsl:output method="xml" omit-xml-declaration="no" indent="yes" standalone="yes"/>
+        <!-- -->
+        <!-- match schema and call recursive template to extract included schemas -->
+        <!-- -->
+        <xsl:template match="xs:schema">
+                <!-- call the schema definition template ... -->
+                <xsl:call-template name="gatherSchema">
+                        <!-- ... with current current root as the $schemas parameter ... -->
+                        <xsl:with-param name="schemas" select="/"/>
+                        <!-- ... and any includes in the $include parameter -->
+                        <xsl:with-param name="includes" 
+						select="document(/xs:schema/xs:*[self::xs:include or self::xs:import or self::xs:redefine]/@schemaLocation)"/>
+                </xsl:call-template>
+        </xsl:template>
+        <!-- -->
+        <!-- gather all included schemas into a single parameter variable -->
+        <!-- -->
+        <xsl:template name="gatherSchema">
+                <xsl:param name="schemas"/>
+                <xsl:param name="includes"/>
+                <xsl:choose>
+                        <xsl:when test="count($schemas) &lt; count($schemas | $includes)">
+                                <!-- when $includes includes something new, recurse ... -->
+                                <xsl:call-template name="gatherSchema">
+                                        <!-- ... with current $includes added to the $schemas parameter ... -->
+                                        <xsl:with-param name="schemas" select="$schemas | $includes"/>
+                                        <!-- ... and any *new* includes in the $include parameter -->
+                                        <xsl:with-param name="includes" 
+										select="document($includes/xs:schema/xs:*[self::xs:include or self::xs:import or self::xs:redefine]/@schemaLocation)"/>
+                                </xsl:call-template>
+                        </xsl:when>
+                        <xsl:otherwise>
+                                <!-- we have the complete set of included schemas, 
+								so now let's output the embedded schematron -->
+                                <xsl:call-template name="output">
+                                        <xsl:with-param name="schemas" select="$schemas"/>
+                                </xsl:call-template>
+                        </xsl:otherwise>
+                </xsl:choose>
+        </xsl:template>
+        <!-- -->
+        <!-- output the schematron information -->
+        <!-- -->
+        <xsl:template name="output">
+                <xsl:param name="schemas"/>
+                <!-- -->
+                <sch:schema queryBinding="xslt2">
+                        <!-- get header-type elements - eg title and especially ns -->
+                        <!-- title (just one) -->
+                        <xsl:copy-of select="$schemas//xs:appinfo/sch:title[1]"/>
+                        <!-- get remaining schematron schema children -->
+                        <!-- get non-blank namespace elements, dropping duplicates -->
+                        <xsl:for-each select="$schemas//xs:appinfo/sch:ns">
+                                <xsl:if test="generate-id(.) = 
+								generate-id($schemas//xs:appinfo/sch:ns[@prefix = current()/@prefix][1])">
+                                        <xsl:copy-of select="."/>
+                                </xsl:if>
+                        </xsl:for-each>
+                        <xsl:copy-of select="$schemas//xs:appinfo/sch:phase"/>
+                        <xsl:copy-of select="$schemas//xs:appinfo/sch:pattern"/>
+                        <sch:diagnostics>
+                                <xsl:copy-of select="$schemas//xs:appinfo/sch:diagnostics/*"/>
+                        </sch:diagnostics>
+                </sch:schema>
+        </xsl:template>
+        <!-- -->
+</xsl:transform>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_abstract_expand.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_abstract_expand.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_abstract_expand.xsl	(revision 1843)
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding="UTF-8"?><?xar XSLT?>
+
+<!-- 
+     OVERVIEW - iso_abstract_expand.xsl
+     
+	    This is a preprocessor for ISO Schematron, which implements abstract patterns. 
+	    It also 
+	       	* extracts a particular schema using an ID, where there are multiple 
+	    schemas, such as when they are embedded in the same NVDL script 
+	    	* experimentally, allows parameter recognition and substitution inside
+	    	text as well as @context, @test, & @select.
+		
+		
+		This should be used after iso-dsdl-include.xsl and before the skeleton or
+		meta-stylesheet (e.g. iso-svrl.xsl) . It only requires XSLT 1.
+		 
+		Each kind of inclusion can be turned off (or on) on the command line.
+		 
+-->
+<!-- 
+  VERSION INFORMATION
+  2008-09-18 RJ
+  		* move out param test from iso:schema template  to work with XSLT 1. (Noah Fontes)
+  		
+  2008-07-29 RJ 
+  		* Create.  Pull out as distinct XSL in its own namespace from old iso_pre_pro.xsl
+  		* Put everything in private namespace
+  		* Rewrite replace_substring named template so that copyright is clear
+  	
+  2008-07-24 RJ
+       * correct abstract patterns so for correct names: param/@name and
+     param/@value
+    
+  2007-01-12  RJ 
+     * Use ISO namespace
+     * Use pattern/@id not  pattern/@name 
+     * Add Oliver Becker's suggests from old Schematron-love-in list for <copy> 
+     * Add XT -ism?
+  2003 RJ
+     * Original written for old namespace
+     * http://www.topologi.com/resources/iso-pre-pro.xsl
+-->	
+<!--
+ LEGAL INFORMATION
+ 
+ Copyright (c) 2000-2008 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+<xslt:stylesheet version="1.0" xmlns:xslt="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+    xmlns:iso="http://purl.oclc.org/dsdl/schematron"  
+    xmlns:nvdl="http://purl.oclc.org/dsdl/nvdl"  
+    
+    xmlns:iae="http://www.schematron.com/namespace/iae" 
+     
+      >
+	
+	<xslt:param name="schema-id"></xslt:param>
+	
+	
+	<!-- Driver for the mode -->
+	<xsl:template match="/">
+  		<xsl:apply-templates select="." mode="iae:go" />
+	</xsl:template> 
+	
+	
+	<!-- ================================================================================== -->
+	<!-- Normal processing rules                                                            -->
+	<!-- ================================================================================== -->
+	<!-- Output only the selected schema --> 
+	<xslt:template match="iso:schema" >
+	    <xsl:if test="string-length($schema-id) =0 or @id= $schema-id ">
+	    	<xslt:copy>
+				<xslt:copy-of select="@*" />
+				<xslt:apply-templates  mode="iae:go" /> 
+			</xslt:copy>
+		</xsl:if>
+	</xslt:template>
+	
+ 
+	<!-- Strip out any foreign elements above the Schematron schema .
+		-->
+	<xslt:template match="*[not(ancestor-or-self::iso:*)]"     mode="iae:go"  >
+	   <xslt:apply-templates  mode="iae:go" />
+	</xslt:template>
+	   
+	
+	<!-- ================================================================================== -->
+	<!-- Handle Schematron abstract pattern preprocessing                                   -->
+	<!-- abstract-to-real calls
+			do-pattern calls 
+				macro-expand calls 
+					multi-macro-expand
+						replace-substring                                                   -->
+	<!-- ================================================================================== -->
+	
+	<!--
+		Abstract patterns allow you to say, for example
+		
+		<pattern name="htmlTable" is-a="table">
+			<param name="row" value="html:tr"/>
+			<param name="cell" value="html:td" />
+			<param name="table" value="html:table" />
+		</pattern>
+		
+		For a good introduction, see Uche Ogbujii's article for IBM DeveloperWorks
+		"Discover the flexibility of Schematron abstract patterns"
+		  http://www-128.ibm.com/developerworks/xml/library/x-stron.html
+		However, note that ISO Schematron uses @name and @value attributes on
+		the iso:param element, and @id not @name on the pattern element.
+		
+	-->
+	
+	<!-- Suppress declarations of abstract patterns -->
+	<xslt:template match="iso:pattern[@abstract='true']"  mode="iae:go"  >
+		<xslt:comment>Suppressed abstract pattern <xslt:value-of select="@id"/> was here</xslt:comment>	
+	</xslt:template> 
+	
+	
+	<!-- Suppress uses of abstract patterns -->
+	<xslt:template match="iso:pattern[@is-a]"  mode="iae:go" >
+			
+		<xslt:comment>Start pattern based on abstract <xslt:value-of select="@is-a"/></xslt:comment>
+		
+		<xslt:call-template name="iae:abstract-to-real" >
+			<xslt:with-param name="caller" select="@id" />
+			<xslt:with-param name="is-a" select="@is-a" />
+		</xslt:call-template>
+			
+	</xslt:template>
+	 
+	 
+	
+	<!-- output everything else unchanged -->
+	<xslt:template match="*" priority="-1"  mode="iae:go" >
+	    <xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="iae:go"/> 
+		</xslt:copy>
+	</xslt:template>
+	
+	<!-- Templates for macro expansion of abstract patterns -->
+	<!-- Sets up the initial conditions for the recursive call -->
+	<xslt:template name="iae:macro-expand">
+		<xslt:param name="caller"/>
+		<xslt:param name="text" />
+		<xslt:call-template name="iae:multi-macro-expand">
+			<xslt:with-param name="caller" select="$caller"/>
+			<xslt:with-param name="text" select="$text"/>
+			<xslt:with-param name="paramNumber" select="1"/>
+		</xslt:call-template>
+		
+	</xslt:template>
+	
+	<!-- Template to replace the current parameter and then
+	   recurse to replace subsequent parameters. -->
+	    
+	<xslt:template name="iae:multi-macro-expand">
+		<xslt:param name="caller"/>
+		<xslt:param name="text" />
+		<xslt:param name="paramNumber" />
+
+		
+		<xslt:choose>
+			<xslt:when test="//iso:pattern[@id=$caller]/iso:param[ $paramNumber]">
+
+				<xslt:call-template name="iae:multi-macro-expand">
+					<xslt:with-param name="caller" select="$caller"/>	
+					<xslt:with-param name="paramNumber" select="$paramNumber + 1"/>		
+					<xslt:with-param name="text" >
+						<xslt:call-template name="iae:replace-substring">
+							<xslt:with-param name="original" select="$text"/>
+							<xslt:with-param name="substring"
+							select="concat('$', //iso:pattern[@id=$caller]/iso:param[ $paramNumber ]/@name)"/>
+							<xslt:with-param name="replacement"
+								select="//iso:pattern[@id=$caller]/iso:param[ $paramNumber ]/@value"/>			
+						</xslt:call-template>
+					</xslt:with-param>						
+				</xslt:call-template>
+			</xslt:when>
+			<xslt:otherwise><xslt:value-of select="$text" /></xslt:otherwise>		
+		
+		</xslt:choose>
+	</xslt:template>
+	
+	
+	<!-- generate the real pattern from an abstract pattern + parameters-->
+	<xslt:template name="iae:abstract-to-real" >
+		<xslt:param name="caller"/>
+		<xslt:param name="is-a" />
+		<xslt:for-each select="//iso:pattern[@id= $is-a]">
+		<xslt:copy>
+		
+		    <xslt:choose>
+		      <xslt:when test=" string-length( $caller ) = 0">
+		      <xslt:attribute name="id"><xslt:value-of select="concat( generate-id(.) , $is-a)" /></xslt:attribute>
+		      </xslt:when>
+		      <xslt:otherwise>
+				<xslt:attribute name="id"><xslt:value-of select="$caller" /></xslt:attribute>
+		      </xslt:otherwise>
+		    </xslt:choose> 
+			
+			<xslt:apply-templates select="*|text()" mode="iae:do-pattern"    >
+				<xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param>
+			</xslt:apply-templates>	
+			
+		</xslt:copy>
+		</xslt:for-each>
+	</xslt:template>
+		
+	
+	<!-- Generate a non-abstract pattern -->
+	<xslt:template mode="iae:do-pattern" match="*">
+		<xslt:param name="caller"/>
+		<xslt:copy>
+			<xslt:for-each select="@*[name()='test' or name()='context' or name()='select']">
+				<xslt:attribute name="{name()}">
+				<xslt:call-template name="iae:macro-expand">
+						<xslt:with-param name="text"><xslt:value-of select="."/></xslt:with-param>
+						<xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param>
+					</xslt:call-template>
+				</xslt:attribute>
+			</xslt:for-each>	
+			<xslt:copy-of select="@*[name()!='test'][name()!='context'][name()!='select']" />
+			<xsl:for-each select="node()">
+				<xsl:choose>
+				    <!-- Experiment: replace macros in text as well, to allow parameterized assertions
+				        and so on, without having to have spurious <iso:value-of> calls and multiple
+				        delimiting -->
+					<xsl:when test="self::text()">	
+						<xslt:call-template name="iae:macro-expand">
+							<xslt:with-param name="text"><xslt:value-of select="."/></xslt:with-param>
+							<xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param>
+						</xslt:call-template>
+					</xsl:when>
+					<xsl:otherwise>
+						<xslt:apply-templates select="." mode="iae:do-pattern">
+							<xslt:with-param name="caller"><xslt:value-of select="$caller"/></xslt:with-param>
+						</xslt:apply-templates>		
+					</xsl:otherwise>
+				</xsl:choose>
+			</xsl:for-each>			
+		</xslt:copy>
+	</xslt:template>
+	
+	<!-- UTILITIES --> 
+	<!-- Simple version of replace-substring function -->
+	<xslt:template name="iae:replace-substring">
+		<xslt:param name="original" />    
+		<xslt:param name="substring" />   
+		<xslt:param name="replacement" select="''"/>
+		
+  <xsl:choose>
+    <xsl:when test="not($original)" /> 
+    <xsl:when test="not(string($substring))">
+      <xsl:value-of select="$original" />
+    </xsl:when> 
+        <xsl:when test="contains($original, $substring)">
+          <xsl:variable name="before" select="substring-before($original, $substring)" />
+          <xsl:variable name="after" select="substring-after($original, $substring)" />
+          
+          <xsl:value-of select="$before" />
+          <xsl:value-of select="$replacement" />
+          <!-- recursion -->
+          <xsl:call-template name="iae:replace-substring">
+            <xsl:with-param name="original" select="$after" />
+            <xsl:with-param name="substring" select="$substring" />
+            <xsl:with-param name="replacement" select="$replacement" /> 
+            </xsl:call-template>
+        </xsl:when>
+        <xsl:otherwise>
+        	<!-- no substitution -->
+        	<xsl:value-of select="$original" />
+        </xsl:otherwise>
+      </xsl:choose> 
+</xslt:template>
+
+
+
+</xslt:stylesheet>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_dsdl_include.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_dsdl_include.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_dsdl_include.xsl	(revision 1843)
@@ -0,0 +1,1508 @@
+<?xml version="1.0" encoding="UTF-8"?><?xar XSLT?>
+
+<!-- 
+     OVERVIEW : iso_dsdl_include.xsl
+     
+	    This is an inclusion preprocessor for the non-smart text inclusions
+	    of ISO DSDL. It handles 
+	    	<relax:extRef> for ISO RELAX NG
+	    	<sch:include>  for ISO Schematron and Schematron 1.n
+	    	<sch:extends>  for 2009 draft ISO Schematron
+	    	<xi:xinclude>  simple W3C XIncludes for ISO NVRL and DSRL 
+	    	<crdl:ref>     for draft ISO CRDL
+	    	<dtll:include> for draft ISO DTLL
+	    	<* @xlink:href> for simple W3C XLink 1.1 embedded links
+	    	
+		 
+		This should be the first in any chain of processing. It only requires
+		XSLT 1. Each kind of inclusion can be turned off (or on) on the command line.
+		
+		Ids in fragment identifiers or xpointers will be sought in the following
+		order:
+		    * @xml:id
+		    * id() for typed schemas (e.g. from DTD) [NOTE: XInclude does not support this]
+		    * untyped @id 
+		    
+	The proposed behaviour for the update to ISO Schematron has been implemented. If an
+	include points to an element with the same name as the parent, then that element's
+	contents will be included. This supports the merge style of inclusion.    
+	
+	When an inclusion is made, it is preceded by a PI with target DSDL_INCLUDE_START
+	and the href and closed by a PI with target DSDL_INCLUDE_START and the href. This is
+	to allow better location of problems, though only to the file level. 
+	
+	Limitations:
+	* No rebasing: relative paths will be interpreted based on the initial document's
+	path, not the including document. (Severe limitation!)
+	* No checking for circular references
+	* Not full xpointers: only ID matching
+	* <relax:include> not implemented 
+	* XInclude handling of xml:base and xml:lang not implemented   
+-->
+<!-- 
+  VERSION INFORMATION
+    2010-04-21
+    * Add basic syntax checks on XPaths belonging to Schematron elements only
+    * Unlocalized messages are put out using xsl:message. The intent is to allow
+    * problems to be caught at compile time. 
+	2009-02-25 
+	* Update DSDL namespace to use schematron.com
+	* Tested with SAXON9, Xalan 2.7.1, IE7, 
+	* IE does not like multiple variables in same template with same name: rename.   
+	2008-09-18
+	* Remove new behaviour for include, because it conflicts with existing usage [KH]
+	* Add extends[@href] element with that merge functionality
+	* Generate PIs to notate source of inclusions for potential better diagnostics
+	
+	2008-09-16
+	* Fix for XSLT1
+	
+	2008-08-28
+	* New behaviour for schematron includes: if the pointed to element is the same as the current,
+	include the children.
+	
+	2008-08-20
+	* Fix bug: in XSLT1 cannot do $document/id('x') but need to use for-each
+	
+	2008-08-04
+	* Add support for inclusions in old namespace  
+	
+	2008-08-03
+	* Fix wrong param name include-relaxng & include-crdl (KH, PH)
+	* Allow inclusion of XSLT and XHTML (KH)
+	* Fix inclusion of fragments (KH)
+	
+	2008-07-25
+	* Add selectable input parameter
+	
+	2008-07-24  
+	* RJ New
+-->
+<!--
+	LEGAL INFORMATION
+	
+	Copyright (c) 2008 Rick Jelliffe 
+	
+	This software is provided 'as-is', without any express or implied warranty. 
+	In no event will the authors be held liable for any damages arising from 
+	the use of this software.
+	
+	Permission is granted to anyone to use this software for any purpose, 
+	including commercial applications, and to alter it and redistribute it freely,
+	subject to the following restrictions:
+	
+	1. The origin of this software must not be misrepresented; you must not claim
+	that you wrote the original software. If you use this software in a product, 
+	an acknowledgment in the product documentation would be appreciated but is 
+	not required.
+	
+	2. Altered source versions must be plainly marked as such, and must not be 
+	misrepresented as being the original software.
+	
+	3. This notice may not be removed or altered from any source distribution.
+-->
+<xslt:stylesheet version="1.0"
+	xmlns:xslt="http://www.w3.org/1999/XSL/Transform"
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	xmlns:iso="http://purl.oclc.org/dsdl/schematron"
+	xmlns:nvdl="http://purl.oclc.org/dsdl/nvdl"
+	xmlns:xhtml="http://www.w3.org/1999/xhtml"
+	xmlns:schold="http://www.ascc.net/xml/schematron"
+	xmlns:crdl="http://purl.oclc.org/dsdl/crepdl/ns/structure/1.0"
+	xmlns:xi="http://www.w3.org/2001/XInclude"
+	xmlns:dtll="http://www.jenitennison.com/datatypes"
+	xmlns:dsdl="http://www.schematron.com/namespace/dsdl"
+	xmlns:relax="http://relaxng.org/ns/structure/1.0"
+	xmlns:xlink="http://www.w3.org/1999/xlink"
+	
+	
+     xmlns:sch-check="http://www.schematron.com/namespace/sch-check" 
+	>
+	<!-- Note: The URL for the dsdl namespace is not official -->
+
+
+	<xsl:param name="include-schematron">true</xsl:param>
+	<xsl:param name="include-crdl">true</xsl:param>
+	<xsl:param name="include-xinclude">true</xsl:param>
+	<xsl:param name="include-dtll">true</xsl:param>
+	<xsl:param name="include-relaxng">true</xsl:param>
+	<xsl:param name="include-xlink">true</xsl:param>
+
+   
+    <!-- ========================================================== -->
+    <!-- Output and process contents, check Schematron XPaths too   -->
+    <!-- ========================================================== -->
+    
+	<xsl:template match="/">
+		<xsl:apply-templates select="." mode="dsdl:go" />
+	</xsl:template>
+
+	<!-- output everything else unchanged. But check Xpaths here.  -->
+
+	<xslt:template match="iso:rule[@context]"  mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @context "  />
+          <xsl:with-param name="subject" select=" 'Bad rule: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+	
+	<xslt:template match="iso:assert[@test]"  mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @test "  />
+          <xsl:with-param name="subject" select=" 'Bad assert: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+	
+	<xslt:template match="iso:report[@test]"  mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @test "  />
+          <xsl:with-param name="subject" select=" 'Bad report: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+	
+	<xslt:template match="iso:let[@value]"  mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @value "  />
+          <xsl:with-param name="subject" select=" 'Bad let: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+	
+	
+		<xslt:template match="iso:value-of[@select]" mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @select "  />
+          <xsl:with-param name="subject" select=" 'Bad value-of: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+	
+		<xslt:template match="iso:name[@path]" mode="dsdl:go">
+	  <xsl:call-template name="sch-check:xpath-wf-message">
+          <xsl:with-param name="string" select=" @select "  />
+          <xsl:with-param name="subject" select=" 'Bad name element: ' "  />
+        </xsl:call-template>
+        
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+
+		<!-- output everything else unchanged -->
+	<xslt:template match="node()" priority="-1" mode="dsdl:go">
+		<xslt:copy>
+			<xslt:copy-of select="@*" />
+			<xslt:apply-templates mode="dsdl:go" />
+		</xslt:copy>
+	</xslt:template>
+
+
+
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 2 - Regular grammar-based validation - RELAX NG        -->
+	<!-- This only implements relax:extRef not relax:include which   -->
+	<!-- is complex.                                                 -->
+	<!-- =========================================================== -->
+	<xslt:template match="relax:extRef" mode="dsdl:go">
+
+
+		<!-- Insert subschema -->
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+		<xsl:choose>
+			<xsl:when test="not( $include-relaxng = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in RELAX NG extRef
+							include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//*[@xml:id= $fragment-id ] | id( $fragment-id) | //*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use a for-each so that the id() function works correctly on the external document -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select="$theDocument_1//*[@xml:id= $fragment-id ]        
+                  |  id( $fragment-id)          
+              | $theDocument_1//*[@id= $fragment-id ]" />
+							<xsl:if test="not($theFragment_1)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:if>
+							<xsl:apply-templates
+								select=" $theFragment_1[1]" mode="dsdl:go" />
+						</xsl:for-each>
+					</xsl:when>
+
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/*" />
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:if test="not($theFragment_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to locate id attribute: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<xsl:apply-templates select="$theFragment_2 "
+							mode="dsdl:go" />
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xslt:template>
+
+
+
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 3 - Rule-based validation - Schematron                 -->
+	<!-- =========================================================== -->
+
+
+	<!-- Extend the URI syntax to allow # references -->
+	<!-- Add experimental support for simple containers like  /xxx:xxx/iso:pattern to allow better includes -->
+	<xsl:template match="iso:include" mode="dsdl:go">
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+
+		<xsl:choose>
+			<xsl:when test="not( $include-schematron = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in Schematron include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//iso:*[@xml:id= $fragment-id ] 
+              	 |id( $fragment-id)
+              	 | //iso:*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<!-- case where there is a fragment in another document (should be an iso: element) -->
+					<!-- There are three cases for includes with fragment:
+						0) No href file or no matching id - error!
+						1) REMOVED
+						
+						2) The linked-to element is sch:schema however the parent of the include
+						is not a schema. In this case, it is an error. (Actually, it should
+						be an error for other kinds of containment problems, but we won't
+						check for them in this version.)
+						
+						3) Otherwise, include the pointed-to element
+					-->
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="originalParent" select=".." />
+
+						<!-- case 0 -->
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to external document -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select=" $theDocument_1//iso:*[@xml:id= $fragment-id ] |
+              	 		id($fragment-id) |
+              			$theDocument_1//iso:*[@id= $fragment-id ]" />
+
+
+							<xsl:choose>
+								<!-- case 0 -->
+								<xsl:when test="not($theFragment_1)">
+									<xsl:message terminate="no">
+										<xsl:text>Unable to locate id attribute: </xsl:text>
+										<xsl:value-of select="@href" />
+									</xsl:message>
+								</xsl:when>
+
+
+								<!-- case 1 REMOVED -->
+
+								<!-- case 2 -->
+								<xsl:when
+									test=" $theFragment_1/self::iso:schema ">
+									<xsl:message>
+										Schema error: Use include to
+										include fragments, not a whole
+										schema
+									</xsl:message>
+								</xsl:when>
+
+								<!-- case 3 -->
+								<xsl:otherwise>
+									<xsl:apply-templates
+										select=" $theFragment_1[1]" mode="dsdl:go" />
+								</xsl:otherwise>
+							</xsl:choose>
+						</xsl:for-each>
+					</xsl:when>
+
+					<!-- Case where there is no ID so we include the whole document -->
+					<!-- Experimental addition: include fragments of children -->
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/iso:*" />
+						<xsl:variable name="theContainedFragments"
+							select="$theDocument_2/*/iso:* | $theDocument_2/*/xsl:* | $theDocument_2/*/xhtml:*" />
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<!-- There are three cases for includes:
+							0) No text specified- error!
+							
+							1) REMOVED
+							
+							2) The linked-to element is sch:schema however the parent of the include
+							is not a schema. In this case, it is an error. (Actually, it should
+							be an error for other kinds of containment problems, but we won't
+							check for them in this version.)
+							
+							3) Otherwise, include the pointed-to element
+						-->
+						<xsl:choose>
+							<!-- case 0 -->
+							<xsl:when
+								test="not($theFragment_2) and not ($theContainedFragments)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:when>
+
+							<!-- case 1 removed -->
+
+							<!-- case 2 -->
+							<xsl:when
+								test=" $theFragment_2/self::iso:schema or $theContainedFragments/self::iso:schema">
+								<xsl:message>
+									Schema error: Use include to include
+									fragments, not a whole schema
+								</xsl:message>
+							</xsl:when>
+
+							<!-- If this were XLST 2, we could use  
+								if ($theFragment) then $theFragment else $theContainedFragments
+								here (thanks to KN)
+							-->
+							<!-- case 3 -->
+							<xsl:otherwise>
+								<xsl:apply-templates
+									select="$theFragment_2 " mode="dsdl:go" />
+							</xsl:otherwise>
+						</xsl:choose>
+					</xsl:otherwise>
+				</xsl:choose>
+			</xsl:otherwise>
+		</xsl:choose>
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xsl:template>
+
+
+	<!-- WARNING   sch:extends[@href] is experimental and non standard  -->
+	<!-- Basically, it adds the children of the selected element, not the element itself.  -->
+	<xsl:template match="iso:extends[@href]" mode="dsdl:go">
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+
+		<xsl:choose>
+			<xsl:when test="not( $include-schematron = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in Schematron include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//iso:*[@xml:id= $fragment-id ]/* 
+              	 |id( $fragment-id)/*
+              	 | //iso:*[@id= $fragment-id ]/*" />
+					</xslt:when>
+
+					<!-- case where there is a fragment in another document (should be an iso: element) -->
+					<!-- There are three cases for includes with fragment:
+						0) No href file or no matching id - error!
+						1) REMOVED
+						
+						2) REMOVED
+						
+						3) Otherwise, include the pointed-to element
+					-->
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="originalParent" select=".." />
+
+						<!-- case 0 -->
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to external document -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select=" $theDocument_1//iso:*[@xml:id= $fragment-id ] |
+              	 		id($fragment-id) |
+              			$theDocument_1//iso:*[@id= $fragment-id ]" />
+
+
+							<xsl:choose>
+								<!-- case 0 -->
+								<xsl:when test="not($theFragment_1)">
+									<xsl:message terminate="no">
+										<xsl:text>Unable to locate id attribute: </xsl:text>
+										<xsl:value-of select="@href" />
+									</xsl:message>
+								</xsl:when>
+
+
+								<!-- case 1 REMOVED -->
+
+								<!-- case 2 REMOVED -->
+
+
+								<!-- case 3 -->
+								<xsl:otherwise>
+
+									<xsl:apply-templates
+										select=" $theFragment_1[1]/*" mode="dsdl:go" />
+								</xsl:otherwise>
+							</xsl:choose>
+						</xsl:for-each>
+					</xsl:when>
+
+					<!-- Case where there is no ID so we include the whole document -->
+					<!-- Experimental addition: include fragments of children -->
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/iso:*" />
+						<xsl:variable name="theContainedFragments"
+							select="$theDocument_2/*/iso:* | $theDocument_2/*/xsl:* | $theDocument_2/*/xhtml:*" />
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<!-- There are three cases for includes:
+							0) No text specified- error!
+							
+							1) REMOVED
+							
+							2) REMOVED
+							
+							3) Otherwise, include the pointed-to element
+						-->
+						<xsl:choose>
+							<!-- case 0 -->
+							<xsl:when
+								test="not($theFragment_2) and not ($theContainedFragments)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:when>
+
+							<!-- case 1 removed -->
+
+							<!-- case 2 removed -->
+
+							<!-- If this were XLST 2, we could use  
+								if ($theFragment) then $theFragment else $theContainedFragments
+								here (thanks to KN)
+							-->
+							<!-- case 3 -->
+							<xsl:otherwise>
+								<xsl:apply-templates
+									select="$theFragment_2/* " mode="dsdl:go" />
+							</xsl:otherwise>
+						</xsl:choose>
+					</xsl:otherwise>
+				</xsl:choose>
+			</xsl:otherwise>
+		</xsl:choose>
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xsl:template>
+
+
+
+	<!-- =========================================================== -->
+	<!-- Handle Schematron 1.6 inclusions: clone of ISO code above   -->
+	<!-- =========================================================== -->
+
+
+	<!-- Extend the URI syntax to allow # references -->
+	<!-- Add experimental support for simple containers like  /xxx:xxx/schold:pattern to allow better includes -->
+	<xsl:template match="schold:include" mode="dsdl:go">
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+
+		<xsl:choose>
+			<xsl:when test="not( $include-schematron = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in Schematron include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//schold:*[@xml:id= $fragment-id ] 
+              	 |id( $fragment-id)
+              	 | //schold:*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<!-- case where there is a fragment in another document (should be an iso: element) -->
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to $theDocument -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select=" $theDocument_1//schold:*[@xml:id= $fragment-id ] |
+              	id($fragment-id) |
+              	$theDocument_1//schold:*[@id= $fragment-id ]" />
+							<xsl:if
+								test=" $theFragment_1/self::schold:schema ">
+								<xsl:message>
+									Schema error: Use include to include
+									fragments, not a whole schema
+								</xsl:message>
+							</xsl:if>
+							<xsl:if test="not($theFragment_1)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:if>
+							<xsl:apply-templates
+								select=" $theFragment_1[1]" mode="dsdl:go" />
+						</xsl:for-each>
+					</xsl:when>
+
+					<!-- Case where there is no ID so we include the whole document -->
+					<!-- Experimental addition: include fragments of children -->
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/iso:*" />
+						<xsl:variable name="theContainedFragments"
+							select="$theDocument_2/*/schold:* | $theDocument_2/*/xsl:* | $theDocument_2/*/xhtml:*" />
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:if
+							test=" $theFragment_2/self::schold:schema or $theContainedFragments/self::schold:schema">
+							<xsl:message>
+								Schema error: Use include to include
+								fragments, not a whole schema
+							</xsl:message>
+						</xsl:if>
+						<xsl:if
+							test="not($theFragment_2) and not ($theContainedFragments)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to locate id attribute: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- If this were XLST 2, we could use  
+							if ($theFragment) then $theFragment else $theContainedFragments
+							here (thanks to KN)
+						-->
+						<xsl:choose>
+							<xsl:when test=" $theFragment_2 ">
+								<xsl:apply-templates
+									select="$theFragment_2 " mode="dsdl:go" />
+							</xsl:when>
+							<xsl:otherwise>
+								<!-- WARNING!  EXPERIMENTAL! Use at your own risk. This may be discontinued! -->
+								<xsl:apply-templates
+									select="  $theContainedFragments " mode="dsdl:go" />
+							</xsl:otherwise>
+						</xsl:choose>
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xsl:template>
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 5 - DataType Library Language - DTLL                   -->
+	<!-- Committee Draft  Experimental support only                  -->
+	<!-- The <include> element may well be replaced by XInclude in   -->
+	<!-- any final version.                                          -->
+	<!-- =========================================================== -->
+	<xslt:template match="dtll:include" mode="dsdl:go">
+		<!-- Insert subschema -->
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+		<xsl:choose>
+			<xsl:when test="not( $include-dtll = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in DTLL include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//*[@xml:id= $fragment-id ] | id( $fragment-id) 
+              	| //*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to $theDocument -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select="$theDocument_1//*[@xml:id= $fragment-id ]
+               | id( $fragment-id ) 
+               | $theDocument_1//*[@id= $fragment-id ]" />
+							<xsl:if test="not($theFragment_1)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:if>
+							<xsl:apply-templates
+								select=" $theFragment_1[1]" mode="dsdl:go" />
+						</xsl:for-each>
+					</xsl:when>
+
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/*" />
+
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:if test="not($theFragment_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to locate id attribute: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<xsl:apply-templates select="$theFragment_2 "
+							mode="dsdl:go" />
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xslt:template>
+
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 7 - Character Repertoire Description Language - CRDL   -->
+	<!-- Final Committee Draft 2008-01-11 Experimental support only  -->
+	<!-- =========================================================== -->
+	<xslt:template match="crdl:ref" mode="dsdl:go">
+		<!-- Insert subschema -->
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@href, '#')" />
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+		<xsl:choose>
+			<xsl:when test="not( $include-crdl = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in CRDL include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+
+						<xslt:apply-templates mode="dsdl:go"
+							select="//*[@xml:id= $fragment-id ] | id( $fragment-id)
+              	| //*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to $theDocument -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select="$theDocument_1//*[@xml:id= $fragment-id ]
+               | id( $fragment-id )
+               | $theDocument_1//*[@id= $fragment-id ]" />
+
+							<xsl:if test="not($theFragment_1)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@href" />
+								</xsl:message>
+							</xsl:if>
+							<xsl:apply-templates select=" $theFragment_1 "
+								mode="dsdl:go" />
+						</xsl:for-each>
+					</xsl:when>
+
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/*" />
+
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+						<xsl:if test="not($theFragment_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to locate id attribute: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:apply-templates select="$theFragment_2"
+							mode="dsdl:go" />
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xslt:template>
+
+
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 4 - Namespace-based Validation Dispatching Language - NVDL -->
+	<!-- Note: This does not include schemas referenced for          -->
+	<!-- validation, it merely handles any simple XIncludes          -->
+	<!-- =========================================================== -->
+	<!-- ISO/IEC 19757 - DSDL Document Schema Definition Languages   -->
+	<!-- Part 8 - Document Schema Renaming Language - DSRL           -->
+	<!-- Note: Final? Committee Draft   Experimental support only    -->
+	<!-- =========================================================== -->
+	<!-- XInclude support for id based references only, with 1 level -->
+	<!-- of fallback.                                                -->
+	<!-- =========================================================== -->
+
+	<xslt:template mode="dsdl:go"
+		match="xi:include[@href][not(@parseType) or @parseType ='xml']">
+		<!-- Simple inclusions only here -->
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+		<xsl:choose>
+			<xsl:when test="not( $include-xinclude = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:choose>
+
+					<xsl:when test="contains( @href, '#')">
+						<xsl:message terminate="yes">
+							Fatal error: Xinclude href contains fragment
+							identifier #
+						</xsl:message>
+					</xsl:when>
+
+
+					<xsl:when test="contains( @xpointer, '(')">
+						<xsl:message terminate="yes">
+							Fatal error: Sorry, this software only
+							supports simple ids in XInclude xpointers
+						</xsl:message>
+					</xsl:when>
+
+					<xsl:when
+						test="string-length( @href ) = 0 and string-length( @xpointer ) = 0">
+
+						<xsl:message terminate="yes">
+							Fatal Error: Impossible URL in XInclude
+							include
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when test="string-length( @href ) = 0">
+
+						<xslt:apply-templates mode="dsdl:go"
+							select="//*[@xml:id= current()/@xpointer  ] | id( @xpointer)
+              	| //*[@id= current()/@xpointer  ]" />
+					</xslt:when>
+
+					<xsl:when
+						test="string-length( @xpointer ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( @href,/ )" />
+						<xsl:variable name="theFragment_1"
+							select="$theDocument_1//*[@xml:id= current()/@xpointer  ]
+             
+              | $theDocument_1//*[@id= current()/@xpointer  ]" />
+						<!-- removed
+							| $theDocument_1/id( @xpointer)
+							because it requires rebasing in XSLT1 and that would mess up the use of current()
+						-->
+
+
+						<!-- Allow one level of fallback, to another XInclude -->
+						<xsl:if test="not($theDocument_1)">
+							<xsl:choose>
+								<xsl:when test="xi:fallback">
+									<xsl:variable name="theDocument_2"
+										select="document( xi:fallback[1]/xi:include[not(@parseType)
+                    	 or @parseType='xml']/@href,/ )" />
+									<xsl:variable name="theFragment_2"
+										select="$theDocument_2//*[@xml:id= current()/xi:fallback[1]/xi:include/@xpointer  ]
+              				| $theDocument_2//*[@id= current()/xi:fallback[1]/xi:include/@xpointer  ]" />
+									<!-- removed 
+										| $theDocument_2/id( xi:fallback[1]/xi:include/@xpointer)
+										because it id() would need rebasing in XSLT1 and that would mess up use of current()
+									-->
+
+									<xsl:if
+										test="not($theDocument_2)">
+
+										<xsl:message terminate="no">
+											<xsl:text>Unable to open referenced included file and fallback
+									file: </xsl:text>
+											<xsl:value-of
+												select="@href" />
+										</xsl:message>
+									</xsl:if>
+								</xsl:when>
+								<xsl:otherwise>
+									<xsl:message terminate="no">
+										<xsl:text>Unable to open referenced included file: </xsl:text>
+										<xsl:value-of select="@href" />
+									</xsl:message>
+								</xsl:otherwise>
+							</xsl:choose>
+						</xsl:if>
+						<xsl:apply-templates select=" $theFragment_1"
+							mode="dsdl:go" />
+					</xsl:when>
+
+					<!-- Document but no fragment specified -->
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_3"
+							select="document( @href,/ )" />
+						<xsl:variable name="theFragment_3"
+							select="$theDocument_3/*" />
+
+						<xsl:if test="not($theDocument_3)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:apply-templates select="$theFragment_3 "
+							mode="dsdl:go" />
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@href" />
+		</xsl:processing-instruction>
+	</xslt:template>
+
+	<!-- =========================================================== -->
+	<!-- W3C XLink 1.1 embedded simple links                        -->
+	<!-- =========================================================== -->
+	<xslt:template
+		match="*[@xlink:href][not(parent::*[@xlink:type='complex'])]
+	           [not(@xlink:type) or (@xlink:type='simple')]
+	           [@xlink:show='embed']
+	           [not(@xlink:actuate) or (@xlink:actuate='onLoad')]"
+		mode="dsdl:go" priority="1">
+
+		<xsl:variable name="document-uri"
+			select="substring-before(concat(@xlink:href,'#'), '#')" />
+		<xsl:variable name="fragment-id"
+			select="substring-after(@xlink:href, '#')" />
+		<xsl:processing-instruction name="DSDL_INCLUDE_START">
+			<xsl:value-of select="@xlink:href" />
+		</xsl:processing-instruction>
+		<xsl:choose>
+			<xsl:when test="not( $include-xlink = 'true' )">
+				<xslt:copy>
+					<xslt:copy-of select="@*" />
+					<xslt:apply-templates mode="dsdl:go" />
+				</xslt:copy>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:choose>
+
+					<xsl:when
+						test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0">
+						<xsl:message>
+							Error: Impossible URL in XLink embedding
+							link
+						</xsl:message>
+					</xsl:when>
+
+					<!-- this case is when there is in embedded schema in the same document elsewhere -->
+					<xslt:when
+						test="string-length( $document-uri ) = 0">
+						<xslt:apply-templates mode="dsdl:go"
+							select="//*[@xml:id= $fragment-id ] | id( $fragment-id) 
+              	| //*[@id= $fragment-id ]" />
+					</xslt:when>
+
+					<xsl:when
+						test="string-length( $fragment-id ) &gt; 0">
+						<xsl:variable name="theDocument_1"
+							select="document( $document-uri,/ )" />
+						<xsl:if test="not($theDocument_1)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@xlink:href" />
+							</xsl:message>
+						</xsl:if>
+						<!-- use for-each to rebase id() to $theDocument -->
+						<xsl:for-each select="$theDocument_1">
+							<xsl:variable name="theFragment_1"
+								select="$theDocument_1//*[@xml:id= $fragment-id ]
+               | id( $fragment-id ) 
+               | $theDocument_1//*[@id= $fragment-id ]" />
+							<xsl:if test="not($theFragment_1)">
+								<xsl:message terminate="no">
+									<xsl:text>Unable to locate id attribute: </xsl:text>
+									<xsl:value-of select="@xlink:href" />
+								</xsl:message>
+							</xsl:if>
+							<xsl:apply-templates
+								select=" $theFragment_1[1]" mode="dsdl:go" />
+						</xsl:for-each>
+					</xsl:when>
+
+					<xsl:otherwise>
+						<xsl:variable name="theDocument_2"
+							select="document( $document-uri,/ )" />
+						<xsl:variable name="theFragment_2"
+							select="$theDocument_2/*" />
+
+						<xsl:if test="not($theDocument_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to open referenced included file: </xsl:text>
+								<xsl:value-of select="@xlink:href" />
+							</xsl:message>
+						</xsl:if>
+
+						<xsl:if test="not($theFragment_2)">
+							<xsl:message terminate="no">
+								<xsl:text>Unable to locate id attribute: </xsl:text>
+								<xsl:value-of select="@xlink:href" />
+							</xsl:message>
+						</xsl:if>
+						<xsl:apply-templates select="$theFragment_2 "
+							mode="dsdl:go" />
+					</xsl:otherwise>
+				</xsl:choose>
+
+			</xsl:otherwise>
+		</xsl:choose>
+
+		<xsl:processing-instruction name="DSDL_INCLUDE_END">
+			<xsl:value-of select="@xlink:href" />
+		</xsl:processing-instruction>
+	</xslt:template>
+
+<!-- ================================================================= -->
+<!-- UTILITY TEMPLATES                                                 -->
+<!-- ================================================================= -->
+
+<!-- MESSAGE WHEN XPATH NOT WELL FORMED -->
+
+<xsl:template name="sch-check:xpath-wf-message" >
+  <xsl:param name="string" />
+  <xsl:param name="subject" />
+	  <xsl:variable name="xpath-wf-result">
+	      <xsl:call-template name="sch-check:xpath-wf">
+          <xsl:with-param name="string" select=" $string "  />
+        </xsl:call-template>
+	   </xsl:variable>
+	   
+	   <xsl:if test="string-length($xpath-wf-result) > 0">
+	      <xsl:message><xsl:value-of select="$subject"/><xsl:value-of select="$xpath-wf-result" /></xsl:message>
+	   </xsl:if>
+  </xsl:template>
+ 
+<!-- XPATH WELL FORMED -->
+ 
+<xsl:template name="sch-check:xpath-wf" >
+  <xsl:param name="string" />
+   <!-- This does some minimal checks to see if a string is well-formed XPath.
+   It checks 
+      1) String is not empty, 
+      2) equal number of open and close parens
+      3) equal number of left and right square brackets
+   It does not check balancing. It does not check inside string literals in XPaths.
+   
+   If there is no error, empty content is returned. If there is an error, it is given
+   as an error message. This is not localized yet.
+   --> 
+   
+   
+   <xsl:variable name="stripped-contents">
+   <xsl:call-template name="sch-check:strip-strings" >  
+            <xsl:with-param name="string" select=" $string " />
+            <xsl:with-param name="mode" select="  0" />
+   </xsl:call-template>
+   </xsl:variable>
+   
+      
+   <xsl:variable name="paren-result">
+   <xsl:call-template name="sch-check:test-paren" >  
+            <xsl:with-param name="string" select="$stripped-contents" />
+            <xsl:with-param name="count" select="  0" />
+   </xsl:call-template>
+   </xsl:variable>
+    
+   
+   <xsl:variable name="sqb-result">
+   <xsl:call-template name="sch-check:test-sqb" >  
+            <xsl:with-param name="string" select="$stripped-contents" />
+            <xsl:with-param name="count" select="  0" />
+   </xsl:call-template>
+   </xsl:variable>
+    
+   
+   <xsl:choose>
+      <xsl:when test="string-length( normalize-space($string)) = 0"
+      >XPath error. No XPath.</xsl:when>
+         <xsl:when test="contains( $stripped-contents, '/[' )"
+      >XPath error. Missing location step. Suggestion: remove '/' before '['.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+      <!-- not implemented yet 
+      <xsl:when test=" count () mod 2 = 1" 
+      >XPath syntax error. Odd number of apostrophe characters. Suggestion: check string termination and delimiting.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+      <xsl:when test=" count ( ) mod 2 = 1" 
+      >XPath syntax error. Odd number of quote characters. Suggestion: check string termination and delimiting.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+      -->
+      <xsl:when test=" $paren-result > 0 "
+      >XPath syntax error. Unclosed parenthesis. Suggestion: add ')'.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+      <xsl:when test=" $paren-result &lt; 0 "
+      >XPath syntax error. Extra close parenthesis. Suggestion: remove ')'.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+     
+      <xsl:when test=" $sqb-result > 0 "
+      >XPath syntax error. Unclosed left square bracket. Suggestion: add ']'.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+      <xsl:when test=" $sqb-result &lt; 0 "
+      >XPath syntax error. Extra right square bracket. Suggestion: remove ']'.
+      <xsl:value-of select=" normalize-space($string)"/></xsl:when>
+
+  </xsl:choose>       
+ 
+ 
+ 
+</xsl:template> 
+
+
+<!--  STRIP XPATH STRINGS -->
+<xsl:template name="sch-check:strip-strings">
+  <xsl:param name="string" />
+  <xsl:param name="mode" />
+  
+  <!-- 
+    mode 0 =  outside string 
+    mode 1 = in double quote string 
+    mode 2 = in single quote string
+  -->
+  <xsl:choose>
+     <xsl:when test=" string-length( $string) = 0" />
+     <xsl:when test="$mode = 1 ">
+      <xsl:choose> 
+          
+          
+           <xsl:when test="starts-with( $string, '&quot;&quot;') " >
+       
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 3 )"/>
+            	<xsl:with-param name="mode" select=" $mode" />
+         	</xsl:call-template>
+           </xsl:when> 
+           <xsl:when test="starts-with( $string, '&quot;') " >
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" 0 " />
+         	</xsl:call-template>
+           </xsl:when>  
+            
+           <xsl:otherwise>
+         	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" $mode " />
+         	</xsl:call-template>
+         </xsl:otherwise>
+         </xsl:choose>
+     </xsl:when>
+     
+     <xsl:when test="$mode = 2 ">
+      <xsl:choose> 
+     
+          <!-- doubled double quote or double apos is an escape  -->
+          <xsl:when test="starts-with( $string, &quot;''&quot;) " >
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 3 )"/>
+            	<xsl:with-param name="mode" select=" $mode" />
+         	</xsl:call-template>
+           </xsl:when>   
+           <xsl:when test="starts-with( $string, &quot;'&quot; )" >
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" 0 " />
+         	</xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+         	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" $mode " />
+         	</xsl:call-template>
+         </xsl:otherwise>
+         </xsl:choose>
+     </xsl:when>
+     
+     <xsl:otherwise> <!-- mode = 0 -->
+         <xsl:choose>
+           <xsl:when test="starts-with( $string, '&quot;')" >
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" 1 " />
+         	</xsl:call-template>
+           </xsl:when> 
+     
+           <xsl:when test="starts-with( $string, &quot;'&quot; )" >
+           	<xsl:call-template name="sch-check:strip-strings">
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" 2 " />
+         	</xsl:call-template>
+           </xsl:when>
+           <xsl:otherwise>
+         	  <xsl:value-of select="substring( $string, 1, 1)" />
+         	  <xsl:call-template name="sch-check:strip-strings">
+         	 
+            	<xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            	<xsl:with-param name="mode" select=" $mode " />
+         	</xsl:call-template>
+         </xsl:otherwise>
+         </xsl:choose>
+     </xsl:otherwise>
+  </xsl:choose>
+  
+  
+</xsl:template>  
+ 
+ <!--  COUNT THE NUMBER OF UNMATCHED PARENTHESES -->
+ <!-- Limitation: Does not check balancing. -->
+ 
+<xsl:template name="sch-check:test-paren">
+  <xsl:param name="string" /> 
+  <xsl:param name="count"  />
+
+  <xsl:choose>
+     <xsl:when test=" string-length( $string) = 0">
+         <xsl:value-of select=" $count " />
+    </xsl:when>
+    <xsl:when test=" starts-with( $string, '(') ">
+         <xsl:call-template name="sch-check:test-paren">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )" />
+            <xsl:with-param name="count" select="  $count + 1 " />
+         </xsl:call-template>
+    </xsl:when>
+    <xsl:when test=" starts-with( $string, ')') ">
+         <xsl:call-template name="sch-check:test-paren">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            <xsl:with-param name="count" select="$count - 1 " />
+         </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+         <xsl:call-template name="sch-check:test-paren">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            <xsl:with-param name="count" select=" $count " />
+         </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>            
+
+
+</xsl:template>
+
+
+ <!--  COUNT THE NUMBER OF SQUARE BRACKETS -->
+ <!-- Limitation: Does not check balancing. -->
+<xsl:template name="sch-check:test-sqb">
+  <xsl:param name="string" /> 
+  <xsl:param name="count"  />
+
+  <xsl:choose>
+     <xsl:when test=" string-length( $string) = 0">
+         <xsl:value-of select=" $count " />
+    </xsl:when>
+    <xsl:when test=" starts-with( $string, '[') ">
+         <xsl:call-template name="sch-check:test-sqb">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )" />
+            <xsl:with-param name="count" select="  $count + 1 " />
+         </xsl:call-template>
+    </xsl:when>
+    <xsl:when test=" starts-with( $string, ']') ">
+         <xsl:call-template name="sch-check:test-sqb">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            <xsl:with-param name="count" select="$count - 1 " />
+         </xsl:call-template>
+    </xsl:when>
+    <xsl:otherwise>
+         <xsl:call-template name="sch-check:test-sqb">
+            <xsl:with-param name="string" select="  substring ( $string, 2 )"/>
+            <xsl:with-param name="count" select=" $count " />
+         </xsl:call-template>
+    </xsl:otherwise>
+  </xsl:choose>            
+
+
+</xsl:template>
+
+
+
+
+
+</xslt:stylesheet>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_message_xslt2.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_message_xslt2.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_message_xslt2.xsl	(revision 1843)
@@ -0,0 +1,55 @@
+<?xml version="1.0" ?><?xar XSLT?>
+<!-- Implmentation for the Schematron XML Schema Language.
+	http://www.ascc.net/xml/resource/schematron/schematron.html
+ 
+ Copyright (c) 2000,2001 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+
+<!-- Schematron message -->
+
+<xsl:stylesheet
+   version="2.0"
+   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+   xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
+
+<xsl:import href="iso_schematron_skeleton_for_saxon.xsl"/>
+
+<xsl:template name="process-prolog">
+   <axsl:output method="text" />
+</xsl:template>
+
+<!-- use default rule for process-root:  copy contens / ignore title -->
+<!-- use default rule for process-pattern: ignore name and see -->
+<!-- use default rule for process-name:  output name -->
+<!-- use default rule for process-assert and process-report:
+     call process-message -->
+
+<xsl:template name="process-message">
+   <xsl:param name="pattern" />
+   <xsl:param name="role" />
+   <axsl:message>
+      <xsl:apply-templates mode="text"  
+      /> (<xsl:value-of select="$pattern" />
+      <xsl:if test="$role"> / <xsl:value-of select="$role" />
+      </xsl:if>)</axsl:message>
+</xsl:template>
+
+</xsl:stylesheet>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl	(revision 1843)
@@ -0,0 +1,2299 @@
+<?xml version="1.0"?><?xar XSLT?>
+
+<!-- 
+   OVERVIEW
+   
+   ASCC/Schematron.com Skeleton Module for ISO Schematron (for XSLT2 systems)
+   
+   ISO Schematron is a language for making assertion about the presence or absense
+   of patterns in XML documents. It is typically used for as a schema language, or
+   to augment existing schema languages, and to check business rules. It is very
+   powerful, yet quite simple: a developer only need know XPath and about five other
+   elements.
+   
+   This is an open source implementation of ISO Schematron in XSLT. Although ISO does
+   not allow reference implementations which might compete with the text of the
+   standard, this code has been compiled by Rick Jelliffe, inventor of Schematron
+   and editor of the ISO standard; so developers can certainly use it as an 
+   unofficial reference implementation for clarification. 
+   
+   This implementation is based on one by Oliver Becker. API documentation is 
+   available separately; try www.schematron.com for this. Funding for this
+   stylesheet over the years has come from Topologi Pty. Ltd., Geotempo Ltd.,
+   and ASCC, Tapei.
+   
+   There are two versions of this skeleton: one is tailored for XSLT1 processors
+   and the other is tailored for XSLT2 processors. Future versions of the
+   XSLT2 skeleton may support more features than that the XSLT 1 skeleton.
+-->
+<!--
+   TIPS
+      
+   A tip for new users of Schematron: make your assertions contain positive messages
+   about what is expected, rather than error messages. For example, use the form
+   "An X should have a Y, because Z". 
+   
+   Another tip is that Schematron provides an
+   element <iso:ns> for declaring the namespaces and prefixes used in Xpaths in 
+   attribute values; it does not extend the XML Namespaces mechanism: if a name
+   in an XPath has a prefix, there must be an <iso:ns> element for that prefix; if
+   a name in an XPath does not have a prefix, it is always in no namespace.
+   
+   A tip for implementers of Schematron, either using this API or re-implementing it:
+   make the value of the diagnostics, flags and richer features available if possible;
+   Schematron has many of the optional richer features which, if implemented, provide
+   a compelling alternative approach to validation and business-rules checking compared
+   to other schema languages and programs. 
+   
+   If you create your own meta-stylesheet to override this one, it is a
+   good idea to have both in the same directory and to run the stylesheet
+   from that directory, as many XSLT implementations have ideosyncratic
+   handling of URLs: keep it simple.
+-->
+ 
+
+<!--
+  INVOCATION INFORMATION
+  
+  The following parameters are available
+  
+    phase           NMTOKEN | "#ALL" (default) Select the phase for validation
+    allow-foreign   "true" | "false" (default)   Pass non-Schematron elements to the generated stylesheet 
+    sch.exslt.imports semi-colon delimited string of filenames for some EXSLT implementations  
+    message-newline "true" (default) | "false"   Generate an extra newline at the end of messages 
+    debug	    "true" | "false" (default)  Debug mode lets compilation continue despite problems
+    attributes "true" | "false"  (Autodetecting) Use only when the schema has no attributes as the context nodes
+    only-child-elements "true" | "false" (Autodetecting) Use only when the schema has no comments
+    or PI  as the context nodes
+    langCode		ISO language code      language for skeleton errors, if available
+    terminate= yes | no | true | false | assert  Terminate on the first failed assertion or successful report
+                                         Note whether any output at all is generated depends on the XSLT implementation.
+                                         
+  The following parameters can be specified as Schematron variables in diagnostics, assertions and so on.
+    fileNameParameter string	  
+    fileDirParameter string				
+    archiveNameParameter string	  In case of ZIP files
+    archiveDirParameter string	  In case of ZIP files	 
+    
+ Experimental: USE AT YOUR OWN RISK   
+    visit-text "true" "false"   Also visist text nodes for context. WARNING: NON_STARDARD.
+    select-contents '' | 'key' | '//'   Select different implementation strategies
+ 
+ Conventions: Meta-stylesheets that override this may use the following parameters
+    generate-paths=true|false   generate the @location attribute with XPaths
+    full-path-notation = 1|2|3  select the notation for the full paths: 1=computer, 2=human, 3=obsolescent
+    diagnose= yes | no    Add the diagnostics to the assertion test in reports
+ 
+-->
+
+<!-- 
+  XSLT VERSION SUPPORT
+
+  XSLT 1:
+     A schema using the standard XSLT 1 query binding will have a /schema/@queryBinding='xslt' or 
+     nothing.
+
+       * Note: XT does not implement key() and will die if given it. 
+       * Add all formal parameters to default templates
+       * Fix missing apply-templates from process-ns and add params back
+
+  EXSLT:  Experimental support
+     A schema using the EXSLT query binding will have a /schema/@queryBinding='exslt'.
+     It is built on XSLT 1. After experience is gained, this binding is expected to be 
+     formalized as part of ISO Schematron, which currently reserves the "exslt" name for this purpose.
+
+     Some EXSLT engines have the extra functions built-in. For these, there is no need to
+     provide library locations. For engines that require the functions, either hard code
+     them in this script or provide them on the command-line argument.
+      
+  XSLT 2:   Experimental support
+     A schema using the XSLT 2 query binding will have a /schema/@queryBinding='xslt2'.
+     This binding is expected to be formalized as part of ISO
+     Schematron, which currently reserves the "xslt2" name for this purpose.
+     The xsl:import-schema, xsl:key and xsl:function elements are allowed as top elements. 
+     
+  XPATH:    Experimental support
+     A schema using the XPATH query binding will have a /schema/@queryBinding='xpath'.
+     It can run with XSLT 1 and is a strict superset of default ISO Schematron. After
+     experience is gained, this binding is expected to be formalized as part of ISO
+     Schematron, which currently reserves the "xpath" name for this purpose.
+
+     The intent of this query binding is to support minimal non-XSLT implementations of 
+     Schematron that use simple XPath APIs. These not only have fewer functions available
+     than the XSLT version of XPath, but some of them do not support variables. 
+     Consequently, in this binding, the <let> element and command-line variables passed
+     to the schema should not be used? 
+     The xsl:import-schema element is not allowed.
+     
+-->
+<!--
+   PROCESS INFORMATION
+   
+   This stylesheet compiles a Schematron schema (*.sch) into XSLT code (*.xsl). 
+   The generated XSLT code can then be run against an XML file (*.xml, etc) and
+   will produce validation results.
+   
+   The output of validation results is performed using named templates (process-*). 
+   These can be overridden easily by making a new XSLT stylesheet that imports this 
+   stylesheet but has its own version of the relevant process-* templates. Several
+   of these invoking stylesheets are available: "iso_svrl.xsl", for example generates
+   ISO Schematron Validation Report Language format results.
+   
+   In this version of the stylesheet, the ISO feature called "abstract patterns" is
+   implemented using macro processing: a prior XSLT stage to which converts uses
+   of abstract patterns into normal patterns. If you do not use abstract patterns,
+   it is not necessary to preprocess the schema.
+   
+   To summarize, a basic process flow for some commandline processor is like this:
+     XSLT -input=xxx.sch  -output=xxx.xsl  -stylesheet=iso_schematron_skeleton.xsl
+     XSLT -input=document.xml  -output=xxx-document.results  -stylesheet=xxx.xsl
+   
+   iso_svrl.xslt is an implementation of Schematron that can use this skeleton and
+   generate ISO SVRL reports. A process flow for some commandline processor would
+   be like this:
+     XSLT -input=xxx.sch  -output=xxx.xsl  -stylesheet=iso_svrl.xsl
+     XSLT -input=document.xml  -output=xxx-document.results  -stylesheet=xxx.xsl
+     
+   It is not impossible that ultimately a third stage, to handle macro-preprocessing
+   and inclusion, might be necessary. (The trade-off is in making this XSLT more
+   complex compared to making the outer process more complex.)
+             
+  This version has been developed to work with 
+     Saxon 9
+  For versions for XSLT 1 processors, see www.xml.com
+
+ Please note that if you are using SAXON and JAXP, then you should use 
+  System.setProperty("javax.xml.transform.TransformerFactory",
+                          "net.sf.saxon.TransformerFactoryImpl");
+ rather than 
+  System.setProperty("javax.xml.xpath.TransformerFactory",
+                           "net.sf.saxon.TransformerFactoryImpl");
+ which is does not work, at least for the versions of SAXON we tried.
+-->
+<!--
+ LEGAL INFORMATION
+ 
+ Copyright (c) 2000-2010 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+<!--
+  VERSION INFORMATION
+     2010-04-14
+     	* RJ Reorder call-template in exslt case only, report by BD
+        * Add command line parameter 'terminate' which will terminate on first failed 
+        assert and (optionally) successful report. 
+     2010-01-24
+     	* RJ Allow let elements to have direct content instead of @value 
+     2009-08020 
+        * RJ Give better scoping to resolution of abstract rules
+     2009-07-07
+     	* RJ Fix up warning on looking for @* on root  TODO CHECK!!!!
+     2009-05-10 
+     	* RJ Fix up incorrect use of tunnel
+     2009-02-25 
+        * RJ Fix up variable names so none are used twice in same template
+      2009-02-19
+        * RJ add experimental support for pattern/@documents 
+        This takes an XPath that returns a sequence of strings, treats them as 
+        relative URI references, and goes through these. It may need to be expanded
+        to allow absolute paths.
+    2008-09-19 RJ
+        * Add mode schematron-select-full-path and param full-path-notation 
+        
+   2008-08-19
+   		* RJ Add experimental property element.
+   		This acts like the diagnostics element. An attribute rule/@properties,
+   		assert/@properties and report/@properties can contain a list of ids
+   		which reference a /schema/proporties/property/@id. This is a property
+   		which will be carried over to the output, eg SVRL. It can have @name,
+   		and the value is @value or the contents. Properties on rules are 
+   		properties regardless of validation: they should apply to the subject
+   		element. Properties on asserts and reports only make it through in the
+   		negative case, at the moment, so they are really just a place to hold
+   		structured info, eg. for diagnostics. The properties mechanism addresses
+   		a bother with Schematron, that you have to post-process the document to
+    	get any kind of structured data that might be nice in the output report. 
+   		 
+   		
+   2008-08-14
+   		* RJ move all messages into localization strings, add langCode parameter, 
+   		named template to call external file in same directory as this xslt.
+   		The file should be called sch-message-$langCode.xhtml ($langCode example "en")
+  
+   2008-08-11
+   		* TT report/@flag was missing
+   2008-08-06
+   		* TT Top-level lets need to be implemented using xsl:param not xsl:variable
+   		* TT xsl:param/@select must have XPath or not be specified
+   		
+   2008-08-04 
+   		* RJ add saxon namespace to output to allow extension functions
+   Version: 2008-07-28
+   		* KH schematron-get-full-path-3 has [index] even on top step
+   Version: 2008-07-24
+   		* RJ clean out commented out namespace handling code 
+   		* RJ allow schema/@queryBinding='xpath2' and warn if variables are
+   		used
+   		
+   Version: 2008-07-14 update for XSLT2 and inclusion experiments
+   		* RJ Clean up zero-length fragment test on include
+   		* RJ Add experimental support for include containers
+   		* RJ Add support for xsl:import-schema (request Paul Hermans)
+   		* RJ Add support for xsl:function
+   		* RJ For path generation, test for //iso:schema not just /iso:schema, for potential embedded Schematron support
+   		* RJ Don't generate double error messages for old namespace elements
+   		* RJ Experimental iso:rule/iso:title just kept as comment (bigger request Uche Ogbuji)
+   		* RJ Fix bug that prevented including patterns in this (report Roger
+   	Costello)
+   Version: 2007-10-17
+     Forked out version just to support SAXON 8 and potentially other XSLT2 processors.
+       * RJ use xsl:namespace element
+       * RJ use schold as namespace for old schematron, to prevent SAXON complaining
+         when validating the Schematron schema for Schematron
+       * RJ fix FULL-PATH for attributes
+
+   Version: 2007-07-19
+     Accept most changes in David Carlisle's fork, but continue as XSLT1 script: 
+    	http://dpcarlisle.blogspot.com/search/label/schematron
+    	* DPC Remove "optimize" parameter
+    	* DPC Add autodetecting optimize parameter attribute to skip checking attribute
+    	context
+    	* DPC Add autodetecting optimize parameter only-child-elements turn off checking for 
+    	comments and PIs
+    	* DPC (Experimental: NON_STANDARD DANGER!) Add param visit-text to viist text
+    	nodes too for context 
+    	* DPC Fix inclusion syntax to allow #
+    	* DPC Priorities count up from 1000 not down from 4000 to allow more rules
+        * RJ Add new template for titles of schemas, with existing behaviour.  
+        Override process-schema-title for custom processing of title
+    		
+    
+   Version: 2007-04-04
+   	* RJ debug mode param
+	* RJ alter mixed test to only test mixed branches, so the same document
+	could have old and new namespaces schemas in it, but each schema must
+	be distinct, just so as not to overconstrain things.
+   	* KH zero-length include/@href is fatal error, but allow debug mode
+	* SB add hint on SAXON and JAXP
+	* DC generate-full-path-1 generates XLST1 code by default
+   Version: 2007-03-05
+      	* AS Typo for EXSLT randome, improve comment
+      	* KH get-schematron-full-path-2 needs to apply to attributes too
+      	* DP document policy on extensions better
+      	* DC use copy-of not copy for foreign elements
+      	* DC add generate-path-2
+      	* DC don't try to apply templates to attribute axis on attribute nodes, to
+      	stop SAXON warning.
+      	* RJ improve reporting of typos 
+   
+   Version: 2007-02-08
+   		* KH Schematron fullpath implementation: @* handled twice and / missing
+   		* KH Change stylesheetbody from named template to mode to allow implementers more flexibility.
+   		  Move process-ns to outside the stylesheet body.
+   		* DP, FG, fix handling of xslt:key
+   		* FG no iso:title/@class
+   		* Experimental optimization 'visit-no-attributes'
+   		* KH Experimental added schematron-get-full-path-2 which gives prefixed version for humans
+ 		* DC Move stylesheet/@version generation to after namespace handling
+ 		* DC, FG EXSLT namespace handling code
+ 		* FG add ref and commented code from FG's page on namespaces
+ 		* Start adding normalize-space() to parameter code
+ 		* Add a space between diagnostics
+   		   		 
+   Version: 2007-01-22
+   	* DP change = ($start) to = $start and =($phase) to =$phase 
+   	to run under Saxon 8.8j
+	* FG better title section using ( @id | iso:title)[last()]
+	* Default query language binding is "xslt" not "xslt1"
+  
+   Version: 2007-01-19
+   		* Simplify message newline code
+   		* Remove termination and xpath appending to message options: 
+   		   factor out as  iso_schematron_terminator.xsl
+   		* Comment out XSLT2 namespace fix temporarily
+  
+   Version: 2007-01-18 (First beta candidate for comment)
+          * DC remove xml:space="preserve"
+          * FG improve comment on import statement
+          * DC improve comments on invocation section
+          * Add exploratory support for iso:schema[@queryBinding='xpath']
+             by allowing it and warning as lets are found
+          * Be strict about queryBinding spelling errors
+          * Extra comments on the different queryBindings
+          * KH Add option "message-paths" to generate XPath from output 
+          * KH Add option "terminate" to halt with an error after the first assertion
+          * KH refactor paths in schematron-full-path
+          * Improve (?) namespace handling: no dummy attributes for prefix "xsl" generated
+   
+   Version: 2007-01-15
+          * FG fix for calling templates
+          * Add formal parameters to default templates: may help XSLT 2
+          * Fix get-schematron-full-path
+          * Include skeleton1-6 is commented out by default
+
+   Version:2007-01-12 (Pre-beta release to Schematron-love-in maillist)
+           * Add many extra parameters to the process-* calls, so that almost
+           all the information in the schema can be provided to client programs.
+           Also, rearrange the parameters to fit in with the ISO schema, which
+           has "rich" and "linkable" attribute groups.
+           * Warn on diagnostics with no ID once only
+           * Improved path reporting, to handle for namespaces
+           * Add process-title dummy template for API
+           * Add command-line parameter allow-foreign (true|false) to suppress
+            warnings one foreign elements and pass them through to the generated
+            stylesheet
+           * remove legacy templates for the old ASCC namespace and no namespace, 
+              and use an import statement instead. Much cleaner now!
+           * patterns use @id not @name
+           * titles can contain sub-elements
+           * start change iso:rule to allow attributes, PIs and comments 
+           * the default process-* for inline elements add a leading and trailing 
+             space, to reduce the chance of concatenation.
+           * add comments to make the generated code clearer
+           
+   Version:2006-11-07 (ISO: first release private to schematron-love-in maillist for review)
+           * Duplicate pattern templates, for handling ISO namespace
+           * Add priority onto default and paragraph templates
+           * Add namespace checks
+           * Handle key in xsl namespace not iso
+           * Add include
+           * Improve namespace handling
+           * Preliminary XSLT2 and EXSLT support
+	       * Refactor iso:schema for clarity
+
+    Version: 2003-05-26 
+    	    * Fix bug with key 
+    Version: 2003-04-16
+    	   * handle 1.6 let expressions
+    	   * make key use XSLT names, and allow anywhere
+    Version: 2001-06-13
+           * same skeleton now supports namespace or no namespace
+           * parameters to handlers updated for all 1.5 attributes 
+           * diagnostic hints supported: command-line option diagnose=yes|no
+           * phases supported: command-line option phase=#ALL|...
+           * abstract rules
+           * compile-time error messages  
+	   * add utility routine generate-id-from-path
+          
+    Contributors: Rick Jelliffe (original), Oliver Becker (architecture, XSLT2), 
+             Miloslav Nic (diagnostic, phase, options), Ludwig Svenonius (abstract)
+             Uche Ogbuji (misc. bug fixes), Jim Ancona (SAXON workaround),
+	 	     Francis Norton (generate-id-from-path), Robert Leftwich, Bryan Rasmussen,
+             Dave Pawson (include, fallback), Florent Georges (namespaces, exslt, attribute
+             context), Benoit Maisonny (attribute context), John Dumps (process-message newline),
+             Cliff Stanford (diagnostics and other newlines)
+
+    
+      
+    
+    KNOWN TYPICAL LIMITATIONS:
+      * Don't use <iso:ns prefix="xsl" .../> with a namespace other than the standard
+      XSLT one. This would be a bizarre thing to do anyway. 
+      * Don't use other prefixes for the XSLT namespace either; some implementations will
+      not handle it correctly.
+     
+     EXTENSIONS:
+      ISO Schematron is designed as a framework with some standard query language
+      bindings. If you need to support other features, please do so safely by making
+      up your own @queryLanguage name: this makes it clear that your schema requires
+      special features. For example, default ISO Schematron does not support user
+      defined functions; so if you want to use the user defined function feature
+      in XSLT, you need to have a schema with some queryBinding attribute name like
+      "XSLT-with-my-functions" or whatever.
+-->
+
+
+
+
+<xsl:stylesheet  
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+	xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias" 
+    xmlns:schold="http://www.ascc.net/xml/schematron"
+    xmlns:iso="http://purl.oclc.org/dsdl/schematron" 
+    xmlns:exsl="http://exslt.org/common" 
+    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    extension-element-prefixes="exsl"
+    version="2.0"
+	 >
+<!-- This program implements ISO Schematron, except for abstract patterns 
+which require a preprocess.
+-->
+  
+
+<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
+
+
+<!-- Category: top-level-element -->
+<xsl:output method="xml" omit-xml-declaration="no" standalone="yes"  indent="yes"/>
+
+
+
+<xsl:param name="phase">
+   <xsl:choose>   
+    <xsl:when test="//iso:schema/@defaultPhase">
+      <xsl:value-of select="//iso:schema/@defaultPhase"/>
+    </xsl:when>
+    <xsl:otherwise>#ALL</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<xsl:param name="allow-foreign">false</xsl:param>
+
+<xsl:param name="message-newline">true</xsl:param>
+
+<!-- DPC set to true if contexts should be checked on attribute nodes
+         defaults to true if there is any possibility that a context could match an attribute,
+         err on the side if caution, a context of *[.='@'] would cause this param to defualt to true
+         even though @ is in a string
+-->
+<xsl:param name="attributes">
+  <xsl:choose>
+    <xsl:when test="//iso:rule[contains(@context,'@') or contains(@context,'attribute')]">true</xsl:when>
+    <xsl:otherwise>false</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<!-- DPC set to true if contexts should be checked on just elements in the child axis
+         defaults to true if there is any possibility that a context could match an comment or PI
+         err on the side if caution, a context of *[.='('] would cause this param to defualt to true
+         even though ( is in a string, but node() comment() and processing-instruction()  all have a (
+-->
+<xsl:param name="only-child-elements">
+  <xsl:choose>
+    <xsl:when test="//iso:rule[contains(@context,'(')]">true</xsl:when>
+    <xsl:otherwise>false</xsl:otherwise>
+  </xsl:choose>
+</xsl:param>
+
+<!-- DPC set to true if contexts should be checked on text nodes nodes (if only-child-elements is false)
+         THIS IS NON CONFORMANT BEHAVIOUR JUST FOR DISCUSSION OF A POSSIBLE CHANGE TO THE
+         SPECIFICATION. THIS PARAM SHOULD GO IF THE FINAL DECISION IS THAT THE SPEC DOES NOT CHANGE.
+	 Always defaults to false
+-->
+<xsl:param name="visit-text" select="'false'"/>
+
+<!-- DPC
+  When selecting contexts the specified behaviour is
+    @*|node()[not(self::text())]
+    The automatic settings may use
+      node()[not(self::text())]
+      @*|*
+      *
+  instead for schema for which they are equivalent.
+  If the params are set explictly the above may be used, and also either if
+      @*
+      @*|node()
+   in all cases the result may not be equivalent, for example if you specify no attributes and the schema 
+   does have attribute contexts they will be silently ignored.
+
+  after testing it turns out that
+  node()[not(self::text())] is slower in saxon than *|comment()|processing-instruction() 
+  which I find a bit surprising but anyway I'll use the longr faster version.
+-->
+<xsl:variable name="context-xpath">
+  <xsl:if test="$attributes='true' and parent::node() ">@*|</xsl:if>
+  <xsl:choose>
+    <xsl:when test="$only-child-elements='true'">*</xsl:when>
+    <xsl:when test="$visit-text='true'">node()</xsl:when>
+    <xsl:otherwise>*|comment()|processing-instruction()</xsl:otherwise>
+  </xsl:choose>
+</xsl:variable>
+
+<!-- DPC if this is set to 
+    '' use recursive templates to iterate over document tree,
+    'key' select  all contexts with a key rather than walking the tree explictly in each mode
+    '//' select all contexts with // a key rather than walking the tree explictly in each mode (XSLT2 only)
+-->
+<xsl:param name="select-contexts" select="''"/>
+
+
+<!-- e.g. saxon file.xml file.xsl "sch.exslt.imports=.../string.xsl;.../math.xsl" -->
+<xsl:param name="sch.exslt.imports"/>
+
+<xsl:param name="debug">false</xsl:param>
+
+<!-- Set the language code for messages -->
+<xsl:param name="langCode">default</xsl:param>
+
+<!-- Set the default for schematron-select-full-path, i.e. the notation for svrl's @location-->
+<xsl:param name="full-path-notation">1</xsl:param>
+
+<xsl:param name="terminate">false</xsl:param>
+
+<!-- Simple namespace check -->
+<xsl:template match="/">
+    <xsl:if  test="//schold:*[ancestor::iso:* or descendant::iso:*]">
+    
+	<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">1</xsl:with-param></xsl:call-template></xsl:message>
+ 
+    </xsl:if>
+
+    <xsl:apply-templates />
+</xsl:template>
+
+
+<!-- ============================================================== -->
+<!-- ISO SCHEMATRON SCHEMA ELEMENT  -->
+<!-- Not handled: Abstract patterns. A pre-processor is assumed. -->
+<!-- ============================================================== -->
+
+<!-- SCHEMA -->
+<!-- Default uses XSLT 1 -->
+<xsl:template match="iso:schema[not(@queryBinding) or @queryBinding='xslt' 
+     or @queryBinding='xslt1' or @queryBinding='XSLT' or @queryBinding='XSLT1'
+     or @queryBinding='xpath']">
+     <xsl:if test="
+	     @queryBinding='xslt1' or @queryBinding='XSLT' or @queryBinding='XSLT1'">
+	     <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">2</xsl:with-param></xsl:call-template></xsl:message>
+	</xsl:if>
+	<axsl:stylesheet>
+	    <xsl:apply-templates 
+		select="iso:ns" />
+
+	    <!-- Handle the namespaces before the version attribute: reported to help SAXON -->
+	    <xsl:attribute name="version">1.0</xsl:attribute>
+	    
+		<xsl:apply-templates select="." mode="stylesheetbody"/>
+		<!-- was xsl:call-template name="stylesheetbody"/ -->
+	</axsl:stylesheet>
+</xsl:template>
+
+<!-- Using EXSLT with all modeles (except function module: not applicable) -->
+<xsl:template match="iso:schema[@queryBinding='exslt']" priority="10">
+    <xsl:comment>This XSLT was automatically generated from a Schematron schema.</xsl:comment>
+	<axsl:stylesheet
+ 	  	xmlns:date="http://exslt.org/dates-and-times"
+ 	  	xmlns:dyn="http://exslt.org/dynamic"
+		xmlns:exsl="http://exslt.org/common"
+		xmlns:math="http://exslt.org/math"
+   		xmlns:random="http://exslt.org/random"
+  		xmlns:regexp="http://exslt.org/regular-expressions"
+   		xmlns:set="http://exslt.org/sets"
+   		xmlns:str="http://exslt.org/strings"
+   		extension-element-prefixes="date dyn exsl math random regexp set str" >
+	
+        <xsl:apply-templates
+		select="iso:ns" />
+	    <!-- Handle the namespaces before the version attribute: reported to help SAXON -->
+	    <xsl:attribute name="version">1.0</xsl:attribute>
+	    
+	    <xsl:apply-templates select="." mode="stylesheetbody"/>
+		<!-- was xsl:call-template name="stylesheetbody"/ -->
+	</axsl:stylesheet>
+</xsl:template>
+
+<!-- Using XSLT 2 -->
+<xsl:template 
+	match="iso:schema[@queryBinding='xslt2' or @queryBinding ='xpath2']" 
+	priority="10">
+	<axsl:stylesheet
+	   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
+	   xmlns:saxon="http://saxon.sf.net/" 
+	   >
+        <xsl:apply-templates 
+		select="iso:ns" />
+	    <!-- Handle the namespaces before the version attribute: reported to help SAXON -->
+	    <xsl:attribute name="version">2.0</xsl:attribute>
+	    
+		<xsl:apply-templates select="." mode="stylesheetbody"/>
+		<!-- was xsl:call-template name="stylesheetbody"/ -->
+	</axsl:stylesheet>
+</xsl:template>
+
+
+<!-- Uses unknown query language binding -->
+<xsl:template match="iso:schema" priority="-1">
+	<xsl:message terminate="yes" ><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">3a</xsl:with-param></xsl:call-template>
+	<xsl:value-of select="@queryBinding"/>
+	<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">3b</xsl:with-param></xsl:call-template></xsl:message>        
+</xsl:template>
+
+<xsl:template match="*" mode="stylesheetbody">
+	<!--xsl:template name="stylesheetbody"-->
+    <xsl:comment>Implementers: please note that overriding process-prolog or process-root is 
+    the preferred method for meta-stylesheets to use where possible. </xsl:comment><xsl:text>&#10;</xsl:text>
+ 
+    <!-- These parameters may contain strings with the name and directory of the file being
+   validated. For convenience, if the caller only has the information in a single string,
+   that string could be put in fileDirParameter. The archives parameters are available
+   for ZIP archives.
+	-->
+    
+    <xsl:call-template name="iso:exslt.add.imports" /> <!-- RJ moved report BH -->
+	<axsl:param name="archiveDirParameter" />
+	<axsl:param name="archiveNameParameter" />
+	<axsl:param name="fileNameParameter"  />
+	<axsl:param name="fileDirParameter" /> 
+	
+       
+    <axsl:variable name="document-uri"><axsl:value-of select="document-uri(/)" /></axsl:variable>
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>PHASES</xsl:comment><xsl:text>&#10;</xsl:text>
+	<xsl:call-template name="handle-phase"/> 
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>PROLOG</xsl:comment><xsl:text>&#10;</xsl:text>
+	<xsl:call-template name="process-prolog"/> 
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>XSD TYPES FOR XSLT2</xsl:comment><xsl:text>&#10;</xsl:text>
+	<xsl:apply-templates mode="do-types"   select="xsl:import-schema"/>
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>KEYS AND FUNCTIONS</xsl:comment><xsl:text>&#10;</xsl:text>
+	<xsl:apply-templates mode="do-keys"   select="xsl:key | xsl:function "/>
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>DEFAULT RULES</xsl:comment><xsl:text>&#10;</xsl:text>
+    <xsl:call-template name="generate-default-rules" />
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>SCHEMA SETUP</xsl:comment><xsl:text>&#10;</xsl:text>
+    <xsl:call-template name="handle-root"/>
+    <xsl:text>&#10;&#10;</xsl:text><xsl:comment>SCHEMATRON PATTERNS</xsl:comment><xsl:text>&#10;</xsl:text>
+ 
+	<xsl:apply-templates select="*[not(self::iso:ns)] " />
+</xsl:template>
+ 
+    <xsl:template name="iso:exslt.add.imports">
+      <xsl:param name="imports" select="$sch.exslt.imports"/>
+      <xsl:choose>
+        <xsl:when test="contains($imports, ';')">
+          <axsl:import href="{ substring-before($imports, ';') }"/>
+          <xsl:call-template name="iso:exslt.add.imports">
+            <xsl:with-param name="imports"  select="substring-after($imports, ';')"/>
+          </xsl:call-template>
+        </xsl:when>
+        <xsl:when test="$imports">
+          <axsl:import href="{ $imports }"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:template>
+
+<xsl:template name="handle-phase" >
+    <!-- This just tests that the phase exists -->
+	<xsl:if test="not(normalize-space( $phase ) = '#ALL')">
+	  <xsl:if test="not(iso:phase[@id = normalize-space( $phase )])">
+		  <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">4a</xsl:with-param></xsl:call-template>
+		  <xsl:value-of select="normalize-space( $phase )"/>
+		  <xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">4b</xsl:with-param></xsl:call-template></xsl:message>
+	  </xsl:if>
+     </xsl:if>
+</xsl:template>
+
+<xsl:template name="generate-default-rules">
+		<xsl:text>&#10;&#10;</xsl:text>
+		<xsl:comment>MODE: SCHEMATRON-SELECT-FULL-PATH</xsl:comment><xsl:text>&#10;</xsl:text>
+		<xsl:comment>This mode can be used to generate an ugly though full XPath for locators</xsl:comment><xsl:text>&#10;</xsl:text>
+   		<axsl:template match="*" mode="schematron-select-full-path">
+   			<xsl:choose>
+   				<xsl:when test=" $full-path-notation = '1' ">
+   					<!-- Use for computers, but rather unreadable for humans -->
+					<axsl:apply-templates select="." mode="schematron-get-full-path"/>
+				</xsl:when>
+   				<xsl:when test=" $full-path-notation = '2' ">
+   					<!-- Use for humans, but no good for paths unless namespaces are known out-of-band -->
+					<axsl:apply-templates select="." mode="schematron-get-full-path-2"/>
+				</xsl:when>
+   				<xsl:when test=" $full-path-notation = '3' "> 
+   					<!-- Obsolescent. Use for humans, but no good for paths unless namespaces are known out-of-band -->
+					<axsl:apply-templates select="." mode="schematron-get-full-path-3"/>
+				</xsl:when>
+
+                   <xsl:otherwise >
+                       <!-- Use for computers, but rather unreadable for humans -->
+                    <axsl:apply-templates select="." mode="schematron-get-full-path"/>
+                </xsl:otherwise>
+			</xsl:choose>
+		</axsl:template>
+	
+
+		<xsl:text>&#10;&#10;</xsl:text>
+		<xsl:comment>MODE: SCHEMATRON-FULL-PATH</xsl:comment><xsl:text>&#10;</xsl:text>
+		<xsl:comment>This mode can be used to generate an ugly though full XPath for locators</xsl:comment><xsl:text>&#10;</xsl:text>
+   		<axsl:template match="*" mode="schematron-get-full-path">
+			<axsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
+			<xsl:choose>
+				<xsl:when test="//iso:schema[@queryBinding='xslt2']">
+					<!-- XSLT2 syntax -->
+			<axsl:text>/</axsl:text>		
+			<axsl:choose>
+      			<axsl:when test="namespace-uri()=''"><axsl:value-of select="name()"/></axsl:when>
+      			<axsl:otherwise>
+      				<axsl:text>*:</axsl:text>
+      				<axsl:value-of select="local-name()"/>
+      				<axsl:text>[namespace-uri()='</axsl:text>
+      				<axsl:value-of select="namespace-uri()"/>
+      				<axsl:text>']</axsl:text>
+      			</axsl:otherwise>
+    		</axsl:choose>
+    		<axsl:variable name="preceding" select=
+    		"count(preceding-sibling::*[local-name()=local-name(current())
+	  		                             and namespace-uri() = namespace-uri(current())])" />
+			<axsl:text>[</axsl:text>
+	  		<axsl:value-of select="1+ $preceding"/>
+	  		<axsl:text>]</axsl:text>
+		</xsl:when>
+
+		<xsl:otherwise>
+			<!-- XSLT1 syntax -->
+
+			<axsl:text>/</axsl:text>
+			<axsl:choose>
+			<axsl:when test="namespace-uri()=''">
+			<axsl:value-of select="name()"/>
+			<axsl:variable name="p_1" select="1+
+			count(preceding-sibling::*[name()=name(current())])" />
+		<axsl:if test="$p_1&gt;1 or following-sibling::*[name()=name(current())]">
+		  <xsl:text/>[<axsl:value-of select="$p_1"/>]<xsl:text/>
+		</axsl:if>
+		</axsl:when>
+		<axsl:otherwise>
+		<axsl:text>*[local-name()='</axsl:text>
+		<axsl:value-of select="local-name()"/>
+		<axsl:text>']</axsl:text>
+		<axsl:variable name="p_2" select="1+
+		count(preceding-sibling::*[local-name()=local-name(current())])" />
+		<axsl:if test="$p_2&gt;1 or following-sibling::*[local-name()=local-name(current())]">
+		  <xsl:text/>[<axsl:value-of select="$p_2"/>]<xsl:text/>
+		</axsl:if>
+		</axsl:otherwise>
+		</axsl:choose> 
+		</xsl:otherwise>
+
+	</xsl:choose>
+       	 	</axsl:template>
+       	 	
+       	 	
+		<axsl:template match="@*" mode="schematron-get-full-path">
+			<xsl:choose>
+				<xsl:when test="//iso:schema[@queryBinding='xslt2']">
+					<!-- XSLT2 syntax -->
+			<axsl:apply-templates select="parent::*" mode="schematron-get-full-path"/>
+      		<axsl:text>/</axsl:text>
+			<axsl:choose>
+      			<axsl:when test="namespace-uri()=''">@<axsl:value-of select="name()"/></axsl:when>
+      			<axsl:otherwise>
+      				<axsl:text>@*[local-name()='</axsl:text>
+      				<axsl:value-of select="local-name()"/>
+      				<axsl:text>' and namespace-uri()='</axsl:text>
+      				<axsl:value-of select="namespace-uri()"/>
+      				<axsl:text>']</axsl:text>
+      			</axsl:otherwise>
+    		</axsl:choose>
+	</xsl:when>
+
+		<xsl:otherwise>
+			<!-- XSLT1 syntax -->
+		<axsl:text>/</axsl:text>
+		<axsl:choose>
+		<axsl:when test="namespace-uri()=''">@<axsl:value-of
+		select="name()"/></axsl:when>
+		<axsl:otherwise>
+		<axsl:text>@*[local-name()='</axsl:text>
+		<axsl:value-of select="local-name()"/>
+		<axsl:text>' and namespace-uri()='</axsl:text>
+		<axsl:value-of select="namespace-uri()"/>
+		<axsl:text>']</axsl:text>
+		</axsl:otherwise>
+		</axsl:choose> 
+
+			</xsl:otherwise>
+			</xsl:choose>
+		</axsl:template>
+	
+	<xsl:text>&#10;&#10;</xsl:text>
+	
+	<xsl:comment>MODE: SCHEMATRON-FULL-PATH-2</xsl:comment>
+	<xsl:text>&#10;</xsl:text>
+	<xsl:comment>This mode can be used to generate prefixed XPath for humans</xsl:comment>
+	<xsl:text>&#10;</xsl:text>
+	<!--simplify the error messages by using the namespace prefixes of the
+     instance rather than the generic namespace-uri-styled qualification-->
+	<axsl:template match="node() | @*" mode="schematron-get-full-path-2">
+	<!--report the element hierarchy-->
+		<axsl:for-each select="ancestor-or-self::*">
+			<axsl:text>/</axsl:text>
+			<axsl:value-of select="name(.)"/>
+			<axsl:if test="preceding-sibling::*[name(.)=name(current())]">
+				<axsl:text>[</axsl:text>
+				<axsl:value-of
+					select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
+				<axsl:text>]</axsl:text>
+			</axsl:if>
+		</axsl:for-each>
+		<!--report the attribute-->
+		<axsl:if test="not(self::*)">
+			<axsl:text/>/@<axsl:value-of select="name(.)"/>
+		</axsl:if>
+	</axsl:template>
+
+
+	<xsl:comment>MODE: SCHEMATRON-FULL-PATH-3</xsl:comment>
+	
+	<xsl:text>&#10;</xsl:text>
+	<xsl:comment>This mode can be used to generate prefixed XPath for humans 
+	(Top-level element has index)</xsl:comment>
+	<xsl:text>&#10;</xsl:text>
+	<!--simplify the error messages by using the namespace prefixes of the
+     instance rather than the generic namespace-uri-styled qualification-->
+	<axsl:template match="node() | @*" mode="schematron-get-full-path-3">
+	<!--report the element hierarchy-->
+		<axsl:for-each select="ancestor-or-self::*">
+			<axsl:text>/</axsl:text>
+			<axsl:value-of select="name(.)"/>
+			<axsl:if test="parent::*">
+				<axsl:text>[</axsl:text>
+				<axsl:value-of
+					select="count(preceding-sibling::*[name(.)=name(current())])+1"/>
+				<axsl:text>]</axsl:text>
+			</axsl:if>
+		</axsl:for-each>
+		<!--report the attribute-->
+		<axsl:if test="not(self::*)">
+			<axsl:text/>/@<axsl:value-of select="name(.)"/>
+		</axsl:if>
+	</axsl:template>
+
+		<xsl:text>&#10;&#10;</xsl:text>
+		<xsl:comment>MODE: GENERATE-ID-FROM-PATH </xsl:comment><xsl:text>&#10;</xsl:text>
+		<!-- repeatable-id maker derived from Francis Norton's. -->
+		<!-- use this if you need generate ids in separate passes,
+		     because generate-id() is not guaranteed to produce the same
+		     results each time. These ids are not XML names but closer to paths. -->
+		<axsl:template match="/" mode="generate-id-from-path"/>
+		<axsl:template match="text()" mode="generate-id-from-path">
+			<axsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
+			<axsl:value-of select="concat('.text-', 1+count(preceding-sibling::text()), '-')"/>
+		</axsl:template>
+		<axsl:template match="comment()" mode="generate-id-from-path">
+			<axsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
+			<axsl:value-of select="concat('.comment-', 1+count(preceding-sibling::comment()), '-')"/>
+		</axsl:template>
+		<axsl:template match="processing-instruction()" mode="generate-id-from-path">
+			<axsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
+			<axsl:value-of 
+			select="concat('.processing-instruction-', 1+count(preceding-sibling::processing-instruction()), '-')"/>
+		</axsl:template>
+		<axsl:template match="@*" mode="generate-id-from-path">
+			<axsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
+			<axsl:value-of select="concat('.@', name())"/>
+		</axsl:template>
+		<axsl:template match="*" mode="generate-id-from-path" priority="-0.5">
+			<axsl:apply-templates select="parent::*" mode="generate-id-from-path"/>
+			<axsl:text>.</axsl:text>
+<!--
+			<axsl:choose>
+				<axsl:when test="count(. | ../namespace::*) = count(../namespace::*)">
+					<axsl:value-of select="concat('.namespace::-',1+count(namespace::*),'-')"/>
+				</axsl:when>
+				<axsl:otherwise>
+-->
+				<axsl:value-of 
+				select="concat('.',name(),'-',1+count(preceding-sibling::*[name()=name(current())]),'-')"/>
+<!--
+				</axsl:otherwise>
+			</axsl:choose>
+-->
+		</axsl:template>
+		
+		
+		<xsl:text>&#10;&#10;</xsl:text>
+		<xsl:comment>MODE: GENERATE-ID-2 </xsl:comment><xsl:text>&#10;</xsl:text>
+		<!-- repeatable-id maker from David Carlisle. -->
+		<!-- use this if you need generate IDs in separate passes,
+		     because generate-id() is not guaranteed to produce the same
+		     results each time. These IDs are well-formed XML NMTOKENS -->
+	<axsl:template match="/" mode="generate-id-2">U</axsl:template>
+
+	<axsl:template match="*" mode="generate-id-2" priority="2">
+		<axsl:text>U</axsl:text>
+		<axsl:number level="multiple" count="*"/>
+	</axsl:template>
+
+	<axsl:template match="node()" mode="generate-id-2">
+		<axsl:text>U.</axsl:text>
+		<axsl:number level="multiple" count="*"/>
+		<axsl:text>n</axsl:text>
+		<axsl:number count="node()"/>
+	</axsl:template>
+
+	<axsl:template match="@*" mode="generate-id-2">
+		<axsl:text>U.</axsl:text>
+		<axsl:number level="multiple" count="*"/>
+		<axsl:text>_</axsl:text>
+		<axsl:value-of select="string-length(local-name(.))"/>
+		<axsl:text>_</axsl:text>
+		<axsl:value-of select="translate(name(),':','.')"/>
+	</axsl:template> 
+		
+
+		<xsl:comment>Strip characters</xsl:comment>
+		<axsl:template match="text()" priority="-1" />
+			
+  </xsl:template>
+
+ <xsl:template name="handle-root">
+		<!-- Process the top-level element -->
+		<axsl:template match="/">
+			<xsl:call-template name="process-root">
+				<xsl:with-param 	
+				name="title" select="(@id | iso:title)[last()]"/>
+				<xsl:with-param name="version" select="'iso'" />
+				<xsl:with-param name="schemaVersion" select="@schemaVersion" />
+				<xsl:with-param name="queryBinding" select="@queryBinding" />
+				<xsl:with-param name="contents">
+					<xsl:apply-templates mode="do-all-patterns"/>
+				</xsl:with-param>
+				
+				<!-- "Rich" properties -->
+				<xsl:with-param name="fpi" select="@fpi"/>
+				<xsl:with-param name="icon" select="@icon"/>
+				<xsl:with-param name="id" select="@id"/>
+				<xsl:with-param name="lang" select="@xml:lang"/>
+				<xsl:with-param name="see" select="@see" />
+				<xsl:with-param name="space" select="@xml:space" />
+			</xsl:call-template>
+		</axsl:template>
+ 
+      
+</xsl:template>
+
+<!-- ============================================================== -->
+<!-- ISO SCHEMATRON ELEMENTS -->
+<!-- ============================================================== -->
+
+	<!-- ISO ACTIVE -->
+	<xsl:template match="iso:active">
+                <xsl:if test="not(@pattern)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">5</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+
+                <xsl:if test="not(../../iso:pattern[@id = current()/@pattern])
+                and not(../../iso:include)">
+                           <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">6a</xsl:with-param></xsl:call-template>
+                           <xsl:value-of select="@pattern"/>
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">6b</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+        </xsl:template>
+
+	<!-- ISO ASSERT and REPORT -->
+	<xsl:template match="iso:assert">
+  
+                <xsl:if test="not(@test)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">7</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+        <xsl:text>&#10;&#10;		</xsl:text>
+		<xsl:comment>ASSERT <xsl:value-of select="@role" /> </xsl:comment><xsl:text>&#10;</xsl:text>      
+	
+		<axsl:choose>
+			<axsl:when test="{@test}"/>
+			<axsl:otherwise>
+				<xsl:call-template name="process-assert">
+					<xsl:with-param name="test" select="normalize-space(@test)" />
+					<xsl:with-param name="diagnostics" select="@diagnostics"/>
+					<xsl:with-param name="flag" select="@flag"/>
+					
+					<xsl:with-param name="properties" select="@properties" />
+					
+					<!-- "Rich" properties -->
+					<xsl:with-param name="fpi" select="@fpi"/>
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="lang" select="@xml:lang"/>
+					<xsl:with-param name="see" select="@see" />
+					<xsl:with-param name="space" select="@xml:space" />
+					
+					<!-- "Linking" properties -->
+					<xsl:with-param name="role" select="@role" />
+					<xsl:with-param name="subject" select="@subject" />
+					 
+				</xsl:call-template>
+ 			 
+ 			
+			</axsl:otherwise>
+		</axsl:choose>
+	</xsl:template>
+	<xsl:template match="iso:report">
+		 
+                <xsl:if test="not(@test)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">8</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+                
+        <xsl:text>&#10;&#10;		</xsl:text>
+		<xsl:comment>REPORT <xsl:value-of select="@role" /> </xsl:comment><xsl:text>&#10;</xsl:text>      
+	
+		<axsl:if test="{@test}">
+		
+			<xsl:call-template name="process-report">
+				<xsl:with-param name="test" select="normalize-space(@test)" />
+				<xsl:with-param name="diagnostics" select="@diagnostics"/>
+					<xsl:with-param name="flag" select="@flag"/>
+				
+					<xsl:with-param name="properties" select="@properties" />
+					<!-- "Rich" properties -->
+					<xsl:with-param name="fpi" select="@fpi"/>
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="lang" select="@xml:lang"/>
+					<xsl:with-param name="see" select="@see" />
+					<xsl:with-param name="space" select="@xml:space" />
+					
+					<!-- "Linking" properties -->
+					<xsl:with-param name="role" select="@role" />
+					<xsl:with-param name="subject" select="@subject" />
+			</xsl:call-template>
+			 
+		</axsl:if>
+	</xsl:template>
+
+
+	<!-- ISO DIAGNOSTIC -->
+	<!-- We use a mode here to maintain backwards compatability, instead of adding it
+	     to the other mode.
+	-->
+	<xsl:template match="iso:diagnostic" mode="check-diagnostics">
+              <xsl:if test="not(@id)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">9</xsl:with-param></xsl:call-template></xsl:message>
+               </xsl:if>
+    </xsl:template>
+    
+    <xsl:template match="iso:diagnostic"  >
+                <xsl:call-template name="process-diagnostic">
+                
+					<!-- "Rich" properties -->
+					<xsl:with-param name="fpi" select="@fpi"/>
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="lang" select="@xml:lang"/>
+					<xsl:with-param name="see" select="@see" />
+					<xsl:with-param name="space" select="@xml:space" />
+               </xsl:call-template>
+                
+        </xsl:template>
+
+	<!-- ISO DIAGNOSTICS -->
+	<xsl:template match="iso:diagnostics" >
+		<xsl:apply-templates mode="check-diagnostics" select="*" />
+	</xsl:template>
+
+	<!-- ISO DIR -->
+	<xsl:template match="iso:dir"  mode="text" >
+		<xsl:call-template name="process-dir">
+			<xsl:with-param name="value" select="@value"/>
+		</xsl:call-template>
+	</xsl:template>
+
+	<!-- ISO EMPH -->
+	<xsl:template match="iso:emph"  mode="text">
+	 
+		<xsl:call-template name="process-emph"/> 
+
+	</xsl:template>
+
+	<!-- ISO EXTENDS -->
+	<xsl:template match="iso:extends">
+		<xsl:if test="not(@rule)">
+            <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">10</xsl:with-param></xsl:call-template></xsl:message>
+        </xsl:if>
+     	<xsl:if test="not(//iso:rule[@abstract='true'][@id= current()/@rule] )">
+            <xsl:message>
+                 <xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">11a</xsl:with-param></xsl:call-template>
+                 <xsl:value-of select="@rule"/>
+                 <xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">11b</xsl:with-param></xsl:call-template></xsl:message>
+        </xsl:if>
+	    <xsl:call-template name="IamEmpty" />
+
+        <xsl:choose>
+            <!-- prefer to use a locally declared rule -->
+            <xsl:when test="parent::*/parent::*/iso:rule[@id=current()/@rule]">
+    		    <xsl:apply-templates select="parent::*/parent::*/iso:rule[@id=current()/@rule]"
+				    mode="extends"/>
+            </xsl:when>
+            <!-- otherwise use a global one: this is not in the 2006 standard -->
+            <xsl:when test="//iso:rule[@id=current()/@rule]">
+    		    <xsl:apply-templates select="//iso:rule[@id=current()/@rule]"
+				    mode="extends"/>
+            </xsl:when>
+        </xsl:choose>
+ 
+
+	</xsl:template>
+
+	<!-- KEY: ISO has no KEY -->
+	<!-- NOTE: 
+	     Key has had a checkered history. Schematron 1.0 allowed it in certain places, but
+	     users came up with a different location, which has now been adopted. 
+	     
+	     XT, the early XSLT processor, did not implement key and died when it was present. 
+	     So there are some versions of the Schematron skeleton for XT that strip out all
+	     key elements.
+	     
+	     Xalan (e.g. Xalan4C 1.0 and a Xalan4J) also had a funny. A fix involved making 
+	     a top-level parameter called $hiddenKey and then using that instead of matching
+	     "key". This has been removed.
+	     
+	     Keys and functions are the same mode, to allow their declaration to be mixed up.
+	-->
+	<xsl:template  match="xsl:key" mode="do-keys" >
+	     <xsl:if test="not(@name)">
+              <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">12</xsl:with-param></xsl:call-template></xsl:message>
+         </xsl:if>
+                <xsl:if test="not(@path) and not(@use)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">13</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>         
+	     <xsl:choose>
+	     	<xsl:when test="parent::iso:rule ">
+	        <xsl:call-template name="IamEmpty" />
+	       <xsl:choose>
+	       	<xsl:when test="@path">
+				<axsl:key match="{../@context}" name="{@name}" use="{@path}"/>
+			</xsl:when>
+			<xsl:otherwise>
+							<axsl:key match="{../@context}" name="{@name}" use="{@use}"/>
+			</xsl:otherwise>
+			</xsl:choose>	
+		</xsl:when>
+		<xsl:otherwise>
+                <xsl:if test="not(@match) ">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">14</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>   		
+			<axsl:key>
+      			<xsl:copy-of select="@*"/>
+    		</axsl:key>	
+		</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+
+	<xsl:template match="xsl:key "  /><!-- swallow -->
+
+	<xsl:template match="iso:key "  >
+		<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">15</xsl:with-param></xsl:call-template></xsl:message>
+    </xsl:template>
+
+  <!-- XSL FUNCTION -->
+  <xsl:template  match="xsl:function" mode="do-keys" >
+	     <xsl:if test="not(@name)">
+              <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">16</xsl:with-param></xsl:call-template></xsl:message>
+         </xsl:if>      
+	     <xsl:copy-of select="."/>
+  </xsl:template>
+
+	<xsl:template match="xsl:function "  /><!-- swallow -->
+
+	<xsl:template match="iso:function "  >
+		<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">17</xsl:with-param></xsl:call-template></xsl:message>
+    </xsl:template>
+
+
+   <!-- ISO INCLUDE -->
+   <!-- This is only a fallback. Include really needs to have been done before this as a separate pass.-->
+
+   <xsl:template match="iso:include[not(normalize-space(@href))]"
+	   priority="1">
+	<xsl:if test=" $debug = 'false' ">
+		<xsl:message terminate="yes"><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">18</xsl:with-param></xsl:call-template></xsl:message>
+	</xsl:if>
+
+   </xsl:template>
+
+   <!-- Extend the URI syntax to allow # refererences -->
+   <!-- Note that XSLT2 actually already allows # references, but we override them because it
+   looks unreliable -->
+   <xsl:template match="iso:include">
+       <xsl:variable name="document-uri" select="substring-before(concat(@href,'#'), '#')"/>
+       <xsl:variable name="fragment-id" select="substring-after(@href, '#')"/>
+       
+       <xsl:choose> 
+          
+          <xsl:when test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0" >
+          	<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">19</xsl:with-param></xsl:call-template></xsl:message>
+          </xsl:when> 
+          
+          <xsl:when test="string-length( $fragment-id ) &gt; 0">
+              <xsl:variable name="theDocument_1" select="document( $document-uri,/ )" />
+              <xsl:variable name="theFragment_1" select="$theDocument_1//iso:*[@id= $fragment-id]" />
+              <xsl:if test="not($theDocument_1)">
+				<xsl:message terminate="no">
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">20a</xsl:with-param></xsl:call-template>
+					<xsl:value-of select="@href"/>
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">20b</xsl:with-param></xsl:call-template>
+				</xsl:message>
+			</xsl:if>
+              <xsl:if test=" $theFragment_1/self::iso:schema ">
+                 <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">21</xsl:with-param></xsl:call-template></xsl:message>
+              </xsl:if>
+              <xsl:apply-templates select=" $theFragment_1"/>
+		   </xsl:when>
+		  
+		   <xsl:otherwise>
+		   	  <!-- Import the top-level element if it is in schematron namespace,
+		   	  or its children otherwise, to allow a simple containment mechanism. -->
+              <xsl:variable name="theDocument_2" select="document( $document-uri,/ )" />
+              <xsl:variable name="theFragment_2" select="$theDocument_2/iso:*" />
+              <xsl:variable name="theContainedFragments" select="$theDocument_2/*/iso:*" />
+              <xsl:if test="not($theDocument_2)">
+				<xsl:message terminate="no">
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">20a</xsl:with-param></xsl:call-template>
+					<xsl:value-of select="@href"/>
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">20b</xsl:with-param></xsl:call-template>
+				</xsl:message>
+			</xsl:if>
+              <xsl:if test=" $theFragment_2/self::iso:schema or $theContainedFragments/self::iso:schema">
+                 <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">21</xsl:with-param></xsl:call-template></xsl:message>
+              </xsl:if>
+       		<xsl:apply-templates select="$theFragment_2 | $theContainedFragments "/>
+       	   </xsl:otherwise>
+       </xsl:choose>
+   </xsl:template>
+   
+   <!-- This is to handle the particular case of including patterns -->  
+   <xsl:template match="iso:include" mode="do-all-patterns">
+       <xsl:variable name="document-uri" select="substring-before(concat(@href,'#'), '#')"/>
+       <xsl:variable name="fragment-id" select="substring-after(@href, '#')"/>
+ 
+       <xsl:choose> 
+          
+          <xsl:when test="string-length( $document-uri ) = 0 and string-length( $fragment-id ) = 0" >
+          	<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">19</xsl:with-param></xsl:call-template></xsl:message>
+          </xsl:when> 
+          
+          <xsl:when test="string-length( $fragment-id ) &gt; 0">
+              <xsl:variable name="theDocument_1" select="document( $document-uri,/ )" />
+              <xsl:variable name="theFragment_1" select="$theDocument_1//iso:*[@id= $fragment-id ]" />
+              <xsl:if test=" $theFragment_1/self::iso:schema ">
+                 <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">21</xsl:with-param></xsl:call-template></xsl:message>
+              </xsl:if>
+              <xsl:apply-templates select=" $theFragment_1" mode="do-all-patterns"/>
+		   </xsl:when>
+		  
+		   <xsl:otherwise>
+		   	  <!-- Import the top-level element if it is in schematron namespace,
+		   	  or its children otherwise, to allow a simple containment mechanism. -->
+              <xsl:variable name="theDocument_2" select="document( $document-uri,/ )" />
+              <xsl:variable name="theFragment_2" select="$theDocument_2/iso:*" />
+              <xsl:variable name="theContainedFragments" select="$theDocument_2/*/iso:*" />
+              <xsl:if test=" $theFragment_2/self::iso:schema or $theContainedFragments/self::iso:schema">
+                 <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">21</xsl:with-param></xsl:call-template></xsl:message>
+              </xsl:if>
+       		<xsl:apply-templates select="$theFragment_2 | $theContainedFragments "
+       		mode="do-all-patterns" />
+       	   </xsl:otherwise>
+       </xsl:choose>
+   </xsl:template>
+   
+	
+	<!-- XSL IMPORT-SCHEMA -->
+	<!-- Importing an XSD schema allows the variour type operations to be available. -->
+	<xsl:template  match="xsl:import-schema" mode="do-types" >	 
+		<xsl:choose>
+		  <xsl:when test="ancestor::iso:schema[@queryBinding='xslt2']">
+		  	<xsl:copy-of select="." />
+		  </xsl:when>
+		<xsl:otherwise>
+			<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">22</xsl:with-param></xsl:call-template></xsl:message>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>  
+		   
+	<!-- swallow -->	   
+    <xsl:template match="xsl:import-schema" />
+ 
+	<xsl:template match="iso:import-schema "  >
+		<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">23</xsl:with-param></xsl:call-template></xsl:message>
+    </xsl:template>
+ 
+	<!-- ISO LET -->
+	<xsl:template match="iso:let" >
+	  <xsl:if test="ancestor::iso:schema[@queryBinding='xpath']">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">24</xsl:with-param></xsl:call-template></xsl:message>
+       </xsl:if>
+	  <xsl:if test="ancestor::iso:schema[@queryBinding='xpath2']">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">25</xsl:with-param></xsl:call-template></xsl:message>
+       </xsl:if>
+       
+       <!-- lets at the top-level are implemented as parameters unless they have contents -->
+       	<xsl:choose>
+       		<xsl:when test="parent::iso:schema">
+       			<!-- it is an error to have an empty param/@select because an XPath is expected -->
+	      			<xsl:choose>
+       				<xsl:when test="@value">
+	      				<axsl:param name="{@name}" select="{@value}">
+	      		 			<xsl:if test="string-length(@value) &gt; 0">
+	      		 				<xsl:attribute name="select"><xsl:value-of select="@value"/></xsl:attribute>
+	      		 			</xsl:if>
+	      		 		</axsl:param>
+	      		 	</xsl:when>
+	      		 	<xsl:otherwise>
+						<axsl:variable name="{@name}"  >
+						  <xsl:copy-of select="child::node()" />
+						</axsl:variable>
+	      		 	</xsl:otherwise> 
+	      		 </xsl:choose>
+       		</xsl:when>
+       		<xsl:otherwise>
+				
+       		    <xsl:choose>
+       		    	<xsl:when  test="@value">
+						<axsl:variable name="{@name}" select="{@value}"/>
+					</xsl:when>
+					<xsl:otherwise>
+						<axsl:variable name="{@name}"  >
+						  <xsl:copy-of select="child::node()" />
+						</axsl:variable>
+				   </xsl:otherwise>
+				 </xsl:choose>
+				  	
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>	
+
+	<!-- ISO NAME -->
+	<xsl:template match="iso:name" mode="text">
+	
+		<xsl:if test="@path">
+			<xsl:call-template name="process-name">
+				<xsl:with-param name="name" select="concat('name(',@path,')')"/>
+			</xsl:call-template>
+		</xsl:if>
+		<xsl:if test="not(@path)">
+			<xsl:call-template name="process-name">
+				<xsl:with-param name="name" select="'name(.)'"/>
+			</xsl:call-template>
+		</xsl:if>
+	    <xsl:call-template name="IamEmpty" />
+	</xsl:template>
+
+	<!-- ISO NS -->
+	<!-- Namespace handling is XSLT is quite tricky and implementation dependent -->
+	<xsl:template match="iso:ns">
+ 		<xsl:call-template name="handle-namespace" />
+	</xsl:template>
+
+    <!-- This template is just to provide the API hook -->
+	<xsl:template match="iso:ns"  mode="do-all-patterns" >
+               <xsl:if test="not(@uri)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">26</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+               <xsl:if test="not(@prefix)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">27</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+	        <xsl:call-template name="IamEmpty" />
+		<xsl:call-template name="process-ns" >
+			<xsl:with-param name="prefix" select="@prefix"/>
+			<xsl:with-param name="uri" select="@uri"/>
+		</xsl:call-template>
+	</xsl:template>
+
+	<!-- ISO P -->
+	<xsl:template match="iso:schema/iso:p " mode="do-schema-p" >
+		<xsl:call-template name="process-p">
+			<xsl:with-param name="class" select="@class"/>
+			<xsl:with-param name="icon" select="@icon"/>
+			<xsl:with-param name="id" select="@id"/>
+			<xsl:with-param name="lang" select="@xml:lang"/>
+		</xsl:call-template>
+	</xsl:template>
+	<xsl:template match="iso:pattern/iso:p " mode="do-pattern-p" >
+		<xsl:call-template name="process-p">
+			<xsl:with-param name="class" select="@class"/>
+			<xsl:with-param name="icon" select="@icon"/>
+			<xsl:with-param name="id" select="@id"/>
+			<xsl:with-param name="lang" select="@xml:lang"/>
+		</xsl:call-template>
+	</xsl:template>
+	
+    <!-- Currently, iso:p in other position are not passed through to the API -->
+	<xsl:template match="iso:phase/iso:p" />
+	<xsl:template match="iso:p " priority="-1" />
+ 
+	<!-- ISO PATTERN -->
+	<xsl:template match="iso:pattern" mode="do-all-patterns">
+	<xsl:if test="($phase = '#ALL') 
+	or (../iso:phase[@id= $phase]/iso:active[@pattern= current()/@id])">
+
+ 		<!-- Extension to allow validation in multiple documents -->  
+ 		<xsl:choose>
+		      	<xsl:when test="string-length(normalize-space(@documents))=0" >
+				    <xsl:call-template name="handle-pattern" />
+	 	       	</xsl:when>
+ 		    	<xsl:otherwise>  
+ 		    	<axsl:variable name="thePath"
+ 		    		select="{@documents}" 
+ 		    		as="xs:string*"  /> 
+ 		    	
+				<axsl:for-each  select="$thePath">  
+					<axsl:choose>
+						<axsl:when test="starts-with( ., 'http:') or starts-with(., 'file:' )
+						   or starts-with(., '/')"><!-- try as absolute path -->
+		  					<axsl:for-each select="document(.)"> 
+		    					<xsl:call-template name="handle-pattern"  />
+							</axsl:for-each>
+						</axsl:when>
+						<axsl:otherwise><!-- is relative path -->
+		  					<axsl:for-each select="document(concat( $document-uri , '/../', .))"> 
+		    					<xsl:call-template name="handle-pattern"  />
+							</axsl:for-each>
+						</axsl:otherwise>
+				  </axsl:choose>		
+				</axsl:for-each>
+			</xsl:otherwise>
+		</xsl:choose>	
+     </xsl:if>
+
+   </xsl:template>
+   
+   <xsl:template name="handle-pattern">
+		<xsl:call-template name="process-pattern">
+			<!-- the following select statement assumes that
+			@id | iso:title returns node-set in document order:
+			we want the title if it is there, otherwise the @id attribute -->
+			<xsl:with-param name="name" select="(@id | iso:title )[last()]"/>
+			<xsl:with-param name="is-a" select="''"/>
+			
+					<!-- "Rich" properties -->
+					<xsl:with-param name="fpi" select="@fpi"/>
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="lang" select="@xml:lang"/>
+					<xsl:with-param name="see" select="@see" />
+					<xsl:with-param name="space" select="@xml:space" />
+		</xsl:call-template>
+		<xsl:choose>
+		  <!--  Use the key method -->
+		  <xsl:when test="$select-contexts='key'">
+		    <axsl:apply-templates select="key('M','M{count(preceding-sibling::*)}')" mode="M{count(preceding-sibling::*)}"/>
+		  </xsl:when>
+		  
+		  <!-- Use the // method -->
+		  <xsl:when test="$select-contexts='//'">
+		    <xsl:choose>
+			  	<xsl:when test="@document">
+			    	<!-- External document -->
+		    		<axsl:for-each select="{@document}">
+					<!-- same code as next block, but run from different context -->		    		
+		    		<axsl:apply-templates mode="M{count(preceding-sibling::*)}" >
+		      			<xsl:attribute name="select"> 
+							<xsl:text>//(</xsl:text>
+							<xsl:for-each select="iso:rule/@context">
+			  					<xsl:text>(</xsl:text>
+			  					<xsl:value-of select="."/>
+			  					<xsl:text>)</xsl:text>
+			  					<xsl:if test="position()!=last()">|</xsl:if>
+							</xsl:for-each>
+							<xsl:text>)</xsl:text>
+							<xsl:if test="$visit-text='false'">[not(self::text())]</xsl:if>
+		      			</xsl:attribute>
+		    		</axsl:apply-templates>
+		    		</axsl:for-each>
+		  		</xsl:when>
+
+		  		<xsl:otherwise>
+		    		<axsl:apply-templates mode="M{count(preceding-sibling::*)}" >
+		      			<xsl:attribute name="select"> 
+							<xsl:text>//(</xsl:text>
+							<xsl:for-each select="iso:rule/@context">
+			  					<xsl:text>(</xsl:text>
+			  					<xsl:value-of select="."/>
+			  					<xsl:text>)</xsl:text>
+			  					<xsl:if test="position()!=last()">|</xsl:if>
+							</xsl:for-each>
+							<xsl:text>)</xsl:text>
+							<xsl:if test="$visit-text='false'">[not(self::text())]</xsl:if>
+		      			</xsl:attribute>
+		    		</axsl:apply-templates>
+		    	</xsl:otherwise>
+		    </xsl:choose>
+		  </xsl:when>
+		  
+		  <!-- Use complete tree traversal -->
+		  <xsl:when test="@document">
+		    <!-- External document -->
+		    <axsl:for-each select="{@document}">
+		    	<axsl:apply-templates select="." mode="M{count(preceding-sibling::*)}"/>
+		    </axsl:for-each>
+		  </xsl:when>
+		  <xsl:otherwise>
+		    <axsl:apply-templates select="/" mode="M{count(preceding-sibling::*)}"/>
+		  </xsl:otherwise>
+		</xsl:choose>
+        <!--/xsl:if-->
+	</xsl:template>
+	
+	<xsl:template match="iso:pattern[@abstract='true']">
+    
+             <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">28</xsl:with-param></xsl:call-template></xsl:message>
+    </xsl:template>
+
+    <!-- Here is the template for the normal case of patterns -->
+	<xsl:template match="iso:pattern[not(@abstract='true')]">
+    
+      <xsl:if test="($phase = '#ALL') 
+	          or (../iso:phase[@id= $phase]/iso:active[@pattern= current()/@id])">
+		<xsl:text>&#10;&#10;</xsl:text>
+		<xsl:comment>PATTERN <xsl:value-of select="@id" /> <xsl:value-of select="iso:title" /> </xsl:comment><xsl:text>&#10;</xsl:text>      
+		<xsl:apply-templates />
+		
+		<!-- DPC select-contexts test -->
+		<xsl:if test="not($select-contexts)">
+		  <axsl:template match="text()" priority="-1" mode="M{count(preceding-sibling::*)}">
+		    <!-- strip characters -->
+		  </axsl:template>
+		  
+		  <!-- DPC introduce context-xpath variable -->
+		  <axsl:template match="@*|node()"
+				 priority="-2"
+				 mode="M{ count(preceding-sibling::*) }">
+		    <axsl:apply-templates select="{$context-xpath}" mode="M{count(preceding-sibling::*)}"/>
+		  </axsl:template>
+		</xsl:if>
+      </xsl:if>
+	</xsl:template>
+
+	<!-- ISO PHASE -->
+	<xsl:template match="iso:phase" >
+                <xsl:if test="not(@id)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">29</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+		  <xsl:apply-templates/>
+	</xsl:template>
+	
+	
+	<!-- PROPERTY Experiemental -->
+	<!-- We use a mode here to maintain backwards compatability, instead of adding it
+	     to the other mode.
+	-->
+	<xsl:template match="iso:property" mode="check-property">
+              <xsl:if test="not(@id)">
+                    <xsl:message>No property found with that ID</xsl:message>
+               </xsl:if>
+    </xsl:template>
+    
+    <xsl:template match="iso:property"  >
+                <xsl:call-template name="process-property">
+                
+					<xsl:with-param name="id" select="@id"/>
+					
+					<xsl:with-param name="name"  select="@name"/>
+					<xsl:with-param name="value" select="@value" />
+					<xsl:with-param name="contents" select="*|text()" />
+				</xsl:call-template>   
+            
+        </xsl:template>
+
+	<!-- PROPERTIES  experimental extension -->
+	<xsl:template match="iso:properties" >
+		 <xsl:apply-templates mode="check-properties" select="property" /> 
+	</xsl:template>
+	
+	
+
+	<!-- ISO RULE -->
+	<xsl:template match="iso:rule[not(@abstract='true')] ">
+                <xsl:if test="not(@context)">
+                    <xsl:message ><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">30</xsl:with-param></xsl:call-template></xsl:message>
+                  
+                    <xsl:message terminate="yes" />
+                </xsl:if>
+        <xsl:text>&#10;&#10;	</xsl:text>
+		<xsl:comment>RULE <xsl:value-of select="@id" /> </xsl:comment><xsl:text>&#10;</xsl:text>   
+        <xsl:if test="iso:title">
+		    <xsl:comment><xsl:value-of select="iso:title" /></xsl:comment>
+		  </xsl:if>
+		<!-- DPC select-contexts -->
+		<xsl:if test="$select-contexts='key'">
+		    <axsl:key name="M"
+			      match="{@context}" 
+			      use="'M{count(../preceding-sibling::*)}'"/>
+		</xsl:if>
+   
+	
+<!-- DPC priorities count up from 1000 not down from 4000 (templates in same priority order as before) -->
+		<axsl:template match="{@context}"
+		priority="{1000 + count(following-sibling::*)}" mode="M{count(../preceding-sibling::*)}">
+		 
+			<xsl:call-template name="process-rule">
+				<xsl:with-param name="context" select="@context"/>
+				
+					<xsl:with-param name="properties" select="@properties" />
+					
+					<!-- "Rich" properties -->
+					<xsl:with-param name="fpi" select="@fpi"/>
+					<xsl:with-param name="icon" select="@icon"/>
+					<xsl:with-param name="id" select="@id"/>
+					<xsl:with-param name="lang" select="@xml:lang"/>
+					<xsl:with-param name="see" select="@see" />
+					<xsl:with-param name="space" select="@xml:space" />
+					
+					<!-- "Linking" properties -->
+					<xsl:with-param name="role" select="@role" />
+					<xsl:with-param name="subject" select="@subject" />
+			</xsl:call-template>
+			 
+				
+			<xsl:apply-templates/>
+			<!-- DPC introduce context-xpath and select-contexts variables -->
+			<xsl:if test="not($select-contexts)">
+			  <axsl:apply-templates select="{$context-xpath}" mode="M{count(../preceding-sibling::*)}"/>
+			</xsl:if>
+		</axsl:template>
+	</xsl:template>
+
+
+	<!-- ISO ABSTRACT RULE -->
+	<xsl:template match="iso:rule[@abstract='true'] " >
+		<xsl:if test=" not(@id)">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">31</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+ 		<xsl:if test="@context">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">32</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+	</xsl:template>
+
+	<xsl:template match="iso:rule[@abstract='true']"
+		mode="extends" >
+                <xsl:if test="@context">
+                    <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">33</xsl:with-param></xsl:call-template></xsl:message>
+                </xsl:if>
+			<xsl:apply-templates/>
+	</xsl:template>
+
+	<!-- ISO SPAN -->
+	<xsl:template match="iso:span" mode="text">
+		<xsl:call-template name="process-span">
+			<xsl:with-param name="class" select="@class"/>
+		</xsl:call-template>
+	</xsl:template>
+
+	<!-- ISO TITLE -->
+	
+	<xsl:template match="iso:schema/iso:title"  priority="1">
+	     <xsl:call-template name="process-schema-title" />
+	</xsl:template>
+ 
+	
+	<xsl:template match="iso:title" >
+	     <xsl:call-template name="process-title" />
+	</xsl:template>
+ 
+
+	<!-- ISO VALUE-OF -->
+	<xsl:template match="iso:value-of" mode="text" >
+        <xsl:if test="not(@select)">
+            <xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">34</xsl:with-param></xsl:call-template></xsl:message>
+        </xsl:if>
+	    <xsl:call-template name="IamEmpty" />
+	         
+		<xsl:choose>
+			<xsl:when test="@select">
+				<xsl:call-template name="process-value-of">
+					<xsl:with-param name="select" select="@select"/>  
+				</xsl:call-template>
+			</xsl:when>
+			<xsl:otherwise >
+				<xsl:call-template name="process-value-of">
+					<xsl:with-param name="select" select="'.'"/>
+				</xsl:call-template>
+			</xsl:otherwise>
+        </xsl:choose> 
+        
+	</xsl:template>
+
+
+<!-- ============================================================== -->
+<!-- DEFAULT TEXT HANDLING  -->
+<!-- ============================================================== -->
+	<xsl:template match="text()" priority="-1" mode="do-keys">
+		<!-- strip characters -->
+	</xsl:template>
+	<xsl:template match="text()" priority="-1" mode="do-all-patterns">
+		<!-- strip characters -->
+	</xsl:template>
+        <xsl:template match="text()" priority="-1" mode="do-schema-p">
+		<!-- strip characters -->
+	</xsl:template>
+        <xsl:template match="text()" priority="-1" mode="do-pattern-p">
+		<!-- strip characters -->
+	</xsl:template>
+	
+	<xsl:template match="text()" priority="-1">
+		<!-- Strip characters -->
+	</xsl:template>
+	
+	<xsl:template match="text()" mode="text">
+		<xsl:value-of select="."/>
+	</xsl:template>
+
+	<xsl:template match="text()" mode="inline-text">
+		<xsl:value-of select="."/>
+	</xsl:template>
+
+<!-- ============================================================== -->
+<!-- UTILITY TEMPLATES -->
+<!-- ============================================================== -->
+<xsl:template name="IamEmpty">
+	<xsl:if test="count( * )">
+		<xsl:message>
+			<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">35a</xsl:with-param></xsl:call-template>
+			<xsl:value-of select="name(.)"/>
+			<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">35b</xsl:with-param></xsl:call-template>
+		</xsl:message>
+	</xsl:if>
+</xsl:template>
+
+<xsl:template name="diagnosticsSplit">
+  <!-- Process at the current point the first of the <diagnostic> elements
+       referred to parameter str, and then recurse -->
+  <xsl:param name="str"/>
+  <xsl:variable name="start">
+    <xsl:choose>
+      <xsl:when test="contains($str,' ')">
+	<xsl:value-of  select="substring-before($str,' ')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="$str"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="end">
+    <xsl:if test="contains($str,' ')">
+      <xsl:value-of select="substring-after($str,' ')"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <!-- This works with all namespaces -->
+  <xsl:if test="not(string-length(normalize-space($start)) = 0)
+  		and not(//iso:diagnostic[@id = $start])
+		and not(//schold:diagnostic[@id = $start]) 
+		and not(//diagnostic[@id = $start])">
+	<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">36a</xsl:with-param></xsl:call-template>
+	<xsl:value-of select="string($start)"/>
+	<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">36b</xsl:with-param></xsl:call-template></xsl:message>
+  </xsl:if>
+
+  <xsl:if test="string-length(normalize-space($start)) > 0">
+     <xsl:text> </xsl:text>
+     <xsl:apply-templates 
+        select="//iso:diagnostic[@id = $start ]
+        	| //schold:diagnostic[@id = $start ] 
+            | //diagnostic[@id= $start ]"/>
+  </xsl:if>
+
+  <xsl:if test="not($end='')">
+    <xsl:call-template name="diagnosticsSplit">
+      <xsl:with-param name="str" select="$end"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+
+
+<xsl:template name="propertiesSplit">
+  <!-- Process at the current point the first of the <property> elements
+       referred to parameter str, and then recurse -->
+  <xsl:param name="str"/>
+  <xsl:variable name="start">
+    <xsl:choose>
+      <xsl:when test="contains($str,' ')">
+	<xsl:value-of  select="substring-before($str,' ')"/>
+      </xsl:when>
+      <xsl:otherwise><xsl:value-of select="$str"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <xsl:variable name="end">
+    <xsl:if test="contains($str,' ')">
+      <xsl:value-of select="substring-after($str,' ')"/>
+    </xsl:if>
+  </xsl:variable>
+
+  <!-- This works with all namespaces -->
+  <xsl:if test="not(string-length(normalize-space($start)) = 0)
+  		and not(//iso:property[@id = $start])">
+	<xsl:message><xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">36a</xsl:with-param></xsl:call-template>
+	<xsl:value-of select="string($start)"/>
+	<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">36b</xsl:with-param></xsl:call-template></xsl:message>
+  </xsl:if>
+
+  <xsl:if test="string-length(normalize-space($start)) > 0">
+     <xsl:text> </xsl:text>
+     <xsl:apply-templates 
+        select="//iso:property[@id = $start ] "/>
+  </xsl:if>
+
+  <xsl:if test="not($end='')">
+    <xsl:call-template name="propertiesSplit">
+      <xsl:with-param name="str" select="$end"/>
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+
+<!-- It would be nice to use this but xsl:namespace does not
+  allow a fallback -->
+<!--xsl:template name="handle-namespace" version="2.0">
+   <xsl:namespace name="{@prefix}" select="@uri">
+</xsl:template-->
+
+<xsl:template name="handle-namespace">
+       <!-- experimental code from http://eccnet.eccnet.com/pipermail/schematron-love-in/2006-June/000104.html -->
+       <!-- Handle namespaces differently for exslt systems,   and default, only using XSLT1 syntax -->
+       <!-- For more info see  http://fgeorges.blogspot.com/2007/01/creating-namespace-nodes-in-xslt-10.html -->
+       <xsl:choose>
+   	<!-- The following code workds for XSLT2 -->
+         <xsl:when test="element-available('xsl:namespace')">
+             <xsl:namespace name="{@prefix}" select="@uri" />
+	 </xsl:when>
+ 
+	 <xsl:when use-when="not(element-available('xsl:namespace'))" 
+		   test="function-available('exsl:node-set')">
+           <xsl:variable name="ns-dummy-elements">
+             <xsl:element name="{@prefix}:dummy" namespace="{@uri}"/>
+           </xsl:variable>
+       	   <xsl:variable name="p" select="@prefix"/>
+           <xsl:copy-of select="exsl:node-set($ns-dummy-elements)
+                                  /*/namespace::*[local-name()=$p]"/>
+         </xsl:when>
+
+	<!-- end XSLT2 code -->
+
+        
+        <xsl:when test="@prefix = 'xsl' ">
+           <!-- Do not generate dummy attributes with the xsl: prefix, as these
+                are errors against XSLT, because we presume that the output
+                stylesheet uses the xsl prefix. In any case, there would already
+                be a namespace declaration for the XSLT namespace generated
+                automatically, presumably using "xsl:".
+           -->
+        </xsl:when>
+        
+        <xsl:when test="@uri = 'http://www.w3.org/1999/XSL/Transform'">
+          <xsl:message terminate="yes">
+            <xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">37a</xsl:with-param></xsl:call-template>
+            <xsl:value-of select="system-property('xsl:vendor')"/>
+            <xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">37b</xsl:with-param></xsl:call-template>
+          </xsl:message>
+        </xsl:when>
+
+        <xsl:otherwise>
+          <xsl:attribute name="{concat(@prefix,':dummy-for-xmlns')}" namespace="{@uri}" />
+           
+        </xsl:otherwise>
+      </xsl:choose>
+
+
+</xsl:template>
+
+<!-- ============================================================== -->
+<!-- UNEXPECTED ELEMENTS -->
+<!-- ============================================================== -->
+
+	<xsl:template match="iso:*"  priority="-2">
+	   <xsl:message>
+			<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">38a</xsl:with-param></xsl:call-template>
+			<xsl:value-of select="name(.)"/>
+			<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">38b</xsl:with-param></xsl:call-template>
+		</xsl:message>
+	</xsl:template>
+	
+	
+	<!-- Swallow old namespace elements: there is an upfront test for them elsewhere -->
+	<xsl:template match="schold:*"  priority="-2" />
+	 
+	<xsl:template match="*"  priority="-3">
+	    <xsl:choose>
+	       <xsl:when test=" $allow-foreign = 'false' ">
+				<xsl:message>
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">39a</xsl:with-param></xsl:call-template>
+					<xsl:value-of select="name(.)"/>
+					<xsl:call-template name="outputLocalizedMessage" ><xsl:with-param name="number">39b</xsl:with-param></xsl:call-template>
+				</xsl:message>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:copy-of select="." />
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+	
+	<xsl:template match="iso:*" mode="text" priority="-2" />
+	<xsl:template match="*" mode="text" priority="-3">
+	    <xsl:if test=" not( $allow-foreign = 'false') "> 
+				<xsl:copy-of select="." />
+		</xsl:if>
+	</xsl:template>
+
+<!-- ============================================================== -->
+<!-- DEFAULT NAMED TEMPLATES -->
+<!-- These are the actions that are performed unless overridden -->
+<!-- ============================================================== -->
+ 
+	<xsl:template name="process-prolog"/>
+	<!-- no params -->
+
+	<xsl:template name="process-root">
+		<xsl:param name="contents"/>
+		<xsl:param name="id" />
+		<xsl:param name="version" />
+		<xsl:param name="schemaVersion" />
+		<xsl:param name="queryBinding" />
+		<xsl:param name="title" />
+
+
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+
+		<xsl:copy-of select="$contents"/>
+	</xsl:template>
+
+	<xsl:template name="process-assert">
+
+		<xsl:param name="test"/>
+		<xsl:param name="diagnostics" />
+		<xsl:param name="id" />
+		<xsl:param name="flag" />
+		<xsl:param name="properties" />
+
+           	<!-- "Linkable" parameters -->
+		<xsl:param name="role"/>
+		<xsl:param name="subject"/>
+
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+
+
+		<xsl:call-template name="process-message">
+			<xsl:with-param name="pattern" select="$test"/>
+			<xsl:with-param name="role" select="$role"/>
+		</xsl:call-template>
+		
+		<xsl:if test=" $terminate = 'yes' or $terminate = 'true' ">
+		   <axsl:message terminate="yes">TERMINATING</axsl:message>
+		</xsl:if>
+	    <xsl:if test=" $terminate = 'assert' ">
+		   <axsl:message terminate="yes">TERMINATING</axsl:message>
+		</xsl:if>
+		
+	</xsl:template>
+
+	<xsl:template name="process-report">
+		<xsl:param name="test"/>
+		<xsl:param name="diagnostics" />
+		<xsl:param name="id" />
+		<xsl:param name="flag" />
+		<xsl:param name="properties" />
+
+           	<!-- "Linkable" parameters -->
+		<xsl:param name="role"/>
+		<xsl:param name="subject"/>
+
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" /> 
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+
+		<xsl:call-template name="process-message">
+			<xsl:with-param name="pattern" select="$test"/>
+			<xsl:with-param name="role" select="$role"/>
+		</xsl:call-template>
+				
+		<xsl:if test=" $terminate = 'yes' or $terminate = 'true'  ">
+		   <axsl:message terminate="yes">TERMINATING</axsl:message>
+		</xsl:if>
+	</xsl:template>
+
+	<xsl:template name="process-diagnostic">
+		<xsl:param name="id" />
+
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+		
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="text"/>
+		<axsl:text> </axsl:text>
+	</xsl:template>
+
+	<xsl:template name="process-dir">
+      	<xsl:param name="value" />
+
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>
+	</xsl:template>
+
+	<xsl:template name="process-emph"> 
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>
+	</xsl:template>
+	
+	<xsl:template name="process-name">
+		<xsl:param name="name"/>
+		
+		<!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<axsl:value-of select="{$name}"/>
+		<axsl:text> </axsl:text>
+		
+    </xsl:template>
+
+	<xsl:template name="process-ns" >
+	<!-- Note that process-ns is for reporting. The iso:ns elements are 
+	     independently used in the iso:schema template to provide namespace bindings -->
+		<xsl:param name="prefix"/>
+		<xsl:param name="uri" />
+      </xsl:template>
+
+	<xsl:template name="process-p">
+		<xsl:param name="id" />
+		<xsl:param name="class" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+      </xsl:template>
+
+	<xsl:template name="process-pattern">
+		<xsl:param name="id" />
+		<xsl:param name="name" />
+		<xsl:param name="is-a" />
+
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+      </xsl:template>
+      
+
+	<xsl:template name="process-rule">
+		<xsl:param name="context" />
+
+		<xsl:param name="id" />
+		<xsl:param name="flag" />
+		<xsl:param name="properties" />
+
+           	<!-- "Linkable" parameters -->
+		<xsl:param name="role"/>
+		<xsl:param name="subject"/>
+  
+		<!-- "Rich" parameters -->
+		<xsl:param name="fpi" />
+		<xsl:param name="icon" />
+		<xsl:param name="lang" />
+		<xsl:param name="see" />
+		<xsl:param name="space" />
+      </xsl:template>
+
+	<xsl:template name="process-span" >
+		<xsl:param name="class" />
+
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>		
+	</xsl:template>
+
+	<xsl:template name="process-title" >
+		<xsl:param name="class" />
+	   <xsl:call-template name="process-p">
+	      <xsl:with-param  name="class">title</xsl:with-param>
+	   </xsl:call-template>
+	</xsl:template>
+		
+	<xsl:template name="process-schema-title" >
+		<xsl:param name="class" />
+	   <xsl:call-template name="process-title">
+	      <xsl:with-param  name="class">schema-title</xsl:with-param>
+	   </xsl:call-template>
+	</xsl:template>
+
+	<xsl:template name="process-value-of">
+		<xsl:param name="select"/>
+		
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<axsl:value-of select="{$select}"/>
+		<axsl:text> </axsl:text>
+	</xsl:template>
+
+	<!-- default output action: the simplest customization is to just override this -->
+	<xsl:template name="process-message">
+		<xsl:param name="pattern" />
+            <xsl:param name="role" />
+
+		<xsl:apply-templates mode="text"/>	
+		 <xsl:if test=" $message-newline = 'true'" >
+			<axsl:value-of  select="string('&#10;')"/>
+		</xsl:if>
+		
+	</xsl:template>
+	
+	
+	<!-- ===================================================== -->
+	<!-- Extension API: default rules 			               -->
+	<!-- This allows the transmission of extra attributes on   -->
+	<!-- rules, asserts, reports, diagnostics.                 -->
+	<!-- ===================================================== -->
+	
+ 
+
+	<xsl:template name="process-property">
+		<xsl:param name="id" />
+		
+		<xsl:param name="name"/>
+		<xsl:param name="value"/>
+		<xsl:param name="contents"/>
+		  
+	</xsl:template>
+	
+	
+	<!-- ===================================================== -->
+	<!-- Localization 						                  -->
+	<!-- ===================================================== -->
+	<!--
+		All messages generated by the skeleton during processing are localized.
+		(This does not apply to the text that comes from Schematron schemas
+		themselves, of course. Nor does it apply to messages in metastylesheets.)
+		
+		Stylesheets have a parameter $langCode which can be used to select the
+		language code (e.g. from the command line)
+		
+		The default value of $langCode is "default". When this is used, the
+		message text is taken from the strings below. We use XHTML, to provide
+		the namespace. 
+		
+		If the $langCode is somethign else, then the XSLT engine will try to
+		find a file called  sch-messages-$langCode.xhtml in the same directory
+		as this stylesheet. Expect a fatal error if the file does not exist.
+		
+		The file should contain XHTML elements, with the text translated.
+		The strings are located by using ids on each xhtml:p element.
+		The ids are formed by sch-message-$number-$langCode such as  
+		sch-message-1-en
+		
+		If there is no match in a localization file for a message, then the
+		default will be used. This allows this XSLT to be developed with new
+		messages added without requiring that any localization files be updated.
+		
+		In many cases, there are actually two localization strings per message.
+		This happens whenever a message has an embedded value that is dynamically
+		generated (using <value-of>). Having two strings, preceding and following,
+		allows the translator to make idiomatic error messages. When there are
+		two message for a single message, they have numbers like 30a and 30b: 
+		translators should check the reference to them in the XSLT above to
+		see what the dynamically generated information is.  
+	-->
+	<xsl:template name="outputLocalizedMessage">
+		<xsl:param name="number" />  
+		 
+		<xsl:choose>
+		   <xsl:when test="string-length( $langCode ) = 0 or $langCode = 'default'" > 	   	 
+				<xsl:value-of select='document("")//xhtml:p[@id=concat("sch-message-", $number)]/text()' />
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:variable name="localizationDocumentFilename" >
+					<xsl:value-of select="concat('sch-messages-', $langCode, '.xhtml')" />
+				</xsl:variable>
+				<xsl:variable name="theLocalizedMessage" >
+					<xsl:value-of select=
+				'document( $localizationDocumentFilename, /)//xhtml:p[@id=concat("sch-message-", $number, "-", $langCode)]/text()' />
+				</xsl:variable>
+				
+				<xsl:choose>
+					<!-- if we found any external message with that id, use it -->
+					<xsl:when test=" string-length($theLocalizedMessage) &gt; 0">
+						<xsl:value-of select="$theLocalizedMessage" />
+					</xsl:when>
+					<xsl:otherwise>
+						<!-- otherwise use the default strings -->		
+						<xsl:value-of select='document("")//xhtml:p[@id=concat("sch-message-", $number)]/text()' />
+					</xsl:otherwise>
+				</xsl:choose>	
+				
+				 
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:template>
+	
+<xhtml:div class="ErrorMessages">	
+	<!-- Where the error message contains dynamic information, the message has been split into an "a" and a "b" section.
+	     This has been done even when the English does not require it, in order to accomodate different language grammars
+	     that might position the dynamic information differently.
+	-->
+	<xhtml:p id="sch-message-1">Schema error: Schematron elements in old and new namespaces found</xhtml:p>
+	<xhtml:p id="sch-message-2">Schema error: in the queryBinding attribute, use 'xslt'</xhtml:p>
+	<xhtml:p id="sch-message-3a">Fail: This implementation of ISO Schematron does not work with schemas using the query language </xhtml:p>
+	<xhtml:p id="sch-message-3b"/>
+	<xhtml:p id="sch-message-4a">Phase Error: no phase has been defined with name </xhtml:p>
+	<xhtml:p id="sch-message-4b" />
+	<xhtml:p id="sch-message-5">Markup Error: no pattern attribute in &lt;active></xhtml:p>
+	<xhtml:p id="sch-message-6a">Reference Error: the pattern  "</xhtml:p>
+	<xhtml:p id="sch-message-6b">" has been activated but is not declared</xhtml:p>
+	<xhtml:p id="sch-message-7">Markup Error: no test attribute in &lt;assert</xhtml:p>
+	<xhtml:p id="sch-message-8">Markup Error: no test attribute in &lt;report></xhtml:p>
+	<xhtml:p id="sch-message-9">Markup Error: no id attribute in &lt;diagnostic></xhtml:p>
+	<xhtml:p id="sch-message-10">Markup Error: no rule attribute in &lt;extends></xhtml:p>				   
+	<xhtml:p id="sch-message-11a">Reference Error: the abstract rule  "</xhtml:p>
+	<xhtml:p id="sch-message-11b">" has been referenced but is not declared</xhtml:p>				
+	<xhtml:p id="sch-message-12">Markup Error: no name attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-13">Markup Error: no path or use attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-14">Markup Error: no path or use attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-15">Schema error: The key element is not in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-16">Markup Error: no name attribute in &lt;function></xhtml:p>
+	<xhtml:p id="sch-message-17">Schema error: The function element is not in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-18">Schema error: Empty href= attribute for include directive.</xhtml:p>
+	<xhtml:p id="sch-message-19">Error: Impossible URL in Schematron include</xhtml:p>
+	<xhtml:p id="sch-message-20a">Unable to open referenced included file: </xhtml:p>
+	<xhtml:p id="sch-message-20b" />
+	<xhtml:p id="sch-message-21">Schema error: Use include to include fragments, not a whole schema</xhtml:p>
+	<xhtml:p id="sch-message-22">Schema error: XSD schemas may only be imported if you are using the 'xslt2' query language binding</xhtml:p>
+	<xhtml:p id="sch-message-23">Schema error: The import-schema element is not available in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-24">Warning: Variables should not be used with the "xpath" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-25">Warning: Variables should not be used with the "xpath2" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-26">Markup Error: no uri attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-27">Markup Error: no prefix attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-28">Schema implementation error: This schema has abstract patterns, yet they are supposed to be preprocessed out already</xhtml:p>
+    <xhtml:p id="sch-message-29">Markup Error: no id attribute in &lt;phase></xhtml:p>
+    <xhtml:p id="sch-message-30">Markup Error: no context attribute in &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-31">Markup Error: no id attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-32">Markup Error: (2) context attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-33">Markup Error: context attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-34">Markup Error: no select attribute in &lt;value-of></xhtml:p>
+    <xhtml:p id="sch-message-35a">Warning: </xhtml:p>
+	<xhtml:p id="sch-message-35b"> must not contain any child elements</xhtml:p>
+    <xhtml:p id="sch-message-36a">Reference error: A diagnostic "</xhtml:p>
+	<xhtml:p id="sch-message-36b">" has been referenced but is not declared</xhtml:p>
+	<xhtml:p id="sch-message-37a">Using the XSLT namespace with a prefix other than "xsl" in Schematron rules is not supported in this processor:</xhtml:p>
+    <xhtml:p id="sch-message-37b" />
+    <xhtml:p id="sch-message-38a">Error: unrecognized element in ISO Schematron namespace: check spelling and capitalization</xhtml:p>
+	<xhtml:p id="sch-message-38b" />
+	<xhtml:p id="sch-message-39a">Warning: unrecognized element </xhtml:p>
+	<xhtml:p id="sch-message-39b" />
+ </xhtml:div>
+</xsl:stylesheet>
+
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_svrl_for_xslt2.xsl
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_svrl_for_xslt2.xsl	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/iso_svrl_for_xslt2.xsl	(revision 1843)
@@ -0,0 +1,684 @@
+<?xml version="1.0" ?>
+<!-- 
+   ISO_SVRL.xsl   
+
+   Implementation of Schematron Validation Report Language from ISO Schematron
+   ISO/IEC 19757 Document Schema Definition Languages (DSDL) 
+     Part 3: Rule-based validation  Schematron 
+     Annex D: Schematron Validation Report Language 
+
+  This ISO Standard is available free as a Publicly Available Specification in PDF from ISO.
+  Also see www.schematron.com for drafts and other information.
+
+  This implementation of SVRL is designed to run with the "Skeleton" implementation 
+  of Schematron which Oliver Becker devised. The skeleton code provides a 
+  Schematron implementation but with named templates for handling all output; 
+  the skeleton provides basic templates for output using this API, but client
+  validators can be written to import the skeleton and override the default output
+  templates as required. (In order to understand this, you must understand that
+  a named template such as "process-assert" in this XSLT stylesheet overrides and
+  replaces any template with the same name in the imported skeleton XSLT file.)
+
+  The other important thing to understand in this code is that there are different
+  versions of the Schematron skeleton. These track the development of Schematron through
+  Schematron 1.5, Schematron 1.6 and now ISO Schematron. One only skeleton must be
+  imported. The code has templates for the different skeletons commented out for 
+  convenience. ISO Schematron has a different namespace than Schematron 1.5 and 1.6;
+  so the ISO Schematron skeleton has been written itself with an optional import
+  statement to in turn import the Schematron 1.6 skeleton. This will allow you to 
+  validate with schemas from either namespace.
+  
+
+  History: 
+    2010-04-14
+        * Add command line parameter 'terminate' which will terminate on first failed 
+        assert and (optionally) successful report. 
+    2009-03-18
+    	* Fix atrribute with space "see " which generates wrong name in some processors
+    	* rename allow-foreign to allow-rich
+  
+    2009-02-19
+    	* RJ add experimental non-standard attribute active-pattern/@document which says which
+    	document is being validated from that point to the next similar. This is to cope with the
+    	experimental multi-document validation in the XSLT2 skeleton.
+    2008-08-19
+  		* RJ Experimental: Handle property elements. NOTE: signature change for process-assert,
+  		process-report and process-rule to add property.
+  	2008-08-11
+   		* RJ Fix attribute/@select which saxon allows  in XSLT 1
+   2008-08-07
+    	* RJ Add output-encoding attribute to specify final encoding to use
+    	* Alter allow-foreign functionality so that Schematron span, emph and dir elements make 
+    	  it to the output, for better formatting and because span can be used to mark up
+    	  semantically interesting information embedded in diagnostics, which reduces the
+    	  need to extend SVRL itself
+    	* Diagnostic-reference had an invalid attribute @id that duplicated @diagnostic: removed
+  	2008-08-06
+    	* RJ Fix invalid output:  svrl:diagnostic-reference is not contained in an svrl:text
+    	* Output comment to SVRL file giving filename if available (from command-line parameter)
+  	2008-08-04
+  		* RJ move sch: prefix to schold: prefix to prevent confusion (we want people to
+  		be able to switch from old namespace to new namespace without changing the
+  		sch: prefix, so it is better to keep that prefix completely out of the XSLT)
+  		* Extra signature fixes (PH)
+    2008-08-03
+    	* Repair missing class parameter on process-p
+    2008-07-31
+    	* Update skeleton names
+    2007-04-03 
+    	* Add option generate-fired-rule (RG)
+    2007-02-07
+    	* Prefer true|false for parameters. But allow yes|no on some old for compatability
+    	* DP Diagnostics output to svrl:text. Diagnosis put out after assertion text.
+      	* Removed non-SVRL elements and attributes: better handled as an extra layer that invokes this one
+      	* Add more formal parameters
+      	* Correct confusion between $schemaVersion and $queryBinding
+     	* Indent
+     	* Validate against RNC schemas for XSLT 1 and 2 (with regex tests removed)
+     	* Validate output with UniversalTest.sch against RNC schema for ISO SVRL
+    	
+    2007-02-01
+       	* DP. Update formal parameters of overriding named templates to handle more attributes.
+       	* DP. Refactor handling of rich and linkable parameters to a named template.
+
+    2007-01-22
+    	* DP change svrl:ns to svrl:ns-in-attribute-value
+		* Change default when no queryBinding from "unknown" to "xslt"
+	
+    2007-01-18:
+     	* Improve documentation
+     	* KH Add command-line options to generate paths or not 
+       	* Use axsl:attribute rather than xsl:attribute to shut XSLT2 up
+       	* Add extra command-line options to pass to the iso_schematron_skeleton
+  
+    2006-12-01: iso_svrl.xsl Rick Jelliffe, 
+          * update namespace, 
+          * update phase handling,
+          * add flag param to process-assert and process-report & @ flag on output
+  
+    2001: Conformance1-5.xsl Rick Jelliffe, 
+          * Created, using the skeleton code contributed by Oliver Becker
+-->
+<!--
+ Derived from Conformance1-5.xsl.
+
+ Copyright (c) 2001-2010 Rick Jelliffe and Academia Sinica Computing Center, Taiwan
+
+ This software is provided 'as-is', without any express or implied warranty. 
+ In no event will the authors be held liable for any damages arising from 
+ the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose, 
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim
+ that you wrote the original software. If you use this software in a product, 
+ an acknowledgment in the product documentation would be appreciated but is 
+ not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be 
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+-->
+
+<!-- Ideas nabbed from schematrons by Francis N., Miloslav N. and David C. -->
+
+<!-- The command-line parameters are:
+  			phase           NMTOKEN | "#ALL" (default) Select the phase for validation
+    		allow-foreign   "true" | "false" (default)   Pass non-Schematron elements and rich markup to the generated stylesheet 
+            diagnose= true | false|yes|no    Add the diagnostics to the assertion test in reports (yes|no are obsolete)
+            property= true | false           Experimental: Add properties to the assertion test in reports  
+            generate-paths=true|false|yes|no   generate the @location attribute with XPaths (yes|no are obsolete)
+            sch.exslt.imports semi-colon delimited string of filenames for some EXSLT implementations          
+   		 optimize        "visit-no-attributes"     Use only when the schema has no attributes as the context nodes
+		 generate-fired-rule "true"(default) | "false"  Generate fired-rule elements
+             terminate= yes | no | true | false | assert  Terminate on the first failed assertion or successful report
+                                         Note: whether any output at all is generated depends on the XSLT implementation.
+-->
+
+<xsl:stylesheet
+   version="1.0"
+   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+   xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias"
+   xmlns:schold="http://www.ascc.net/xml/schematron" 
+   xmlns:iso="http://purl.oclc.org/dsdl/schematron"
+   xmlns:svrl="http://purl.oclc.org/dsdl/svrl" 
+    
+>
+
+<!-- Select the import statement and adjust the path as 
+   necessary for your system.
+-->
+<xsl:import href="iso_schematron_skeleton_for_saxon.xsl"/>
+ 
+ <!--
+<xsl:import href="iso_schematron_skeleton_for_xslt1.xsl"/>
+ 
+<xsl:import href="iso_schematron_skeleton.xsl"/>
+<xsl:import href="skeleton1-5.xsl"/>
+<xsl:import href="skeleton1-6.xsl"/>
+-->
+
+<xsl:param name="diagnose">true</xsl:param>
+<xsl:param name="property">true</xsl:param>
+<xsl:param name="phase">
+	<xsl:choose>
+		<!-- Handle Schematron 1.5 and 1.6 phases -->
+		<xsl:when test="//schold:schema/@defaultPhase">
+			<xsl:value-of select="//schold:schema/@defaultPhase"/>
+		</xsl:when>
+		<!-- Handle ISO Schematron phases -->
+		<xsl:when test="//iso:schema/@defaultPhase">
+			<xsl:value-of select="//iso:schema/@defaultPhase"/>
+		</xsl:when>
+		<xsl:otherwise>#ALL</xsl:otherwise>
+	</xsl:choose>
+</xsl:param>
+<xsl:param name="allow-foreign">false</xsl:param>
+<xsl:param name="generate-paths">true</xsl:param>
+<xsl:param name="generate-fired-rule">true</xsl:param>
+<xsl:param name="optimize" />
+<!-- e.g. saxon file.xml file.xsl "sch.exslt.imports=.../string.xsl;.../math.xsl" -->
+<xsl:param name="sch.exslt.imports" />
+
+<xsl:param name="terminate" >false</xsl:param>
+
+<!-- Set the language code for messages -->
+<xsl:param name="langCode">default</xsl:param>
+ 
+<xsl:param name="output-encoding"/>
+
+<!-- Set the default for schematron-select-full-path, i.e. the notation for svrl's @location-->
+<xsl:param name="full-path-notation">1</xsl:param>
+
+
+
+<!-- Experimental: If this file called, then must be generating svrl -->
+<xsl:variable name="svrlTest" select="true()" />
+
+  
+ 
+<!-- ================================================================ -->
+
+<xsl:template name="process-prolog">
+	<axsl:output method="xml" omit-xml-declaration="no" standalone="yes"
+		indent="yes">
+		<xsl:if test=" string-length($output-encoding) &gt; 0">
+			<xsl:attribute name="encoding"><xsl:value-of select=" $output-encoding" /></xsl:attribute>
+		</xsl:if>
+    </axsl:output>
+     
+</xsl:template>
+
+<!-- Overrides skeleton.xsl -->
+<xsl:template name="process-root">
+	<xsl:param name="title"/>
+	<xsl:param name="contents" />
+	<xsl:param name="queryBinding" >xslt1</xsl:param>
+	<xsl:param name="schemaVersion" />
+	<xsl:param name="id" />
+	<xsl:param name="version"/>
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	
+	<svrl:schematron-output title="{$title}" schemaVersion="{$schemaVersion}" >
+		<xsl:if test=" string-length( normalize-space( $phase )) &gt; 0 and 
+		not( normalize-space( $phase ) = '#ALL') ">
+			<axsl:attribute name="phase">
+				<xsl:value-of select=" $phase " />
+			</axsl:attribute>
+		</xsl:if> 
+		
+		 <axsl:comment><axsl:value-of select="$archiveDirParameter"/>  &#xA0;
+		 <axsl:value-of select="$archiveNameParameter"/> &#xA0;
+		 <axsl:value-of select="$fileNameParameter"/> &#xA0;
+		 <axsl:value-of select="$fileDirParameter"/></axsl:comment> 
+		 
+		
+		<xsl:apply-templates mode="do-schema-p" />
+		<xsl:copy-of select="$contents" />
+	</svrl:schematron-output>
+</xsl:template>
+
+
+<xsl:template name="process-assert">
+	<xsl:param name="test"/>
+	<xsl:param name="diagnostics" />
+	<xsl:param name="properties" />
+	<xsl:param name="id" />
+	<xsl:param name="flag" />
+	<!-- "Linkable" parameters -->
+	<xsl:param name="role"/>
+	<xsl:param name="subject"/>
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<svrl:failed-assert test="{$test}" >
+		<xsl:if test="string-length( $id ) &gt; 0">
+			<axsl:attribute name="id">
+				<xsl:value-of select=" $id " />
+			</axsl:attribute>
+		</xsl:if>
+		<xsl:if test=" string-length( $flag ) &gt; 0">
+			<axsl:attribute name="flag">
+				<xsl:value-of select=" $flag " />
+			</axsl:attribute>
+		</xsl:if>
+		<!-- Process rich attributes.  -->
+		<xsl:call-template name="richParms">
+			<xsl:with-param name="fpi" select="$fpi"/>
+			<xsl:with-param name="icon" select="$icon"/>
+			<xsl:with-param name="lang" select="$lang"/>
+			<xsl:with-param name="see" select="$see" />
+			<xsl:with-param name="space" select="$space" />
+		</xsl:call-template>
+		<xsl:call-template name='linkableParms'>
+			<xsl:with-param name="role" select="$role" />
+			<xsl:with-param name="subject" select="$subject"/>
+		</xsl:call-template>
+		<xsl:if test=" $generate-paths = 'true' or $generate-paths= 'yes' ">
+			<!-- true/false is the new way -->
+			<axsl:attribute name="location">
+				<axsl:apply-templates select="." mode="schematron-select-full-path"/>
+			</axsl:attribute>
+		</xsl:if>
+		  
+		<svrl:text>
+			<xsl:apply-templates mode="text" />
+	
+		</svrl:text>
+		    <xsl:if test="$diagnose = 'yes' or $diagnose= 'true' ">
+			<!-- true/false is the new way -->
+				<xsl:call-template name="diagnosticsSplit">
+					<xsl:with-param name="str" select="$diagnostics"/>
+				</xsl:call-template>
+			</xsl:if>
+			
+			
+		    <xsl:if test="$property= 'yes' or $property= 'true' ">
+			<!-- true/false is the new way -->
+				<xsl:call-template name="propertiesSplit">
+					<xsl:with-param name="str" select="$properties"/>
+				</xsl:call-template>
+			</xsl:if>
+			
+	</svrl:failed-assert>
+	
+	
+		<xsl:if test=" $terminate = 'yes' or $terminate = 'true' ">
+		   <axsl:message terminate="yes">TERMINATING</axsl:message>
+		</xsl:if>
+	    <xsl:if test=" $terminate = 'assert' ">
+		   <axsl:message terminate="yes">TERMINATING</axsl:message>
+		</xsl:if>
+</xsl:template>
+
+<xsl:template name="process-report">
+	<xsl:param name="id"/>
+	<xsl:param name="test"/>
+	<xsl:param name="diagnostics"/>
+	<xsl:param name="flag" />
+	<xsl:param name="properties"/>
+	<!-- "Linkable" parameters -->
+	<xsl:param name="role"/>
+	<xsl:param name="subject"/>
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<svrl:successful-report test="{$test}" >
+		<xsl:if test=" string-length( $id ) &gt; 0">
+			<axsl:attribute name="id">
+				<xsl:value-of select=" $id " />
+			</axsl:attribute>
+		</xsl:if>
+		<xsl:if test=" string-length( $flag ) &gt; 0">
+			<axsl:attribute name="flag">
+				<xsl:value-of select=" $flag " />
+			</axsl:attribute>
+		</xsl:if>
+		
+		<!-- Process rich attributes.  -->
+		<xsl:call-template name="richParms">
+			<xsl:with-param name="fpi" select="$fpi"/>
+			<xsl:with-param name="icon" select="$icon"/>
+			<xsl:with-param name="lang" select="$lang"/>
+			<xsl:with-param name="see" select="$see" />
+			<xsl:with-param name="space" select="$space" />
+		</xsl:call-template>
+		<xsl:call-template name='linkableParms'>
+			<xsl:with-param name="role" select="$role" />
+			<xsl:with-param name="subject" select="$subject"/>
+		</xsl:call-template>
+		<xsl:if test=" $generate-paths = 'yes' or $generate-paths = 'true' ">
+			<!-- true/false is the new way -->
+			<axsl:attribute name="location">
+				<axsl:apply-templates select="." mode="schematron-select-full-path"/>
+			</axsl:attribute>
+		</xsl:if>
+	 
+		<svrl:text>
+			<xsl:apply-templates mode="text" />
+
+		</svrl:text>
+			<xsl:if test="$diagnose = 'yes' or $diagnose='true' ">
+			<!-- true/false is the new way -->
+				<xsl:call-template name="diagnosticsSplit">
+					<xsl:with-param name="str" select="$diagnostics"/>
+				</xsl:call-template>
+			</xsl:if>
+			
+			
+			<xsl:if test="$property = 'yes' or $property='true' ">
+			<!-- true/false is the new way -->
+				<xsl:call-template name="propertiesSplit">
+					<xsl:with-param name="str" select="$properties"/>
+				</xsl:call-template>
+			</xsl:if>
+			 
+			
+	</svrl:successful-report>
+	
+	
+		<xsl:if test=" $terminate = 'yes' or $terminate = 'true' ">
+		   <axsl:message terminate="yes"  >TERMINATING</axsl:message>
+		</xsl:if>
+</xsl:template>
+
+
+
+
+<xsl:template name="process-diagnostic">
+	<xsl:param name="id"/>
+	<!-- Rich parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<svrl:diagnostic-reference diagnostic="{$id}" >
+		<!--xsl:if test="string($id)">
+			<xsl:attribute name="id">
+				<xsl:value-of select="$id"/>
+			</xsl:attribute>
+		</xsl:if-->
+		<xsl:call-template name="richParms">
+			<xsl:with-param name="fpi" select="$fpi"/>
+			<xsl:with-param name="icon" select="$icon"/>
+			<xsl:with-param name="lang" select="$lang"/>
+			<xsl:with-param name="see" select="$see" />
+			<xsl:with-param name="space" select="$space" />
+		</xsl:call-template> 
+<xsl:text>
+</xsl:text>
+ 
+		<xsl:apply-templates mode="text"/>
+		 
+	</svrl:diagnostic-reference>
+</xsl:template>
+
+
+    <!-- Overrides skeleton -->
+	<xsl:template name="process-dir" >
+		<xsl:param name="value" />
+        <xsl:choose>
+        	<xsl:when test=" $allow-foreign = 'true'">
+        		<xsl:copy-of select="."/>
+        	</xsl:when>
+       
+        <xsl:otherwise>
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>
+		</xsl:otherwise>
+		 </xsl:choose>		
+	</xsl:template>
+	
+	
+    <!-- Overrides skeleton -->
+	<xsl:template name="process-emph" >
+		<xsl:param name="class" />
+        <xsl:choose>
+        	<xsl:when test=" $allow-foreign = 'true'">
+        		<xsl:copy-of select="."/>
+        	</xsl:when> 
+        <xsl:otherwise>
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>
+		</xsl:otherwise>
+	 	</xsl:choose>	
+	</xsl:template>
+
+<xsl:template name="process-rule">
+	<xsl:param name="id"/>
+	<xsl:param name="context"/>
+	<xsl:param name="flag"/>
+	<xsl:param name="properties" />
+	<!-- "Linkable" parameters -->
+	<xsl:param name="role"/>
+	<xsl:param name="subject"/>
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<xsl:if test=" $generate-fired-rule = 'true'">
+	<svrl:fired-rule context="{$context}" >
+		<xsl:if test=" string( $id )">
+			<xsl:attribute name="id">
+				<xsl:value-of select=" $id " />
+			</xsl:attribute>
+		</xsl:if>
+		<xsl:if test=" string-length( $role ) &gt; 0">
+			<xsl:attribute name="role">
+				<xsl:value-of select=" $role " />
+			</xsl:attribute>
+		</xsl:if>
+		<!-- Process rich attributes.  -->
+		<xsl:call-template name="richParms">
+			<xsl:with-param name="fpi" select="$fpi"/>
+			<xsl:with-param name="icon" select="$icon"/>
+			<xsl:with-param name="lang" select="$lang"/>
+			<xsl:with-param name="see" select="$see" />
+			<xsl:with-param name="space" select="$space" />
+		</xsl:call-template>
+		
+		
+		    <xsl:if test="$property= 'yes' or $property= 'true' ">
+			<!-- true/false is the new way -->
+				<xsl:call-template name="propertiesSplit">
+					<xsl:with-param name="str" select="$properties"/>
+				</xsl:call-template>
+			</xsl:if>
+		
+	</svrl:fired-rule>
+</xsl:if>
+</xsl:template>
+
+<xsl:template name="process-ns">
+	<xsl:param name="prefix"/>
+	<xsl:param name="uri"/>
+	<svrl:ns-prefix-in-attribute-values uri="{$uri}" prefix="{$prefix}" />
+</xsl:template>
+
+<xsl:template name="process-p"> 
+	<xsl:param name="icon"/>
+	<xsl:param name="class"/>
+	<xsl:param name="id"/>
+	<xsl:param name="lang"/>
+	 
+	<svrl:text> 
+		<xsl:apply-templates mode="text"/>
+	</svrl:text>
+</xsl:template>
+
+<xsl:template name="process-pattern">
+	<xsl:param name="name"/>
+	<xsl:param name="id"/>
+	<xsl:param name="is-a"/>
+	
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<svrl:active-pattern >
+	    <axsl:attribute name="document">
+	    	<axsl:value-of select="document-uri(/)" />
+	    </axsl:attribute><!-- If XSLT1 remove this -->
+		<xsl:if test=" string( $id )">
+			<axsl:attribute name="id">
+				<xsl:value-of select=" $id " />
+			</axsl:attribute>
+		</xsl:if>
+		<xsl:if test=" string( $name )">
+			<axsl:attribute name="name">
+				<xsl:value-of select=" $name " />
+			</axsl:attribute>
+		</xsl:if> 
+		 
+		<xsl:call-template name='richParms'>
+			<xsl:with-param name="fpi" select="$fpi"/>
+			<xsl:with-param name="icon" select="$icon"/>
+			<xsl:with-param name="lang" select="$lang"/>
+			<xsl:with-param name="see" select="$see" />
+			<xsl:with-param name="space" select="$space" />
+		</xsl:call-template>
+		
+		<!-- ?? report that this screws up iso:title processing  -->
+		<xsl:apply-templates mode="do-pattern-p"/>
+		<!-- ?? Seems that this apply-templates is never triggered DP -->
+		<axsl:apply-templates />
+	</svrl:active-pattern>
+</xsl:template>
+
+<!-- Overrides skeleton -->
+<xsl:template name="process-message" > 
+	<xsl:param name="pattern"/>
+	<xsl:param name="role"/>
+</xsl:template>
+
+
+    <!-- Overrides skeleton -->
+	<xsl:template name="process-span" >
+		<xsl:param name="class" />
+        <xsl:choose>
+        	<xsl:when test=" $allow-foreign = 'true'">
+        		<xsl:copy-of select="."/>
+        	</xsl:when> 
+        <xsl:otherwise>
+	    <!-- We generate too much whitespace rather than risking concatenation -->
+		<axsl:text> </axsl:text>
+		<xsl:apply-templates mode="inline-text"/>
+		<axsl:text> </axsl:text>
+		</xsl:otherwise>
+	 	</xsl:choose>	
+	</xsl:template>
+
+<!-- =========================================================================== -->
+<!-- processing rich parameters. -->
+<xsl:template name='richParms'>
+	<!-- "Rich" parameters -->
+	<xsl:param name="fpi" />
+	<xsl:param name="icon" />
+	<xsl:param name="lang" />
+	<xsl:param name="see" />
+	<xsl:param name="space" />
+	<!-- Process rich attributes.  -->
+	<xsl:if  test=" $allow-foreign = 'true'">
+	<xsl:if test="string($fpi)"> 
+		<axsl:attribute name="fpi">
+			<xsl:value-of select="$fpi "/>
+		</axsl:attribute>
+	</xsl:if>
+	<xsl:if test="string($icon)"> 
+		<axsl:attribute name="icon">
+			<xsl:value-of select="$icon"/>
+		</axsl:attribute>
+	</xsl:if>
+	<xsl:if test="string($see)"> 
+		<axsl:attribute name="see">
+			<xsl:value-of select="$see" />
+		</axsl:attribute>
+	</xsl:if>
+	</xsl:if>
+	<xsl:if test="string($space)">
+		<axsl:attribute name="xml:space">
+			<xsl:value-of select="$space"/>
+		</axsl:attribute>
+	</xsl:if>
+	<xsl:if test="string($lang)">
+		<axsl:attribute name="xml:lang">
+			<xsl:value-of select="$lang"/>
+		</axsl:attribute>
+	</xsl:if>
+</xsl:template>
+
+<!-- processing linkable parameters. -->
+<xsl:template name='linkableParms'>
+	<xsl:param name="role"/>
+	<xsl:param name="subject"/>
+	
+	<!-- ISO SVRL has a role attribute to match the Schematron role attribute -->
+	<xsl:if test=" string($role )">
+		<axsl:attribute name="role">
+			<xsl:value-of select=" $role " />
+		</axsl:attribute>
+	</xsl:if>
+	<!-- ISO SVRL does not have a subject attribute to match the Schematron subject attribute.
+       Instead, the Schematron subject attribute is folded into the location attribute -->
+</xsl:template>
+
+
+
+	<!-- ===================================================== -->
+	<!-- Extension API:              			               -->
+	<!-- This allows the transmission of extra attributes on   -->
+	<!-- rules, asserts, reports, diagnostics.                 -->
+	<!-- ===================================================== -->
+
+
+<!-- Overrides skeleton EXPERIMENTAL -->
+<!-- The $contents is for static contents, the $value is for dynamic contents -->
+<xsl:template name="process-property">
+	<xsl:param name="id"/>
+	<xsl:param name="name"/>
+	<xsl:param name="value"/>
+	<xsl:param name="contents"/>
+	
+	<svrl:property id="{$id}" >  
+		<xsl:if test="$name">
+			<xsl:attribute name="name"><xsl:value-of select="$name"/></xsl:attribute>
+		</xsl:if>
+		
+		<xsl:if test="$value">
+			<xsl:attribute name="value"><xsl:value-of select="$value"/></xsl:attribute>
+		</xsl:if>
+		
+		<xsl:if test="$contents">
+			<xsl:copy-of select="$contents"/>
+		</xsl:if> 
+		
+	</svrl:property>
+</xsl:template>
+
+
+</xsl:stylesheet>
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/readme.txt
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/readme.txt	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/readme.txt	(revision 1843)
@@ -0,0 +1,100 @@
+<h1>ISO SCHEMATRON 2010</h1>
+
+XSLT implementation by Rick Jelliffe with assistance from members of Schematron-love-in maillist.
+
+2010-04-14
+
+Two distributions are available. One is for XSLT1 engines. 
+The other is for XSLT2 engines, such as SAXON 9.
+
+
+This version of Schematron splits the process into a pipeline of several different XSLT stages.
+
+1) First, preprocess your Schematron schema with iso_dsdl_include.xsl.  
+This is a macro processor to assemble the schema from various parts. 
+If your schema is not in separate parts, you can skip this stage.
+
+2) Second, preprocess the output from stage 1 with iso_abstract_expand.xsl.  
+This is a macro processor to convert abstract patterns to real patterns. 
+If your schema does not use abstract patterns, you can skip this
+stage.
+
+3) Third, compile the Schematron schema into an XSLT script. 
+This will typically use iso_svrl_for_xslt1.xsl or iso_svrl_for_xslt2.xsl 
+(which in turn invoke iso_schematron_skeleton_for_xslt1.xsl or iso_schematron_skeleton_for_saxon.xsl)
+However, other "meta-styleseets" are also in common use; the principle of operation is the same.
+If your schema uses Schematron phases, supply these as command line/invocation parameters
+to this process.
+
+4) Fourth, run the script generated by stage 3 against the document being validated.
+If you are using the SVRL script, then the output of validation will be an XML document.
+If your schema uses Schematron parameters, supply these as command line/invocation parameters
+to this process. 
+
+
+The XSLT2 distribution also features several next generation features, 
+such as validating multiple documents. See the source code for details.
+
+Schematron assertions can be written in any language, of course; the file
+sch-messages-en.xhtml contains the diagnostics messages from the XSLT2 skeleton
+in English, and this can be used as template to localize the skeleton's
+error messages. Note that typically programming errors in Schematron are XPath
+errors, which requires localized messages from the XSLT engine.
+
+ANT
+---
+To give an example of how to process a document, here is a sample ANT task.
+
+<target  name="schematron-compile-test" >
+
+	   <!-- expand inclusions -->
+	   <xslt basedir="test/schematron"
+	   		style="iso_dsdl_include.xsl" in="test.sch"  out="test1.sch"> 
+	   				<classpath>
+	   					<pathelement location="${lib.dir}/saxon9.jar"/>
+	   				</classpath>
+	   </xslt>
+
+	   <!-- expand abstract patterns -->
+	   <xslt basedir="test/schematron"
+	   		style="iso_abstract_expand.xsl" in="test1.sch"  out="test2.sch"> 
+	   				<classpath>
+	   					<pathelement location="${lib.dir}/saxon9.jar"/>
+	   				</classpath>
+	   </xslt>
+
+
+
+	   <!-- compile it -->
+	   <xslt basedir="test/schematron"
+	   		style="iso_svrl_for_xslt2.xsl" in="test2.sch"  out="test.xsl"> 
+	   				<classpath>
+	   					<pathelement location="${lib.dir}/saxon9.jar"/>
+	   				</classpath>
+	   </xslt>
+	   
+	   <!-- validate -->
+	   <xslt basedir="test/schematron"
+		   		style="test.xsl" in="instance.xml"  out="instance.svrlt"> 
+		   				<classpath>
+		   					<pathelement location="${lib.dir}/saxon9.jar"/>
+		   				</classpath>
+	</xslt>
+		</target>
+		
+EXTRACTION SCHEMATRON FROM XSD OR RELAX NG
+
+The following files allow extracting of embedded schematron patterns
+in XML Schemas or RELAX NG schemas. For details, see the at
+  article http://www.topologi.com/resources/schtrn_xsd_paper.html
+  
+The following files are provided:
+  ExtractSchFromRNG.xsl      Generate a Schematron schema from patterns
+                  embedded in a RELAX NG schema. The schema uses XSLT1.                 
+  ExtractSchFromXSD.xsl      Generate a Schematron schema from patterns
+                  embedded in a W3C XML Schemas schema. The schema uses XSLT1.
+                  
+  ExtractSchFromRNG-2.xsl      Generate a Schematron schema from patterns
+                  embedded in a RELAX NG schema. The schema uses XSLT2.                 
+  ExtractSchFromXSD-2.xsl      Generate a Schematron schema from patterns
+                  embedded in a W3C XML Schemas schema. The schema uses XSLT2.
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-cs.xhtml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-cs.xhtml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-cs.xhtml	(revision 1843)
@@ -0,0 +1,56 @@
+<xhtml:div class="ErrorMessages" xml:lang="cs"
+	   xmlns:xhtml="http://www.w3.org/1999/xhtml" >
+  <!-- Obsahuje-li chybovÃ© hlÃ¡Å¡enÃ­ dynamickÃ© informace, je rozdÄleno
+       do sekcÃ­ "a" a "b". RÅ¯znÃ© jazyky tak mohou dynamickÃ© informace
+       umÃ­stit s ohledem na svÃ¡ gramatickÃ¡ pravidla. -->
+    <xhtml:p id="sch-message-1-cs">Chyba ve schÃ©matu: nalezeny elementy Schematronu ve starÃ©m i novÃ©m jmennÃ©m prostoru</xhtml:p>
+    <xhtml:p id="sch-message-2-cs">Chyba ve schÃ©matu:  v atributu queryBinding pouÅŸijte 'xslt'</xhtml:p>
+    <xhtml:p id="sch-message-3a-cs">Porucha: Tato implementace ISO Schematronu nefunguje se schÃ©maty, kterÃ¡ pouÅŸÃ­vajÃ­ dotazovacÃ­ jazyk</xhtml:p>
+    <xhtml:p id="sch-message-3b-cs"/>
+    <xhtml:p id="sch-message-4a-cs">FÃ¡zovÃ¡ chyba: fÃ¡ze jmÃ©nem </xhtml:p>
+    <xhtml:p id="sch-message-4b-cs"> nenÃ­ definovÃ¡na.</xhtml:p>
+    <xhtml:p id="sch-message-5-cs">ChybnÃœ markup: v elementu &lt;active> chybÃ­ atribut pattern</xhtml:p>
+    <xhtml:p id="sch-message-6a-cs">ChybnÃœ odkaz: vzor "</xhtml:p>
+    <xhtml:p id="sch-message-6b-cs">" byl aktivovÃ¡n, ne vÅ¡ak deklarovÃ¡n</xhtml:p>
+    <xhtml:p id="sch-message-7-cs">ChybnÃœ markup: v elementu &lt;assert> chybÃ­ atribut test</xhtml:p>
+    <xhtml:p id="sch-message-8-cs">ChybnÃœ markup: v elementu &lt;report> chybÃ­ atribut test</xhtml:p>
+    <xhtml:p id="sch-message-9-cs">ChybnÃœ markup: v elementu &lt;diagnostic> chybÃ­ atribut id</xhtml:p>
+    <xhtml:p id="sch-message-10-cs">ChybnÃœ markup: v elementu &lt;extends> chybÃ­ atribut rule</xhtml:p>                  
+    <xhtml:p id="sch-message-11a-cs">ChybnÃœ odkaz: abstraktnÃ­ pravidlo "</xhtml:p>
+    <xhtml:p id="sch-message-11b-cs">" nenÃ­ definovÃ¡no, aÄkoli se na nÄ odkazuje</xhtml:p>
+    <xhtml:p id="sch-message-12-cs">ChybnÃœ markup: v elementu &lt;key> chybÃ­ atribut name</xhtml:p>
+    <xhtml:p id="sch-message-13-cs">ChybnÃœ markup: v elementu &lt;key> chybÃ­ atribut path nebo use</xhtml:p>
+    <xhtml:p id="sch-message-14-cs">ChybnÃœ markup: v elementu &lt;key> chybÃ­ atribut path nebo use</xhtml:p>
+    <xhtml:p id="sch-message-15-cs">Chyba ve schÃ©matu: element &lt;key> nenÃ­ ve jmennÃ©m prostoru ISO Schematronu. PouÅŸijte jmennÃœ prostor XSLT.</xhtml:p>
+    <xhtml:p id="sch-message-16-cs">ChybnÃœ markup: v elementu &lt;function> chybÃ­ atribut name</xhtml:p>
+    <xhtml:p id="sch-message-17-cs">Chyba ve schÃ©matu: element &lt;function> nenÃ­ ve jmennÃ©m prostoru ISO Schematronu. PouÅŸijte jmennÃœ prostor XSLT.</xhtml:p>
+    <xhtml:p id="sch-message-18-cs">Chyba ve schÃ©matu: direktiva &lt;include> mÃ¡ prÃ¡zdnÃœ atribut href</xhtml:p>
+    <xhtml:p id="sch-message-19-cs">Chyba: NesprÃ¡vnÃ© URL v direktivÄ &lt;include></xhtml:p>
+    <xhtml:p id="sch-message-20a-cs">Chyba: Nelze otevÅÃ­t vklÃ¡danÃœ soubor </xhtml:p>
+    <xhtml:p id="sch-message-20b-cs" />
+    <xhtml:p id="sch-message-21-cs">Chyba ve schÃ©matu: &lt;include> pouÅŸÃ­vejte ke vklÃ¡dÃ¡nÃ­ fragmentÅ¯, ne celÃ©ho schÃ©matu</xhtml:p>
+    <xhtml:p id="sch-message-22-cs">Chyba ve schÃ©matu: SchÃ©mata XSD lze importovat pouze pokud pouÅŸÃ­vÃ¡te dotazovacÃ­ jazyk "xslt2"</xhtml:p>
+    <xhtml:p id="sch-message-23-cs">Chyba ve schÃ©matu: element &lt;import-schema> nenÃ­ ve jmennÃ©m prostoru ISO Schematronu. PouÅŸijte jmennÃœ prostor XSLT.</xhtml:p>
+    <xhtml:p id="sch-message-24-cs">VarovÃ¡nÃ­: S dotazovacÃ­m jazykem "xpath" by se nemÄly pouÅŸÃ­vat promÄnnÃ©</xhtml:p>
+    <xhtml:p id="sch-message-25-cs">VarovÃ¡nÃ­: S dotazovacÃ­m jazykem "xpath2" by se nemÄly pouÅŸÃ­vat promÄnnÃ©</xhtml:p>
+    <xhtml:p id="sch-message-26-cs">ChybnÃœ markup: v elementu &lt;ns> chybÃ­ atribut uri</xhtml:p>
+    <xhtml:p id="sch-message-27-cs">ChybnÃœ markup: v elementu &lt;ns> chybÃ­ atribut prefix</xhtml:p>
+    <xhtml:p id="sch-message-28-cs">Chyba v implementaci schÃ©matu: toto schÃ©ma obsahuje abstraktnÃ­ vzory, kterÃ© vÅ¡ak jiÅŸ mÄly bÃœt pÅedchozÃ­m zpracovÃ¡nÃ­m odstranÄny</xhtml:p>
+    <xhtml:p id="sch-message-29-cs">ChybnÃœ markup: v elementu &lt;phase> chybÃ­ atribut id</xhtml:p>
+    <xhtml:p id="sch-message-30-cs">ChybnÃœ markup: v elementu &lt;rule> chybÃ­ atribut context</xhtml:p>
+    <xhtml:p id="sch-message-31-cs">ChybnÃœ markup: v abstraktnÃ­m pravidlu chybÃ­ atribut id</xhtml:p>
+    <xhtml:p id="sch-message-32-cs">ChybnÃœ markup: (2) AbstraktnÃ­ pravidlo nesmÃ­ mÃ­t atribut context</xhtml:p>
+    <xhtml:p id="sch-message-33-cs">ChybnÃœ markup: AbstraktnÃ­ pravidlo nesmÃ­ mÃ­t atribut context</xhtml:p>
+    <xhtml:p id="sch-message-34-cs">ChybnÃœ markup: v elementu &lt;value-of> chybÃ­ atribut select</xhtml:p>
+    <xhtml:p id="sch-message-35a-cs">VarovÃ¡nÃ­: </xhtml:p>
+    <xhtml:p id="sch-message-35b-cs"> nesmÃ­ obsahovat ÅŸÃ¡dnÃ© podelementy</xhtml:p>
+    <xhtml:p id="sch-message-36a-cs">ChybnÃœ odkaz: Diagnostika "</xhtml:p>
+    <xhtml:p id="sch-message-36b-cs">" nebyla deklarovÃ¡na, aÄkoli se na ni odkazuje</xhtml:p>
+    <xhtml:p id="sch-message-37a-cs">Chyba: procesor </xhtml:p>
+    <xhtml:p id="sch-message-37b-cs"> nepodporuje pouÅŸitÃ­ jmennÃ©ho prostoru XSLT s jinÃœm prefixem neÅŸ "xsl"</xhtml:p>
+    <xhtml:p id="sch-message-38a-cs">Chyba: neznÃ¡mÃœ element </xhtml:p>
+    <xhtml:p id="sch-message-38b-cs"> ve jmennÃ©m prostoru ISO Schematronu: zkontrolujte, je-li sprÃ¡vnÄ zapsÃ¡n</xhtml:p>
+    <xhtml:p id="sch-message-39a-cs">VarovÃ¡nÃ­: neznÃ¡mÃœ element 
+</xhtml:p>
+    <xhtml:p id="sch-message-39b-cs" />
+ </xhtml:div>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-de.xhtml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-de.xhtml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-de.xhtml	(revision 1843)
@@ -0,0 +1,57 @@
+ 
+<xhtml:div class="ErrorMessages"   xml:lang="en"
+    xmlns:xhtml="http://www.w3.org/1999/xhtml" >	
+	<!-- Where the error message contains dynamic information, the message has been split into an "a" and a "b" section.
+	     This has been done even when the English does not require it, in order to accomodate different language grammars
+	     that might position the dynamic information differently.
+	-->
+	<xhtml:p id="sch-message-1-de">Fehler im Schema: Schematron Elemente sowohl im alten als auch neuen Namensraum gefunden</xhtml:p>
+	<xhtml:p id="sch-message-2-de">Fehler im Schema: Nutzen Sie 'xslt' im queryBinding-Attribut</xhtml:p>
+	<xhtml:p id="sch-message-3a-de">Fehler: Diese Implementierung von ISO Schematron arbeitet nicht mit Schemas zusammen, die die Query Language  </xhtml:p>
+	<xhtml:p id="sch-message-3b-de">nutzen</xhtml:p>
+	<xhtml:p id="sch-message-4a-de">Phasenfehler: Es gibt keine Phase mit Namen </xhtml:p>
+	<xhtml:p id="sch-message-4b-de" />
+	<xhtml:p id="sch-message-5-de">Fehler in der Annotation: Kein Attribut pattern in &lt;active></xhtml:p>
+	<xhtml:p id="sch-message-6a-de">Referenzierungsfehler: Der Ausdruck  "</xhtml:p>
+	<xhtml:p id="sch-message-6b-de">" wurde aktiviert, ist aber nicht deklariert</xhtml:p>
+	<xhtml:p id="sch-message-7-de">Fehler in der Annotation: Kein Attribut test in &lt;assert</xhtml:p>
+	<xhtml:p id="sch-message-8-de">Fehler in der Annotation: Kein Attribut test &lt;report></xhtml:p>
+	<xhtml:p id="sch-message-9-de">Fehler in der Annotation: Kein Attribut id in &lt;diagnostic></xhtml:p>
+	<xhtml:p id="sch-message-10-de">Fehler in der Annotation: Kein Attribut rule in &lt;extends></xhtml:p>				   
+	<xhtml:p id="sch-message-11a-de">Referenzierungsfehler: Die abstrakte Regel  "</xhtml:p>
+	<xhtml:p id="sch-message-11b-de">" wurde referenziert, ist aber nicht deklariert</xhtml:p>				
+	<xhtml:p id="sch-message-12-de">Fehler in der Annotation: Kein Attribut name in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-13-de">Fehler in der Annotation: Kein Attribut path oder use in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-14-de">Fehler in der Annotation: Kein Attribut path oder use in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-15-de">Fehler im Schema: Das Element key ist im ISO Schematron-Namensraum nicht vorhanden. Benutzen Sie den XSLT-Namensraum.</xhtml:p>
+	<xhtml:p id="sch-message-16-de">Fehler in der Annotation: Kein Attribut name in &lt;function></xhtml:p>
+	<xhtml:p id="sch-message-17-de">Fehler im Schema: Das Element function ist im ISO Schematron-Namensraum nicht vorhanden. Benutzen Sie den XSLT-Namensraum.</xhtml:p>
+	<xhtml:p id="sch-message-18-de">Fehler im Schema: Leeres Attribut href= fÃŒr include Anweisung.</xhtml:p>
+	<xhtml:p id="sch-message-19-de">Fehler: UngÃŒltige URL in Schematron include</xhtml:p>
+	<xhtml:p id="sch-message-20a-de">Kann die referenzierte Datei nicht Ã¶ffnen: </xhtml:p>
+	<xhtml:p id="sch-message-20b-de" />
+	<xhtml:p id="sch-message-21-de">Fehler im Schema: include darf nur zur Einbettung von Schemafragmenten genutzt werden, nicht fÃŒr ganze Schemata</xhtml:p>
+	<xhtml:p id="sch-message-22-de">Fehler im Schema: XSD Schemata dÃŒrfen nur importiert werden, wenn das 'xslt2' Query Language Binding genutzt wird</xhtml:p>
+	<xhtml:p id="sch-message-23-de">Fehler im Schema: Das Element import-schema ist im ISO Schematron-Namensraum nicht vorhanden. Benutzen Sie den XSLT-Namensraum.</xhtml:p>
+	<xhtml:p id="sch-message-24-de">Warnung: Variablen sollten nicht zusammen mit dem "xpath" Query Language Binding genutzt werden.</xhtml:p>
+	<xhtml:p id="sch-message-25-de">Warnung: Variablen sollten nicht zusammen mit dem "xpath2" Query Language Binding genutzt werden.</xhtml:p>
+	<xhtml:p id="sch-message-26-de">Fehler in der Annotation: Fehlendes Attiribut uri in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-27-de">Fehler in der Annotation: Fehlendes Attribut prefix in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-28-de">Fehler bei der Schemaimplementierung: Dieses Schema enthÃ€lt abstrakte Mustervergleiche, die bereits vorverarbeitet sein sollten.</xhtml:p>
+    <xhtml:p id="sch-message-29-de">Fehler in der Annotation: Fehlendes Attiribut id in &lt;phase></xhtml:p>
+    <xhtml:p id="sch-message-30-de">Fehler in der Annotation: Fehlendes Attiribut context in &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-31-de">Fehler in der Annotation: Fehlendes Attiribut id on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-32-de">Fehler in der Annotation: (2) context attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-33-de">Fehler in der Annotation: Attribut context bei abstrakter &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-34-de">Fehler in der Annotation: Fehlendes Attiribut select in &lt;value-of></xhtml:p>
+    <xhtml:p id="sch-message-35a-de">Warnung: </xhtml:p>
+	<xhtml:p id="sch-message-35b-de"> darf keine Kindelemente beinhalten</xhtml:p>
+    <xhtml:p id="sch-message-36a-de">Referenzierungsfehler: Ein diagnostic-Element "</xhtml:p>
+	<xhtml:p id="sch-message-36b-de">" wurde referenziert, ist aber nicht deklariert</xhtml:p>
+	<xhtml:p id="sch-message-37a-de">Der Gebrauch des XSLT-Namensraums mit einem anderen PrÃ€fix als "xsl" in Schematron-Regeln wird von diesem Prozessor nicht unterstÃŒtzt:</xhtml:p>
+    <xhtml:p id="sch-message-37b-de" />
+    <xhtml:p id="sch-message-38a-de">Fehler: Unbekanntes Element im ISO Schematron-Namensraum: ÃberprÃŒfen Sie die Schreibweise (inkl. GroÃ- und Kleinschreibung)</xhtml:p>
+	<xhtml:p id="sch-message-38b-de" />
+	<xhtml:p id="sch-message-39a-de">Warnung: Unbekanntes Element </xhtml:p>
+	<xhtml:p id="sch-message-39b-de" />
+ </xhtml:div>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-en.xhtml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-en.xhtml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-en.xhtml	(revision 1843)
@@ -0,0 +1,57 @@
+ 
+<xhtml:div class="ErrorMessages"   xml:lang="en"
+    xmlns:xhtml="http://www.w3.org/1999/xhtml" >	
+	<!-- Where the error message contains dynamic information, the message has been split into an "a" and a "b" section.
+	     This has been done even when the English does not require it, in order to accomodate different language grammars
+	     that might position the dynamic information differently.
+	-->
+	<xhtml:p id="sch-message-1-en">Schema error: Schematron elements in old and new namespaces found</xhtml:p>
+	<xhtml:p id="sch-message-2-en">Schema error: in the queryBinding attribute, use 'xslt'</xhtml:p>
+	<xhtml:p id="sch-message-3a-en">Fail: This implementation of ISO Schematron does not work with schemas using the query language </xhtml:p>
+	<xhtml:p id="sch-message-3b-en"/>
+	<xhtml:p id="sch-message-4a-en">Phase Error: no phase has been defined with name </xhtml:p>
+	<xhtml:p id="sch-message-4b-en" />
+	<xhtml:p id="sch-message-5-en">Markup Error: no pattern attribute in &lt;active></xhtml:p>
+	<xhtml:p id="sch-message-6a-en">Reference Error: the pattern  "</xhtml:p>
+	<xhtml:p id="sch-message-6b-en">" has been activated but is not declared</xhtml:p>
+	<xhtml:p id="sch-message-7-en">Markup Error: no test attribute in &lt;assert></xhtml:p>
+	<xhtml:p id="sch-message-8-en">Markup Error: no test attribute in &lt;report></xhtml:p>
+	<xhtml:p id="sch-message-9-en">Markup Error: no id attribute in &lt;diagnostic></xhtml:p>
+	<xhtml:p id="sch-message-10-en">Markup Error: no rule attribute in &lt;extends></xhtml:p>				   
+	<xhtml:p id="sch-message-11a-en">Reference Error: the abstract rule  "</xhtml:p>
+	<xhtml:p id="sch-message-11b-en">" has been referenced but is not declared</xhtml:p>				
+	<xhtml:p id="sch-message-12-en">Markup Error: no name attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-13-en">Markup Error: no path or use attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-14-en">Markup Error: no path or use attribute in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-15-en">Schema error: The &lt;key> element is not in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-16-en">Markup Error: no name attribute in &lt;function></xhtml:p>
+	<xhtml:p id="sch-message-17-en">Schema error: The &lt;function> element is not in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-18-en">Schema error: Empty href attribute for &lt;include> directive.</xhtml:p>
+	<xhtml:p id="sch-message-19-en">Error: Impossible URL in Schematron &lt;include></xhtml:p>
+	<xhtml:p id="sch-message-20a-en">Error: Unable to open referenced included file: </xhtml:p>
+	<xhtml:p id="sch-message-20b-en" />
+	<xhtml:p id="sch-message-21-en">Schema error: Use &lt;include> to include fragments, not a whole schema</xhtml:p>
+	<xhtml:p id="sch-message-22-en">Schema error: XSD schemas may only be imported if you are using the 'xslt2' query language binding</xhtml:p>
+	<xhtml:p id="sch-message-23-en">Schema error: The &lt;import-schema> element is not available in the ISO Schematron namespace. Use the XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-24-en">Warning: Variables should not be used with the "xpath" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-25-en">Warning: Variables should not be used with the "xpath2" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-26-en">Markup Error: no uri attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-27-en">Markup Error: no prefix attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-28-en">Schema implementation error: This schema has abstract patterns, yet they are supposed to be preprocessed out already</xhtml:p>
+    <xhtml:p id="sch-message-29-en">Markup Error: no id attribute in &lt;phase></xhtml:p>
+    <xhtml:p id="sch-message-30-en">Markup Error: no context attribute in &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-31-en">Markup Error: no id attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-32-en">Markup Error: (2) context attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-33-en">Markup Error: context attribute on abstract &lt;rule></xhtml:p>
+    <xhtml:p id="sch-message-34-en">Markup Error: no select attribute in &lt;value-of></xhtml:p>
+    <xhtml:p id="sch-message-35a-en">Warning: </xhtml:p>
+	<xhtml:p id="sch-message-35b-en"> must not contain any child elements</xhtml:p>
+    <xhtml:p id="sch-message-36a-en">Reference error: A diagnostic "</xhtml:p>
+	<xhtml:p id="sch-message-36b-en">" has been referenced but is not declared</xhtml:p>
+	<xhtml:p id="sch-message-37a-en">Warning: Using the XSLT namespace with a prefix other than "xsl" in Schematron rules is not supported in this processor:</xhtml:p>
+    <xhtml:p id="sch-message-37b-en" />
+    <xhtml:p id="sch-message-38a-en">Error: unrecognized element in ISO Schematron namespace: check spelling and capitalization</xhtml:p>
+	<xhtml:p id="sch-message-38b-en" />
+	<xhtml:p id="sch-message-39a-en">Warning: unrecognized element </xhtml:p>
+	<xhtml:p id="sch-message-39b-en" />
+ </xhtml:div>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-fr.xhtml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-fr.xhtml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-fr.xhtml	(revision 1843)
@@ -0,0 +1,54 @@
+<xhtml:div class="ErrorMessages" xml:lang="fr" xmlns:xhtml="http://www.w3.org/1999/xhtml">	
+   <!-- Where the error message contains dynamic information, the message has been split into an "a" and a "b" section.
+        This has been done even when the English does not require it, in order to accomodate different language grammars
+        that might position the dynamic information differently.
+   -->
+   <xhtml:p id="sch-message-1-fr">Erreur de schema: Ã©lÃ©ments Schematron Ã  la fois dans l'ancien et le nouveau namespace</xhtml:p>
+   <xhtml:p id="sch-message-2-fr">Erreur de schema: utilisez 'xslt' dans l'attribut queryBinding</xhtml:p>
+   <xhtml:p id="sch-message-3a-fr">Ãchec: Cette implÃ©mentation de Schematron ISO ne fonctionne pas avec des schemas utilisant le langage de query </xhtml:p>
+   <xhtml:p id="sch-message-3b-fr"/>
+   <xhtml:p id="sch-message-4a-fr">Erreur de phase: aucune phase n'a Ã©tÃ© dÃ©finie avec le nom </xhtml:p>
+   <xhtml:p id="sch-message-4b-fr"/>
+   <xhtml:p id="sch-message-5-fr">Erreur de balisage: pas d'attribut pattern dans &lt;active></xhtml:p>
+   <xhtml:p id="sch-message-6a-fr">Erreur de rÃ©fÃ©rence: le pattern "</xhtml:p>
+   <xhtml:p id="sch-message-6b-fr">" a Ã©tÃ© activÃ© mais n'a pas Ã©tÃ© dÃ©calarÃ©</xhtml:p>
+   <xhtml:p id="sch-message-7-fr">Erreur de balisage: pas d'attribut test dans &lt;assert></xhtml:p>
+   <xhtml:p id="sch-message-8-fr">Erreur de balisage: pas d'attribut test dans &lt;report></xhtml:p>
+   <xhtml:p id="sch-message-9-fr">Erreur de balisage: pas d'attribut id dans &lt;diagnostic></xhtml:p>
+   <xhtml:p id="sch-message-10-fr">Erreur de balisage: pas d'attribut rule dans &lt;extends></xhtml:p>
+   <xhtml:p id="sch-message-11a-fr">Erreur de rÃ©fÃ©rence: la rÃšgle abstraite "</xhtml:p>
+   <xhtml:p id="sch-message-11b-fr">" a Ã©tÃ© rÃ©fÃ©rencÃ©e mais pas dÃ©clarÃ©e</xhtml:p>
+   <xhtml:p id="sch-message-12-fr">Erreur de balisage: pas d'attribut name dans &lt;key></xhtml:p>
+   <xhtml:p id="sch-message-13-fr">Erreur de balisage: pas d'attribut path ou use dans &lt;key></xhtml:p>
+   <xhtml:p id="sch-message-15-fr">Erreur de schema: L'Ã©lÃ©ment key n'est pas dans le namespace Schematron ISO.  Utilisez le namespace XSLT.</xhtml:p>
+   <xhtml:p id="sch-message-16-fr">Erreur de balisage: pas d'attribut name dans &lt;function></xhtml:p>
+   <xhtml:p id="sch-message-17-fr">Erreur de schema: L'Ã©lÃ©ment function n'est pas dans le namespace Schematron ISO.  Utilisez le namespace XSLT.</xhtml:p>
+   <xhtml:p id="sch-message-18-fr">Erreur de schema: Attribut href vide sur a directive include.</xhtml:p>
+   <xhtml:p id="sch-message-19-fr">Erreur: URL impossible dans la directive include de Schematron</xhtml:p>
+   <xhtml:p id="sch-message-20a-fr">Impossible d'ouvrir le fichier rÃ©fÃ©rencÃ© pour l'inclusion: </xhtml:p>
+   <xhtml:p id="sch-message-20b-fr"/>
+   <xhtml:p id="sch-message-21-fr">Erreur de schema: Utilisez include pour inclure des fragments et non un schema entier</xhtml:p>
+   <xhtml:p id="sch-message-22-fr">Erreur de schema: Les schema XSD peuvent Ãªtre importÃ©s seulement si vous utilisez the langage de query 'xslt2'</xhtml:p>
+   <xhtml:p id="sch-message-23-fr">Erreur de schema: L'Ã©lÃ©ment import-schema n'est pas disponible dans le namespace Schematron ISO.  Utilisez le namespace XSLT.</xhtml:p>
+   <xhtml:p id="sch-message-24-fr">Avertissement: Des variables ne devraient pas Ãªtre utiliÃ©es avec le langage de query "xpath".</xhtml:p>
+   <xhtml:p id="sch-message-24-fr">Avertissement: Des variables ne devraient pas Ãªtre utiliÃ©es avec le langage de query "xpath2".</xhtml:p>
+   <xhtml:p id="sch-message-26-fr">Erreur de balisage: pas d'attribut uri dans &lt;ns></xhtml:p>
+   <xhtml:p id="sch-message-27-fr">Erreur de balisage: pas d'attribut prefix dans &lt;ns></xhtml:p>
+   <xhtml:p id="sch-message-28-fr">Erreur d'implÃ©mentation de schema: Ce schema des patterns abstraits, bien qu'ils sont supposÃ©s avoir Ã©tÃ© prÃ©processÃ©s prÃ©cÃ©demment</xhtml:p>
+   <xhtml:p id="sch-message-29-fr">Erreur de balisage: pas d'attribut id dans &lt;phase></xhtml:p>
+   <xhtml:p id="sch-message-30-fr">Erreur de balisage: pas d'attribut context dans &lt;rule></xhtml:p>
+   <xhtml:p id="sch-message-31-fr">Erreur de balisage: pas d'attribut id dans &lt;rule></xhtml:p>
+   <xhtml:p id="sch-message-32-fr">Erreur de balisage: (2) attribut context dans une &lt;rule> abstraite</xhtml:p>
+   <xhtml:p id="sch-message-33-fr">Erreur de balisage: attribut context dans une &lt;rule> abstraite</xhtml:p>
+   <xhtml:p id="sch-message-34-fr">Erreur de balisage: pas d'attribut select dans &lt;value-of></xhtml:p>
+   <xhtml:p id="sch-message-35a-fr">Avertissement: </xhtml:p>
+   <xhtml:p id="sch-message-35b-fr"> ne peut contenir aucun Ã©lÃ©ment enfant</xhtml:p>
+   <xhtml:p id="sch-message-36a-fr">Erreur de rÃ©fÃ©rence: Un diagnostique "</xhtml:p>
+   <xhtml:p id="sch-message-36b-fr">" a Ã©tÃ© rÃ©fÃ©rencÃ© mais n'est pas dÃ©clarÃ©</xhtml:p>
+   <xhtml:p id="sch-message-37a-fr">Utiliser the namespace XSLT avec un autre prÃ©fixe que "xsl" dans les rules Schematron n'est pas supportÃ© par ce processor:</xhtml:p>
+   <xhtml:p id="sch-message-37b-fr"/>
+   <xhtml:p id="sch-message-38a-fr">Erreur: Ã©lÃ©ment inconnu dans le namespace Schematron ISO: vÃ©rifiez l'orthographe et la casse</xhtml:p>
+   <xhtml:p id="sch-message-38b-fr"/>
+   <xhtml:p id="sch-message-39a-fr">Avertissement: Ã©lÃ©ment inconnu</xhtml:p>
+   <xhtml:p id="sch-message-39b-fr"/>
+</xhtml:div>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-nl.xhtml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-nl.xhtml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/sch-messages-nl.xhtml	(revision 1843)
@@ -0,0 +1,58 @@
+ <xhtml:div class="ErrorMessages" xml:lang="nl" xmlns:xhtml="http://www.w3.org/1999/xhtml">
+	<!-- Where the error message contains dynamic information, the message has been split into an "a" and a "b" section.
+	     This has been done even when the English does not require it, in order to accomodate different language grammars
+	     that might position the dynamic information differently.
+	-->
+	<xhtml:p id="sch-message-1-nl">Schema fout: er werden Schematron elementen uit de oude en nieuwe
+		namespace gevonden</xhtml:p>
+	<xhtml:p id="sch-message-2-nl">Schema fout: gebruik 'xslt' in het queryBinding attribute</xhtml:p>
+	<xhtml:p id="sch-message-3a-nl">Faling: Deze implementatie van ISO Schematron werkt niet met
+		schemas die gebruik maken van de query language </xhtml:p>
+	<xhtml:p id="sch-message-3b-nl"/>
+	<xhtml:p id="sch-message-4a-nl">Fase fout: er is geen 'phase' gedefinieerd met naam </xhtml:p>
+	<xhtml:p id="sch-message-4b-nl"/>
+	<xhtml:p id="sch-message-5-nl">Markup fout: er is geen 'pattern' attribuut in &lt;active></xhtml:p>
+	<xhtml:p id="sch-message-6a-nl">Referentie fout: het 'pattern' "</xhtml:p>
+	<xhtml:p id="sch-message-6b-nl">" is geactiveerd maar niet gedeclareerd</xhtml:p>
+	<xhtml:p id="sch-message-7-nl">Markup fout: er is geen 'test' attribuut in &lt;assert</xhtml:p>
+	<xhtml:p id="sch-message-8-nl">Markup fout: er is geen 'test' attribuut in &lt;report></xhtml:p>
+	<xhtml:p id="sch-message-9-nl">Markup fout: er is geen 'id' attribuut in &lt;diagnostic></xhtml:p>
+	<xhtml:p id="sch-message-10-nl">Markup fout: er is geen 'rule' attribuut in &lt;extends></xhtml:p>
+	<xhtml:p id="sch-message-11a-nl">Referentie fout: de abstracte regel "</xhtml:p>
+	<xhtml:p id="sch-message-11b-nl">" werd gerefereerd maar niet gedeclareerd</xhtml:p>
+	<xhtml:p id="sch-message-12-nl">Markup fout: er is geen 'name' attribuut in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-13-nl">Markup fout: er is geen 'path' of 'use' attribuut in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-14-nl">Markup fout: er is geen 'path' of 'use' attribuut in &lt;key></xhtml:p>
+	<xhtml:p id="sch-message-15-nl">Schema fout: Het 'key' element zit niet in de ISO Schematron namespace. Gebruik de XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-16-nl">Markup fout: er is geen 'name' attribuut in &lt;function></xhtml:p>
+	<xhtml:p id="sch-message-17-nl">Schema fout: Het 'function' element zit niet in de ISO Schematron namespace. Gebruik de XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-18-nl">Schema fout: Leeg 'href=' attribuut bij de include opdracht.</xhtml:p>
+	<xhtml:p id="sch-message-19-nl">Fout: Onmogelijke URL gebruikt bij de Schematron include</xhtml:p>
+	<xhtml:p id="sch-message-20a-nl">Kan de gerefereerde 'include' file niet openen: </xhtml:p>
+	<xhtml:p id="sch-message-20b-nl"/>
+	<xhtml:p id="sch-message-21-nl">Schema fout: Gebruik include om fragmenten op te nemen, niet een volledig schema</xhtml:p>
+	<xhtml:p id="sch-message-22-nl">Schema fout: XSD schemas kunnen enkel geÃ¯mporteerd worden indien de 'xslt2' query language binding gebruikt is</xhtml:p>
+	<xhtml:p id="sch-message-23-nl">Schema fout: Het 'import-schema' element is niet beschikbaar in the ISO Schematron namespace. Gebruik de XSLT namespace.</xhtml:p>
+	<xhtml:p id="sch-message-24-nl">Waarschuwing: Variabelen niet gebruiken met de "xpath" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-25-nl">Waarschuwing: Variabelen niet gebruiken met de "xpath2" query language binding.</xhtml:p>
+	<xhtml:p id="sch-message-26-nl">Markup fout: er is geen 'uri' attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-27-nl">Markup fout: er is geen 'prefix' attribute in &lt;ns></xhtml:p>
+	<xhtml:p id="sch-message-28-nl">Schema implementatie fout: Dit schema heeft abstracte patronen, die al gepreprocessed zouden moeten zijn</xhtml:p>
+	<xhtml:p id="sch-message-29-nl">Markup fout: er is geen 'id' attribuut in &lt;phase></xhtml:p>
+	<xhtml:p id="sch-message-30-nl">Markup fout: er is geen 'context' attribuut in &lt;rule></xhtml:p>
+	<xhtml:p id="sch-message-31-nl">Markup fout: er is geen 'id' attribuut op abstracte &lt;rule></xhtml:p>
+	<xhtml:p id="sch-message-32-nl">Markup fout: (2) context attributen op abstracte &lt;rule></xhtml:p>
+	<xhtml:p id="sch-message-33-nl">Markup fout: context attribuut op abstracte &lt;rule></xhtml:p>
+	<xhtml:p id="sch-message-34-nl">Markup fout: er is geen 'select' attribute in &lt;value-of></xhtml:p>
+	<xhtml:p id="sch-message-35a-nl">Waarschuwing: </xhtml:p>
+	<xhtml:p id="sch-message-35b-nl"> mag geen kind elementen bevatten</xhtml:p>
+	<xhtml:p id="sch-message-36a-nl">Referentie fout: Een diagnostic "</xhtml:p>
+	<xhtml:p id="sch-message-36b-nl">" werd gerefereerd maar is niet gedeclareerd.</xhtml:p>
+	<xhtml:p id="sch-message-37a-nl">Het gebruik van de XSLT namespace met een prefix verschillend
+		van "xsl" in Schematron regels wordt niet ondersteund in deze processor:</xhtml:p>
+	<xhtml:p id="sch-message-37b-nl"/>
+	<xhtml:p id="sch-message-38a-nl">Fout: een niet herkend element in de ISO Schematron namespace: check spelling en hoofdlettergebruik</xhtml:p>
+	<xhtml:p id="sch-message-38b-nl"/>
+	<xhtml:p id="sch-message-39a-nl">Waarschuwing: een niet herkend element </xhtml:p>
+	<xhtml:p id="sch-message-39b-nl"/>
+</xhtml:div>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/schematron-skeleton-api.htm
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/schematron-skeleton-api.htm	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/main/resources/schematron/schematron-skeleton-api.htm	(revision 1843)
@@ -0,0 +1,723 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
+	<TITLE>The ISO Schematron Skeleton API</TITLE>
+	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.4  (Win32)">
+	<META NAME="CREATED" CONTENT="0;0">
+	<META NAME="CHANGED" CONTENT="20080808;2200065">
+</HEAD>
+<BODY LANG="en-AU" DIR="LTR">
+<H1>API for ISO Schematron Skeleton</H1>
+<H2><BR><BR>
+</H2>
+<P>Rick Jelliffe, 2010/04/14</P>
+<P>This document provides documentation on the XSLT API available in
+the implementation of Schematron called <TT>iso_schematron_skeleton.xsl</TT>.
+(available in an XSLT1 and XSLT2 version). The API makes available as
+much information from the schema, however there may be some edge
+cases where it is not exhaustive.   
+</P>
+<P>The <I>skeleton</I> is an XSLT script which provides all the basic
+parsing and validating routines for compiling a Schematron schema
+into XSLT. Schematron was designed to allow many different uses, and
+the skeleton gives you a headstart in creating a customized
+implementation. You just need to write XSLT templates to override the
+default ones. (The program you write is sometimes called a
+<I>meta-stylesheet</I>.)   It is the meta-stylesheet that is called
+as the XSLT script, not the skeleton. There are several
+pre-processing stages which the Schematron schema should be processed
+through first, to handle such things as include statements and
+abstract patterns. 
+</P>
+<P>Phases and error reporting for problems in the schema itself are
+handled by the skeleton with no interaction with a &ldquo;meta-stylesheet&rdquo;.
+Note that there is no guarantee that the context node is always the
+element being handled: in most cases the only information available
+is the information in the parameters. 
+</P>
+<P>For an introductory tutorial on using this API, see Bob DuCharme's
+<A HREF="http://www.xml.com/pub/a/2004/10/05/tr.html">Schematron 1.5:
+Looking Under the Hood</A> 
+</P>
+<H1>Superset of API for Schematron 1.5 and 1.6</H1>
+<P>(This is an updated version of the API for the Schematron 1.5
+implementation called <TT>skeleton1-5.xsl</TT>, which in turn comes
+from the <I>new architecture</I> contributed by Oliver Becker for
+Schematron 1.3.)</P>
+<P>The current API contains only additions. Well-written
+meta-stylesheets that use the new API will be be able to run on the
+existing 1.5 and 1.6 skeletons. Similarly, it should be possible to
+upgrade the skeleton from 1.5 or 1.6 to the iso-schematron-skeleton
+only by correcting the import statement at the beginning of the
+meta-stylsheet. Additions or re-groupings from the 1.5 schema are
+shown in red. Deletions have overstrike.</P>
+<P>Mooted addition: a parameter @action  which for specifying
+processing instructions on assertions and reports.</P>
+<HR>
+<H2><TT>process-prolog</TT></H2>
+<P>The <TT>process-prolog</TT> template gets called at the start of
+the validation session. It has no parameters. The default
+implementation is no action.</P>
+<HR>
+<H2><TT>process-root</TT></H2>
+<P>The <TT>process-root</TT> template processes the root element of
+the schema (which is not the same thing as the root of the document /
+and need not be the document element /*) .</P>
+<DL>
+	<DT><TT><I>node-list</I></TT><TT> $contents</TT> 
+	</DT><DT>
+	<TT><I>string</I></TT><TT> $schemaVersion</TT> 
+	</DT><DD>
+	The version of the schema, perhaps a datestamp. 
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;xslt&quot; | &quot;xpath&quot; |
+	&quot;xslt2&quot; | ...</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$queryBinding</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The query language binding. </FONT>
+	</DD><DT>
+	<TT><I>string</I></TT><TT> $title</TT> 
+	</DT><DD>
+	The title of this schema 
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;iso&quot; | &quot;1.5&quot; |
+	&quot;1.6&quot; | ...</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$version</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The version of Schematron being used. </FONT>
+	</DD></DL>
+<P>
+Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for the
+	</FONT><TT><FONT COLOR="#ff0000">schema</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this schema. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this schema, from
+	xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">Link to documentation on WWW or file </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD></DL>
+<P>
+To print the documentation paragraphs, use <TT>&lt;xsl:apply-templates
+mode=&quot;do-schema-p&quot; /&gt;</TT></P>
+<P>To output the results, use <TT>&lt;xsl:copy-of select=&quot;$contents&quot;
+/&gt;</TT></P>
+<HR>
+<H2><TT>process-assert</TT></H2>
+<P>The <TT>process-assert</TT> template handles asserts whose test
+has failed. 
+</P>
+<DL>
+	<DT><TT><I>XPath</I></TT><TT> $test</TT> 
+	</DT><DD>
+	The test 
+	</DD><DT>
+	<TT><I>XML IDREFS</I></TT><TT> $diagnostics</TT> 
+	</DT><DD>
+	A list of the idrefs diagnostic elements related to the current
+	assertion 
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML NMTOKEN</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$flag</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The name of a flag that becomes true because
+	this assertion fails. The flag is true for the document if it is
+	flagged true on any assertion. For compatability, this parameter
+	should not be used with Schematron 1.5.</FONT> 
+	</DD></DL>
+<P>
+Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for the
+	</FONT><TT><FONT COLOR="#ff0000">assert</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this
+	assertion. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this assertion,
+	from xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">Link to documentation on WWW or file </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD></DL>
+<P>
+Linking properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML NMTOKEN</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$role</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">A name for the generic role of this assertion.
+	The schema creator would have their own vocabulary. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XPath</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$subject</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">A path relative to the current context to some
+	interesting node considered the subject. </FONT>
+	</DD></DL>
+<P>
+To print the text contents, use <TT>&lt;xsl:apply-templates
+mode=&quot;text&quot; /&gt;</TT></P>
+<HR>
+<H2><TT>process-diagnostic</TT></H2>
+<P>The <TT>process-diagnostic</TT> template handles diagnostic
+messages for <TT>assert</TT> statements that have failed and <TT>report</TT>
+statements that have succeeded. The diagnostics are evaluated in the
+context of the rule.</P>
+<P>Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for the
+	</FONT><TT><FONT COLOR="#ff0000">assert</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this
+	assertion. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this assertion,
+	from xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">Link to documentation on WWW or file </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD><HR>
+</DL>
+<H2><TT>process-dir</TT></H2>
+<P>The <TT>process-dir</TT> template handles bi-directionality
+markup, which is only needed by certain human scripts such as Arabic.</P>
+<DL>
+	<DT><TT><I>&quot;ltr&quot; or &quot;rtl&quot; or &quot;&quot;</I></TT><TT>
+	$value</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	Left-to-right or right-to-left or unspecified 
+	</DD><HR>
+</DL>
+<H2><TT>process-emph</TT></H2>
+<P>The <TT>process-emph</TT> template handles the markup of
+emphasized text in paragraphs, assertions and diagnostics. It has no
+parameters.</P>
+<HR>
+<H2><TT>process-message</TT></H2>
+<P>The <TT>process-message</TT> handles default outputing of text.</P>
+<DL>
+	<DT><TT><I>string</I></TT><TT> $pattern</TT> 
+	</DT><DD>
+	Some text that may be some kind of pattern 
+	</DD><DT>
+	<TT><I>string</I></TT><TT> $role</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	Some text that may be some kind of role 
+	</DD><HR>
+</DL>
+<H2><TT>process-name</TT></H2>
+<P>The <TT>process-name</TT> templates handle name strings that can
+be used in assertions. <TT>asssert</TT> and <TT>report</TT> only
+provide <TT>name</TT> subelements rather than the more general
+<TT>value-of</TT> elements to encourage plain language and generic
+descriptions rather than specific diagnostics, for which purpose the
+<TT>diagnostics</TT> elements are used.</P>
+<DL>
+	<DT><TT><I>string</I></TT><TT> $name</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	The name of the current element, or of the node specified by a <TT>name</TT>
+	element 
+	</DD><HR>
+</DL>
+<H2><TT>process-ns</TT></H2>
+<P>The <TT>process-ns</TT> template reports on <TT>ns</TT>
+declarations, which are used to transmit on namespace information by
+the skeleton.</P>
+<DL>
+	<DT><TT><I>Namespace NCName</I></TT><TT> $prefix</TT> 
+	</DT><DD>
+	The prefix of a namespace 
+	</DD><DT>
+	<TT><I>XML SystemId</I></TT><TT> $uri</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	The (internationalized) URI Reference of a namespace 
+	</DD><HR>
+</DL>
+<H2><TT>process-p</TT></H2>
+<P>The <TT>process-p</TT> template handles paragraphs.</P>
+<DL>
+	<DT><TT><I>XML NMTOKEN</I></TT><TT> $class</TT> 
+	</DT><DD>
+	An attribute that can be used for stylesheet style 
+	</DD><DT>
+	<TT><I>XML ID</I></TT><TT> $id</TT> 
+	</DT><DD>
+	The unique identifier with the schema for the <TT>p</TT> element. 
+	</DD><DT>
+	<TT><I>XML SystemId</I></TT><TT> $icon</TT> 
+	</DT><DD>
+	The URI of an icon 
+	</DD><DT>
+	<TT><I>IETF Language</I></TT><TT> $lang</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	The human language used in this paragraph 
+	</DD></DL>
+<P>
+To print the text contents, use <TT>&lt;xsl:apply-templates
+mode=&quot;text&quot; /&gt;</TT> 
+</P>
+<HR>
+<H2><TT>process-pattern</TT></H2>
+<P>The <TT>process-pattern</TT> reports on the start of evaluation of
+a <TT>pattern</TT> element.</P>
+<DL>
+	<DT><TT><I>string</I></TT><TT> $name</TT> 
+	</DT><DD>
+	The title of the current pattern 
+	</DD><DT>
+	<TT><I>XML NCNAMES</I></TT><TT> $is-a</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	Empty or not provided if the pattern is not derived from an abstract
+	pattern. Otherwise the name of the abstract pattern. A list may be
+	used if there was a sequence of abstract patterns. 
+	</DD></DL>
+<P>
+Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for the
+	</FONT><TT><FONT COLOR="#ff0000">pattern</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this pattern.
+	</FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this pattern, from
+	xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">A (internationalized) URI reference to some
+	supporting or defining documentation </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD></DL>
+<P>
+To print the documentation contents, use <TT>&lt;xsl:apply-templates
+mode=&quot;do-pattern-p&quot;/&gt;</TT></P>
+<HR>
+<H2><TT>process-report</TT></H2>
+<P>The <TT>process-report</TT> template handles <TT>report</TT> whose
+test has succeeded. 
+</P>
+<DL>
+	<DT><TT><I>XPath</I></TT><TT> $test</TT> 
+	</DT><DD>
+	The test 
+	</DD><DT>
+	<TT><I>XML IDREFS</I></TT><TT> $diagnostics</TT> 
+	</DT><DD>
+	A list of the diagnostic elements related to the current assertion 
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML NMTOKEN</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$flag</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The name of a flag that becomes true because
+	this assertion fails. The flag is true for the document if it is
+	flagged true on any assertion. For compatability, this parameter
+	should not be used with Schematron 1.5.</FONT> 
+	</DD></DL>
+<P>
+Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for the
+	</FONT><TT><FONT COLOR="#ff0000">report</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this report. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this report, from
+	xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">Link to documentation on WWW or file </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD></DL>
+<P>
+Linking properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML NMTOKEN</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$role</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">A name for the generic role of this assertion.
+	The schema creator would have their own vocabulary. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XPath</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$subject</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">A path relative to the current context to some
+	interesting node considered the subject. </FONT>
+	</DD></DL>
+<P>
+To print the text contents, use <TT>&lt;xsl:apply-templates
+mode=&quot;text&quot; /&gt;</TT></P>
+<HR>
+<H2><TT>process-rule</TT></H2>
+<P>The <TT>process-rule</TT> reports that a <TT>rule</TT> element has
+fired: its <TT>context</TT> attribute matched some nodes. .</P>
+<DL>
+	<DT><TT><I>XSLT expression</I></TT><TT> $context</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	The expression that gives the context of the current 
+	</DD></DL>
+<P>
+Rich properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML SystemId</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$icon</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The URI of an icon </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XML ID</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$id</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The unique identifier with the schema for this
+	</FONT><TT><FONT COLOR="#ff0000">rule</FONT></TT><FONT COLOR="#ff0000">
+	element. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>SGML FPI</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$fpi</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The Formal Public Identifier for this rule. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>IETF language</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$lang</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">The human language used in this rule, from
+	xml:lang </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>URL</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$see</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">Link to documentation on WWW or file </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>&quot;preserve&quot; | &quot;default&quot;</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$space</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">The value for xml:space </FONT>
+	</DD></DL>
+<P>
+Linking properties:</P>
+<DL>
+	<DT><TT><FONT COLOR="#ff0000"><I>XML NMTOKEN</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$role</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD>
+	<FONT COLOR="#ff0000">A name for the generic role of this assertion.
+	The schema creator would have their own vocabulary. </FONT>
+	</DD><DT>
+	<TT><FONT COLOR="#ff0000"><I>XPath</I></FONT></TT><TT><FONT COLOR="#ff0000">
+	$subject</FONT></TT><FONT COLOR="#ff0000"> </FONT>
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	<FONT COLOR="#ff0000">A path relative to the current context to some
+	interesting node considered the subject. </FONT>
+	</DD><HR>
+</DL>
+<H2><TT>process-span</TT></H2>
+<P>The <TT>process-span</TT> handles span elements, which are generic
+elements for styling, like HTML's .</P>
+<DL>
+	<DT><TT><I>XML NMTOKEN</I></TT><TT> $class</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	An attribute that can be used for stylesheet style 
+	</DD><HR>
+</DL>
+<H2><TT>process-title</TT></H2>
+<P>The <TT>process-title</TT> handles title elements, which are
+generic elements for styling, like HTML's .</P>
+<DL>
+	<DT><TT><I>XML NMTOKEN</I></TT><TT> $class</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	An attribute that can be used for stylesheet style 
+	</DD></DL>
+<P>
+By default, titles are handled by invocing <TT>process-p</TT> with
+the parameter class with a value &quot;title&quot;.</P>
+<HR>
+<H2><TT>process-value-of</TT></H2>
+<P>The <TT>process-value-of</TT> template handles <TT>value-of</TT>
+elements, which are used in diagnostic messages to allow very
+specific hinting .</P>
+<DL>
+	<DT><TT><I>XPath</I></TT><TT> $select</TT> 
+	</DT><DD STYLE="margin-bottom: 0.5cm">
+	The path of some node that will be evaluated and printed.</DD><HR>
+</DL>
+<H1>Global Parameters</H1>
+<P>There are several global parameters that may be available for use.
+However, it is not a requirement to follow these, and implementations
+may not supply them with any value. So a test of
+string-length(<I>variable</I><SPAN STYLE="font-style: normal">) &lt;
+0 is appropriate in each case.</SPAN></P>
+<P><BR><BR>
+</P>
+<TABLE WIDTH=557 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=1 CELLSPACING=0>
+	<COL WIDTH=132>
+	<COL WIDTH=77>
+	<COL WIDTH=340>
+	<TR>
+		<TD WIDTH=132>
+			<P ALIGN=CENTER><FONT SIZE=2><B>Parameter</B></FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P ALIGN=CENTER><FONT SIZE=2><B>Value</B></FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P ALIGN=CENTER><FONT SIZE=2><B>Description</B></FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>allow-foreign</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>&quot;true&quot; | &quot;false&quot; (default) </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>Pass non-Schematron elements to the generated
+			stylesheet.  Pass the Schematron elements span, emph and dir: to
+			the output SVRL.  </FONT>
+			</P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>fileNameParameter</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>string</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>A parameter passed to the Validator and
+			potentially available as a variable in Schematron schemas as
+			$fileNameParameter</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>fileDirParameter</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>string</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>A parameter passed to the Validator and
+			potentially available as a variable in Schematron schemas as
+			$fileDirParameter</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>archiveNamePaameter</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>string</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>A parameter passed to the Validator and
+			potentially available as a variable in Schematron schemas as
+			$archiveNameParameter</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>archiveDirParameter</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>string</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>A parameter passed to the Validator and
+			potentially available as a variable in Schematron schemas as
+			$archivePathParameter</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>debug </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=77>
+			<P>&ldquo;<FONT SIZE=2>true&rdquo; | &ldquo;false&rdquo; (default)</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>Verbose error messages (Note this may be
+			superceded by &ldquo;verbose&rdquo; at some stage in the future.)</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>generate-paths</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>true|false </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>generate the SVRL @location attribute with XPaths</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>diagnose</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>yes | no </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>Add the diagnostics to the assertion results</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><A NAME="DDE_LINK"></A><FONT SIZE=2>terminate</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>yes | no | true | false | assert</FONT>
+			</P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>Terminate on the first failed assertion or
+			successful report</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>message-newline </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>&quot;true&quot; (default) | &quot;false&quot;  </FONT>
+			</P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>Generate an extra newline at the end of messages</FONT></P>
+		</TD>
+	</TR>
+	<TR>
+		<TD WIDTH=132>
+			<P><FONT SIZE=2>output-encoding</FONT></P>
+		</TD>
+		<TD WIDTH=77>
+			<P><FONT SIZE=2>string</FONT></P>
+		</TD>
+		<TD WIDTH=340>
+			<P><FONT SIZE=2>The encoding used for output, for example if the
+			output is XML</FONT></P>
+		</TD>
+	</TR>
+</TABLE>
+<DL>
+	<DD STYLE="margin-bottom: 0.5cm"> 
+	</DD></DL>
+</BODY>
+</HTML>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/CMDValidateTestSuite.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/CMDValidateTestSuite.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/CMDValidateTestSuite.java	(revision 1843)
@@ -0,0 +1,38 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package clarin.cmdi.schema.cmd;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ *
+ * @author menwin
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({clarin.cmdi.schema.cmd.TestCMDValidate.class})
+public class CMDValidateTestSuite {
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+    
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/TestCMDValidate.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/TestCMDValidate.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/java/clarin/cmdi/schema/cmd/TestCMDValidate.java	(revision 1843)
@@ -0,0 +1,140 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package clarin.cmdi.schema.cmd;
+
+import clarin.cmdi.schema.cmd.Validator.Message;
+import java.util.List;
+import javax.xml.transform.Source;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author menwin
+ */
+public class TestCMDValidate {
+
+    private Validator cmdValidator;
+
+    @Before
+    public void setUp() {
+	cmdValidator = new Validator(getClass().getResource("/schema/general-component-schema.xsd"));
+    }
+
+    @After
+    public void tearDown() {
+	cmdValidator = null;
+    }
+
+    protected boolean validate(String prof) throws Exception {
+	System.out.print("Test CMD validation [" + prof + "] ");
+	Source src = new javax.xml.transform.stream.StreamSource(new java.io.File(TestCMDValidate.class.getResource("/docs/" + prof).toURI()));
+	boolean valid = cmdValidator.validateProfile(src);
+	if (valid) {
+	    System.out.println("valid");
+	} else {
+	    System.out.println("invalid");
+	}
+	cmdValidator.printMessages(System.out);
+	return valid;
+    }
+
+    @Test
+    public void valid() throws Exception {
+	assertTrue(validate("CLARINWebService.xml"));
+	assertEquals(0, cmdValidator.getMessages().size());
+    }
+
+    @Test
+    public void invalid_1() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-1.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/AttributeList[1]/Attribute[1]", message.location);
+	assertEquals("not(Name=('ref','ComponentId'))", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_2() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-2.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/AttributeList[1]/Attribute[1]/ValueScheme[1]/enumeration[1]/item[2]", message.location);
+	assertEquals("empty(preceding-sibling::item[.=current()])", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_3() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-3.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/AttributeList[1]/Attribute[2]", message.location);
+	assertEquals("empty(preceding-sibling::Attribute[Name=current()/Name])", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_4() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-4.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/CMD_Component[2]", message.location);
+	assertEquals("empty(preceding-sibling::*[@name=current()/@name])", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_5() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-5.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/CMD_Element[3]", message.location);
+	assertEquals("empty(preceding-sibling::*[@name=current()/@name])", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_6() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-6.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertEquals("/CMD_ComponentSpec[1]/CMD_Component[1]/CMD_Component[1]/CMD_Component[1]", message.location);
+	assertEquals("empty(preceding-sibling::*[@name=current()/@name])", message.test);
+	assertNotNull(message.text);
+    }
+
+    @Test
+    public void invalid_7() throws Exception {
+	assertFalse(validate("CLARINWebService_faulty-7.xml"));
+
+	final List<Message> messages = cmdValidator.getMessages();
+	assertEquals(1, messages.size());
+	Message message = messages.get(0);
+	assertTrue(message.error);
+	assertNull(message.location);
+	assertNull(message.test);
+	assertNotNull(message.text);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService.xml	(revision 1843)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-1.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-1.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-1.xml	(revision 1843)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <!-- ERROR: @ref clashes with CMD @ref -->
+                    <Name>ref</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-2.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-2.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-2.xml	(revision 1843)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                            <!-- ERROR: double item in an enum -->
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-3.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-3.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-3.xml	(revision 1843)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+                <!-- ERROR: multiple attributes with the same name -->
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-4.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-4.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-4.xml	(revision 1843)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <!-- ERROR: double CMD component -->
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-5.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-5.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-5.xml	(revision 1843)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <!-- ERROR: double CMD element -->
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-6.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-6.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-6.xml	(revision 1843)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <!-- ERROR: double CMD element/component -->
+            <CMD_Element CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation" ValueScheme="string" />
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-7.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-7.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/docs/CLARINWebService_faulty-7.xml	(revision 1843)
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<CMD_ComponentSpec isProfile="true" xsi:schemaLocation="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Header>
+        <ID>clarin.eu:cr1:p_1311927752335</ID>
+        <Name>CLARINWebService</Name>
+        <Description>This is a core model which can be used as a basis for web service registry specific models. In principle this profile shouldn't be instantiated, instead new profiles can be created which extend the structure built by the components in this profile. Valid instantiations of these extensions allow validation of the core elements against the schema of this profile. More detailed information, including facilities to validate compliance with this core model, can be found at: http://www.isocat.org/clarin/ws/cmd-core/</Description>
+    </Header>
+    <CMD_Component CardinalityMax="1" CardinalityMin="1" name="CLARINWebService">
+        <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4159" ComponentId="clarin.eu:cr1:c_1299509410081" name="Service">
+            <AttributeList>
+                <Attribute>
+                    <Name>CoreVersion</Name>
+                    <ConceptLink>http://www.isocat.org/datcat/DC-2547</ConceptLink>
+                    <ValueScheme>
+                        <enumeration>
+                            <item AppInfo="" ConceptLink="">1.0</item>
+                        </enumeration>
+                    </ValueScheme>
+                </Attribute>
+            </AttributeList>
+            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="The name of the web service or set of web services." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4160" name="Name"/>
+            <CMD_Element Multilingual="true" Documentation="A description of the web service or set of web services." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation"/>
+            <!-- ERROR: all elements should precede the components -->
+            <CMD_Element CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4161" name="ServiceDescriptionLocation" ValueScheme="string" />
+            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Operations">
+                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4175" ComponentId="clarin.eu:cr1:c_1299509410080" name="Operation">
+                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Operation Name should be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4176" name="Name"/>
+                    <CMD_Element Multilingual="true" Documentation="The Operation Description should describe what this operation does to the input to produce the output." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4177" name="Input">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                    <CMD_Component CardinalityMax="1" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4178" name="Output">
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4179" ComponentId="clarin.eu:cr1:c_1302702320471" name="ParameterGroup">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This ParameterGroup Name should in general be resolvable in the Service ServiceDescription, i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this ParameterGroup for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this ParameterGroup, which indicates that its one input resource containing several input Parameters." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this ParameterGroup." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="1" name="Parameters">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                                    <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                                    <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                                    <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                    <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                                    <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                            <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                        </CMD_Component>
+                                    </CMD_Component>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                        <CMD_Component CardinalityMax="unbounded" CardinalityMin="0" ConceptLink="http://www.isocat.org/datcat/DC-4184" ComponentId="clarin.eu:cr1:c_1299509410079" name="Parameter">
+                            <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="This Parameter Name, unless the Parameter is part of a ParameterGroup, should be resolvable in the Service ServiceDescription, , i.e., the WSDL or WADL document describing how to technically invoke the service." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4180" name="Name"/>
+                            <CMD_Element Multilingual="true" Documentation="Describes the role of this Parameter for this web service operation." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                            <CMD_Element Multilingual="false" Documentation="The MIME type of this Parameter, which indicates that its an input resource on its own." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2571" name="MIMEType"/>
+                            <CMD_Element Multilingual="false" Documentation="The data type of this Parameter. In general this should be an XSD data type, e.g., xsd:string or xsd:anyURI." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4181" name="DataType"/>
+                            <CMD_Element Documentation="Set this flag to true if the parameter configures the operation of the web services, which is something else then the input the operation works upon. For example, the input of an operation can be a series of sensor values while a configuration parameter might be a treshhold or a weight used in the calculation done on this sensor values." CardinalityMax="1" CardinalityMin="0" ValueScheme="boolean" ConceptLink="http://www.isocat.org/datcat/DC-4185" name="isConfigurationParameter"/>
+                            <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                            <CMD_Element Multilingual="false" Documentation="A type describing the semantics of this parameter in its context. For example, an input parameter might be an WS specific project name, given to a project created by an earlier WS call. In that case the name of the parameter might be 'project', its data type might be 'xsd:string', its data category /projectName/ and its semantic type 'myWSApp.project'." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-4183" name="SemanticType"/>
+                            <CMD_Component CardinalityMax="1" CardinalityMin="0" name="Values">
+                                <CMD_Component CardinalityMax="unbounded" CardinalityMin="1" ConceptLink="http://www.isocat.org/datcat/DC-4186" name="ParameterValue">
+                                    <CMD_Element Multilingual="false" DisplayPriority="1" Documentation="A possible literal value of a parameter." CardinalityMax="1" CardinalityMin="1" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-1978" name="Value"/>
+                                    <CMD_Element Multilingual="false" Documentation="A description of the meaning of a possible literal value of a parameter." CardinalityMax="1" CardinalityMin="0" ValueScheme="string" ConceptLink="http://www.isocat.org/datcat/DC-2520" name="Description"/>
+                                    <CMD_Element Documentation="The PID refering to the (ISOcat) data category specifying this Parameter Value." CardinalityMax="1" CardinalityMin="0" ValueScheme="anyURI" ConceptLink="http://www.isocat.org/datcat/DC-4182" name="DataCategory"/>
+                                </CMD_Component>
+                            </CMD_Component>
+                        </CMD_Component>
+                    </CMD_Component>
+                </CMD_Component>
+            </CMD_Component>
+        </CMD_Component>
+    </CMD_Component>
+</CMD_ComponentSpec>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/schema/general-component-schema.xsd
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/schema/general-component-schema.xsd	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/src/test/resources/schema/general-component-schema.xsd	(revision 1843)
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+    $Revision: 1585 $ 
+    $Date: 2010-06-24 11:36:11 +0200 (Thu, 24 Jun 2010) $ 
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sch="http://purl.oclc.org/dsdl/schematron">
+    
+    <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+        schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
+
+    <!-- root element -->
+    <xs:element name="CMD_ComponentSpec">
+        <xs:annotation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element name="Header">
+                    <xs:complexType>
+                        <xs:sequence>
+                            <xs:element name="ID" type="xs:anyURI" minOccurs="0"/>
+                            <xs:element name="Name" type="xs:string" minOccurs="0"/>
+                            <xs:element name="Description" type="xs:string" minOccurs="0"/>
+                        </xs:sequence>
+                    </xs:complexType>
+                </xs:element>
+                <xs:element name="CMD_Component" type="CMD_Component_type">
+                    <xs:annotation>
+                        <xs:documentation>At the root level there should always be a
+                        Component.</xs:documentation>
+                    </xs:annotation>
+                </xs:element>
+            </xs:sequence>
+            <xs:attribute name="isProfile" type="xs:boolean" use="required"/>
+        </xs:complexType>
+    </xs:element>
+
+    <!-- recursive construction: A component can contain elements and/or other components  -->
+    <xs:group name="group">
+        <xs:annotation>
+            <xs:appinfo>
+                <sch:pattern id="component" name="CMD component group">
+                    <sch:rule context="CMD_Component|CMD_Element">
+                        <sch:assert test="empty(preceding-sibling::*[@name=current()/@name])">Sibling components or elements should all have a different name. Found multiple components or elements named '<sch:value-of select="@name"/>'!</sch:assert>
+                    </sch:rule>
+                </sch:pattern>
+            </xs:appinfo>            
+        </xs:annotation>
+        <xs:sequence>
+            <!-- from small (attribute) to big (component) -->
+            <xs:element name="AttributeList" type="AttributeList_type" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="CMD_Element" type="CMD_Element_type" minOccurs="0"
+                maxOccurs="unbounded"> </xs:element>
+            <xs:element name="CMD_Component" type="CMD_Component_type" minOccurs="0"
+                maxOccurs="unbounded"/>
+        </xs:sequence>
+    </xs:group>
+
+    <!-- type definitions -->
+    <xs:complexType name="CMD_Element_type">
+        <xs:sequence>
+            <xs:element name="AttributeList" type="AttributeList_type" minOccurs="0" maxOccurs="1">
+                <xs:annotation>
+                    <xs:documentation>The AttributeList child of an element contains a set of XML
+                        attributes for that element.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element minOccurs="0" maxOccurs="1" name="ValueScheme" type="ValueScheme_type">
+                <xs:annotation>
+                    <xs:documentation>When an element is linked to a regular expression or a
+                        controlled vocabulary, the ValueScheme sub-element contains more information
+                        about this.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+        </xs:sequence>
+        <xs:attributeGroup ref="clarin_element_attributes"/>
+    </xs:complexType>
+
+
+    <xs:complexType name="ValueScheme_type">
+        <xs:choice>
+            <xs:element name="pattern" type="xs:string" maxOccurs="1">
+                <xs:annotation>
+                    <xs:documentation>Specification of a regular expression the element should
+                        comply with.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="enumeration" type="enumeration_type">
+                <xs:annotation>
+                    <xs:documentation>A list of the allowed values of a controlled
+                    vocabulary.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+        </xs:choice>
+    </xs:complexType>
+
+
+    <xs:complexType name="AttributeList_type">
+        <xs:sequence>
+            <xs:element name="Attribute" minOccurs="1" maxOccurs="unbounded">
+                <xs:annotation>
+                    <xs:appinfo>
+                        <sch:pattern id="attribute" name="CMD attribute">
+                            <sch:rule context="Attribute">
+                                <sch:assert test="empty(preceding-sibling::Attribute[Name=current()/Name])">All attributes in an attribute list should have a different name. Found multiple attributes named '<sch:value-of select="Name"/>'!</sch:assert>
+                                <sch:assert test="not(Name=('ref','ComponentId'))">Attribute name shouldn't be 'ref' or 'ComponentId', as these are used internally by CMD!</sch:assert>
+                            </sch:rule>
+                        </sch:pattern>
+                    </xs:appinfo>            
+                </xs:annotation>
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="Name" type="xs:string">
+                            <xs:annotation>
+                                <xs:documentation>The name of the attribute.</xs:documentation>
+                            </xs:annotation>
+                        </xs:element>
+                        <xs:element name="ConceptLink" type="xs:anyURI" minOccurs="0">
+                            <xs:annotation>
+                                <xs:documentation>A link to the ISOcat data category registry (or any other concept registry).</xs:documentation>
+                            </xs:annotation>
+                        </xs:element>
+                        <xs:choice>
+                            <xs:element name="Type" type="allowed_attributetypes_type">
+                                <xs:annotation>
+                                    <xs:documentation>For the use of simple XML types as the type of
+                                        the attribute.</xs:documentation>
+                                </xs:annotation>
+                            </xs:element>
+                            <xs:element name="ValueScheme" type="ValueScheme_type">
+                                <xs:annotation>
+                                    <xs:documentation>For the use of a regular expression or a
+                                        controlled vocabulary as the type of the
+                                    attribute.</xs:documentation>
+                                </xs:annotation>
+                            </xs:element>
+                        </xs:choice>
+                    </xs:sequence>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="CMD_Component_type">
+        <xs:group ref="group" minOccurs="0"/>
+        <xs:attributeGroup ref="clarin_component_attributes"/>
+    </xs:complexType>
+
+
+    <!-- list of all attributes that can be bound to a cl_el -->
+    <xs:attributeGroup name="clarin_element_attributes">
+        <xs:attribute name="name" type="xs:Name" use="required">
+            <xs:annotation>
+                <xs:documentation>The name of the element.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ConceptLink" type="xs:anyURI">
+            <xs:annotation>
+                <xs:documentation>A link to the ISOcat data category registry (or any other concept
+                    registry).</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ValueScheme" type="allowed_attributetypes_type">
+            <xs:annotation>
+                <xs:documentation>Used to specify that an element has a simple XML type (string,
+                    integer, etc)</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="CardinalityMin" type="cardinality_type">
+            <xs:annotation>
+                <xs:documentation>Minimal number of occurrences.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="CardinalityMax" type="cardinality_type">
+            <xs:annotation>
+                <xs:documentation>Maximal number of occurrences.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="Documentation" type="xs:string">
+            <xs:annotation>
+                <xs:documentation>Some information an application (eg Arbil) can display to give
+                    guidance to the user when entering metadata.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="DisplayPriority" type="xs:integer">
+            <xs:annotation>
+                <xs:documentation>The element with the highest priority will be displayed as the
+                    label for a metadata file (eg in Arbil)</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="Multilingual" type="xs:boolean">
+            <xs:annotation>
+                <xs:documentation>Indicates that this element can have values in multiple languages
+                    (and thus is repeatable). This will result in the possibility of using the
+                    xml:lang attribute in the metadata instances that are
+                created.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+    </xs:attributeGroup>
+
+    <!-- list of all attributes that can be bound to a cl_comp -->
+    <xs:attributeGroup name="clarin_component_attributes">
+        <xs:attribute name="name" type="xs:Name"/>
+        <xs:attribute name="ComponentId" type="xs:anyURI">
+            <xs:annotation>
+                <xs:documentation>Indicates that a component (using its unique ComponentId issued by
+                    the ComponentRegistry) should be included.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="ConceptLink" type="xs:anyURI">
+            <xs:annotation>
+                <xs:documentation>A link to the ISOcat data category registry (or any other concept
+                    registry). Currently not used.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="filename" type="xs:anyURI">
+            <xs:annotation>
+                <xs:documentation>Outdated way of including an external component. Here for backward
+                    compatibility with the XML-cmdi-toolkit.</xs:documentation>
+            </xs:annotation>
+        </xs:attribute>
+
+        <!-- (components cannot have a ValueScheme attribute) -->
+
+        <xs:attribute name="CardinalityMin" type="cardinality_type"/>
+        <xs:attribute name="CardinalityMax" type="cardinality_type"/>
+        <xs:attribute ref="xml:base"/>
+    </xs:attributeGroup>
+
+
+    <xs:simpleType name="cardinality_type">
+        <xs:annotation>
+            <xs:documentation>cardinality for elements and components</xs:documentation>
+        </xs:annotation>
+        <xs:union>
+            <xs:simpleType>
+                <xs:list itemType="xs:nonNegativeInteger"/>
+            </xs:simpleType>
+            <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="unbounded"/>
+                </xs:restriction>
+            </xs:simpleType>
+        </xs:union>
+    </xs:simpleType>
+
+    <xs:simpleType name="allowed_attributetypes_type">
+        <xs:annotation>
+            <xs:documentation>Subset of XSD types that are allowed as CMD type</xs:documentation>
+        </xs:annotation>
+
+        <xs:restriction base="xs:token">
+            <xs:enumeration value="boolean"/>
+            <xs:enumeration value="decimal"/>
+            <xs:enumeration value="float"/>
+            <xs:enumeration value="string"/>
+            <xs:enumeration value="anyURI"/>
+            <xs:enumeration value="date"/>
+            <xs:enumeration value="gDay"/>
+            <xs:enumeration value="gMonth"/>
+            <xs:enumeration value="gYear"/>
+            <xs:enumeration value="time"/>
+        </xs:restriction>
+    </xs:simpleType>
+
+    <xs:complexType name="enumeration_type">
+        <xs:annotation>
+            <xs:documentation>controlled vocabularies</xs:documentation>
+        </xs:annotation>
+        <xs:choice minOccurs="0" maxOccurs="unbounded">
+            <xs:element name="item" type="item_type">
+                <xs:annotation>
+                    <xs:documentation>An item from a controlled vocabulary.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+            <xs:element name="appinfo" type="xs:string">
+                <xs:annotation>
+                    <xs:documentation>End-user guidance about the value of the controlled vocabulary
+                        as a whole. Currently not used.</xs:documentation>
+                </xs:annotation>
+            </xs:element>
+        </xs:choice>
+    </xs:complexType>
+
+    <xs:complexType name="item_type">
+        <xs:annotation>
+            <xs:appinfo>
+                <sch:pattern id="item" name="CMD enumeration item">
+                    <sch:rule context="item">
+                        <sch:assert test="empty(preceding-sibling::item[.=current()])">All items in an enumeration should be different. Found multiple items with value '<sch:value-of select="."/>'!</sch:assert>
+                    </sch:rule>
+                </sch:pattern>
+            </xs:appinfo>            
+        </xs:annotation>
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute type="xs:anyURI" name="ConceptLink">
+                    <xs:annotation>
+                        <xs:documentation>A link to the ISOcat data category registry (or any other
+                            concept registry) related to this controllec vocabulary
+                        item.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+                <xs:attribute type="xs:string" name="AppInfo">
+                    <xs:annotation>
+                        <xs:documentation>End-user guidance about the value of this controlled
+                            vocabulary item.</xs:documentation>
+                    </xs:annotation>
+                </xs:attribute>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+
+</xs:schema>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/validate.sh
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/validate.sh	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/CMDValidate/validate.sh	(revision 1843)
@@ -0,0 +1,9 @@
+#!/bin/sh
+if [[ $# == 0 ]]
+then
+	echo "Usage: $0 [-s schema url] files..."
+	exit 1;
+fi
+
+eval "mvn exec:java -Dexec.args=\"$@\""
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/flexFormatting.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/flexFormatting.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/flexFormatting.properties	(revision 1843)
@@ -0,0 +1,109 @@
+#FlexPrettyPrintSettings
+#Wed Apr 27 14:06:57 CEST 2011
+ASRearr_UseModifierOrder_Function=true
+Actionscript.useBraceStyle=true
+ASRearr_ModifierOrder_Property=<Namespace>,override,native,public,private,protected,internal,static,dynamic,final
+ASRearr_ModifierOrder_Class=<Namespace>,override,native,public,private,protected,internal,static,dynamic,final
+ASRearr_ElementSortStaticProperties=true
+ASRearr_ElementStaticFunctionVisibilityOrder=public\:true,protected\:true,internal\:true,private\:true,
+MXML.attrWrapMode=52
+ASRearr_UseElementStaticPropertyVisibilityOrder=true
+ASRearr_ElementSortImports=true
+ASRearr_ElementOrder=Import,Include,Namespace Definition,Default Namespace,Namespace Use,Static Property,Static Function,Constructor,Property,Function,
+Actionscript.spacesAfterComma=1
+Actionscript.advancedSpacesAroundEqualsInOptionalParameters=0
+ASRearr_ElementFunctionVisibilityOrder=public\:true,protected\:true,internal\:true,private\:true,
+MXML.onlyFormatASIfCDATABlock=false
+Actionscript.advancedWrappingElements=165
+Actionscript.spacesBeforeComma=0
+Actionscript.advancedSpacesInsideLiteralBraces=1
+Actionscript.wrapArrayDeclMode=4
+Flex.useTabs=true
+ASRearr_ElementSortMetatags=false
+MXML.attrsToKeepOnSameLine=4
+MXML.sortAttrMode=0
+Actionscript.wrapMethodCallMode=1
+Actionscript.spacesBeforeControlOpenParen=1
+Actionscript.spacesAfterColons=0
+Actionscript.useGlobalCRBeforeBrace=true
+Actionscript.blankLinesBeforeFunctions=1
+MXML.spacesAroundEquals=0
+ASRearr_UseModifierOrder_Class=true
+Actionscript.breakLinesBeforeComma=false
+Actionscript.spacesAroundAssignment=1
+ASRearr_ElementSortIncludes=true
+MXML.wrapIndentStyle=1001
+Actionscript.leaveExtraWhitespaceAroundVarDecls=false
+MXML.maxLineLength=200
+Actionscript.putEmptyStatementsOnNewLine=true
+Actionscript.wrapExpressionMode=1
+ASRearr_UseElementStaticFunctionVisibilityOrder=true
+Actionscript.spacesAroundColons=0
+Actionscript.advancedUseSpacesAroundEqualsInOptionalParameters=false
+Actionscript.useAdvancedWrapping=false
+Actionscript.putOpenBraceOnNewLine=true
+Actionscript.blankLinesBeforeControlStatements=0
+MXML.blankLinesBeforeTags=0
+Actionscript.advancedCRBeforeBraceSettings=2047
+Actionscript.dontIndentPackageItems=false
+Actionscript.keepBlankLines=true
+MXML.keepBlankLines=true
+ASRearr_UseMetatagOrder=false
+ActionScript.spacesBeforeFormalParameters=0
+MXML.attrGroups=name\=properties|sort\=11|wrap\=54|attrs\=allowDisjointSelection,allowMultipleSelection,allowThumbOverlap,allowTrackClick,autoLayout,autoRepeat,automationName,cachePolicy,class,clipContent,condenseWhite,conversion,creationIndex,creationPolicy,currentState,data,dataDescriptor,dataProvider,dataTipFormatFunction,dayNames,defaultButton,direction,disabledDays,disabledRanges,displayedMonth,displayedYear,doubleClickEnabled,emphasized,enabled,explicitHeight,explicitMaxHeight,explicitMaxWidth,explicitMinHeight,explicitMinWidth,explicitWidth,firstDayOfWeek,focusEnabled,fontContext,height,horizontalLineScrollSize,horizontalPageScrollSize,horizontalScrollBar,horizontalScrollPolicy,horizontalScrollPosition,htmlText,icon,iconField,id,imeMode,includeInLayout,indeterminate,label,labelField,labelFunction,labelPlacement,labels,layout,lineScrollSize,listData,liveDragging,maxChars,maxHeight,maxScrollPosition,maxWidth,maxYear,maximum,measuredHeight,measuredMinHeight,measuredMinWidth,measuredWidth,menuBarItemRenderer,menuBarItems,menus,minHeight,minScrollPosition,minWidth,minYear,minimum,mode,monthNames,monthSymbol,mouseFocusEnabled,pageScrollSize,pageSize,percentHeight,percentWidth,scaleX,scaleY,scrollPosition,selectable,selectableRange,selected,selectedDate,selectedField,selectedIndex,selectedRanges,showDataTip,showRoot,showToday,sliderDataTipClass,sliderThumbClass,snapInterval,source,states,stepSize,stickyHighlighting,styleName,text,text,thumbCount,tickInterval,tickValues,toggle,toolTip,transitions,truncateToFit,validationSubField,value,value,verticalLineScrollSize,verticalPageScrollSize,verticalScrollBar,verticalScrollPolicy,verticalScrollPosition,width,x,y,yearNavigationEnabled,yearSymbol,|data\=-1|\nname\=xml_namespaces|sort\=11|wrap\=54|attrs\=xmlns\:.*,|data\=-1|\nname\=events|sort\=11|wrap\=54|attrs\=add,added,activate,addedToStage,buttonDown,change,childAdd,childIndexChange,childRemove,clickHandler,clear,click,complete,contextMenu,copy,creationComplete,currentStateChange,currentStateChanging,cut,dataChange,deactivate,doubleClick,dragComplete,dragDrop,dragEnter,dragExit,dragOver,dragStart,effectEnd,effectStart,enterFrame,enterState,exitFrame,exitState,focusIn,focusOut,frameConstructed,hide,httpStatus,init,initialize,invalid,ioError,itemClick,itemRollOut,itemRollOver,keyDown,keyFocusChange,keyUp,menuHide,menuShow,middleClick,middleMouseDown,middleMouseUp,mouseDown,mouseUp,mouseOver,mouseMove,mouseOut,mouseFocusChange,mouseWheel,mouseDownOutside,mouseWheelOutside,move,nativeDragComplete,nativeDragDrop,nativeDragEnter,nativeDragExit,nativeDragOver,nativeDragStart,nativeDragUpdate,open,paste,preinitialize,progress,record,remove,removed,removedFromStage,render,resize,rightClick,rightMouseDown,rightMouseUp,rollOut,rollOver,scroll,securityError,selectAll,show,tabChildrenChange,tabEnabledChange,tabIndexChange,thumbDrag,thumbPress,thumbRelease,toolTipCreate,toolTipEnd,toolTipHide,toolTipShow,toolTipShown,toolTipStart,updateComplete,unload,valid,valueCommit,|data\=-1|\nname\=styles|sort\=11|wrap\=54|attrs\=backgroundAlpha,backgroundAttachment,backgroundColor,backgroundDisabledColor,backgroundImage,backgroundSize,backgroundSkin,barColor,barSkin,borderColor,borderSides,borderSkin,borderStyle,borderThickness,bottom,color,cornerRadius,dataTipOffset,dataTipPrecision,dataTipStyleName,disabledColor,disabledIcon,disabledIconColor,disabledSkin,disbledOverlayAlpha,downArrowDisabledSkin,downArrowDownSkin,downArrowOverSkin,downArrowUpSkin,downIcon,downSkin,dropShadowColor,dropShadowEnabled,errorColor,fillAlphas,fillColors,focusAlpha,focusBlendMode,focusRoundedCorners,focusSkin,focusThickness,fontAntiAliasType,fontFamily,fontGridFitType,fontSharpness,fontSize,fontStyle,fontThickness,fontWeight,fontfamily,headerColors,headerStyleName,highlightAlphas,horizontalAlign,horizontalCenter,horizontalGap,horizontalScrollBarStyleName,icon,iconColor,indeterminateMoveInterval,indeterminateSkin,itemDownSkin,itemOverSkin,itemUpSkin,kerning,labelOffset,labelStyleName,labelWidth,leading,left,letterSpacing,maskSkin,menuStyleName,nextMonthDisabledSkin,nextMonthDownSkin,nextMonthOverSkin,nextMonthSkin,nextMonthUpSkin,nextYearDisabledSkin,nextYearDownSkin,nextYearOverSkin,nextYearSkin,nextYearUpSkin,overIcon,overSkin,paddingBottom,paddingLeft,paddingRight,paddingTop,prevMonthDisabledSkin,prevMonthDownSkin,prevMonthOverSkin,prevMonthSkin,prevMonthUpSkin,prevYearDisabledSkin,prevYearDownSkin,prevYearOverSkin,prevYearSkin,prevYearUpSkin,repeatDelay,repeatInterval,right,rollOverColor,rollOverIndicatorSkin,selectedDisabledIcon,selectedDisabledSkin,selectedDownIcon,selectedDownSkin,selectedOverIcon,selectedOverSkin,selectedUpIcon,selectedUpSkin,selectionColor,selectionIndicatorSkin,shadowColor,shadowDirection,shadowDistance,showTrackHighlight,skin,slideDuration,slideEasingFunction,strokeColor,strokeWidth,textAlign,textDecoration,textIndent,textRollOverColor,textSelectedColor,themeColor,thumbDisabledSkin,thumbDownSkin,thumbIcon,thumbOffset,thumbOverSkin,thumbUpSkin,tickColor,tickLength,tickOffset,tickThickness,todayColor,todayIndicatorSkin,todayStyleName,top,tracHighlightSkin,trackColors,trackHeight,trackMargin,trackSkin,upArrowDisabledSkin,upArrowDownSkin,upArrowOverSkin,upArrowUpSkin,upIcon,upSkin,verticalAlign,verticalCenter,verticalGap,verticalScrollBarStyleName,weekDayStyleName,|data\=-1|\nname\=effects|sort\=11|wrap\=54|attrs\=addedEffect,completeEffect,creationCompleteEffect,focusInEffect,focusOutEffect,hideEffect,mouseDownEffect,mouseUpEffect,moveEffect,removedEffect,resizeEffect,rollOutEffect,rollOverEffect,showEffect,|data\=-1|\n
+ASRearr_UseModifierOrder_Property=true
+ASRearr_MoveImportsOutsideClass=true
+Actionscript.maxLineLength=200
+Actionscript.spacesInsideParens=0
+ASRearr_ElementSortProperties=true
+Actionscript.advancedSpacesInsideArrayRefBrackets=0
+Actionscript.newLineAfterBindable=true
+Actionscript.blankLinesToKeep=0
+Actionscript.keepElseIfOnSameLine=true
+Actionscript.blankLinesBeforeProperties=0
+Actionscript.advancedWrappingEnforceMax=false
+Actionscript.spacesBeforeColons=0
+Actionscript.advancedWrappingPreservePhrases=true
+Actionscript.alwaysGenerateIndent=false
+ASRearr_UseElementPropertyVisibilityOrder=true
+Actionscript.spacesAfterLabel=1
+Actionscript.wrapMethodDeclMode=1
+Actionscript.useGlobalSpacesAroundColons=true
+ASRearr_ModifierOrder_Function=<Namespace>,override,native,public,private,protected,internal,static,dynamic,final
+ASRearr_ElementStaticPropertyVisibilityOrder=public\:true,protected\:true,internal\:true,private\:true,
+MXML.sortExtraAttrs=false
+Actionscript.tabCountForHangingIndent=1
+ASRearr_ElementSortFunctions=true
+ASRearr_ElementPropertyVisibilityOrder=public\:true,protected\:true,internal\:true,private\:true,
+Actionscript.wrapEmbeddedXMLMode=2
+ASRearr_UseElementOrder=true
+Actionscript.doRearrangeWhileFormatting=false
+ASRearr_UseGlobalModifierOrder=true
+Actionscript.useGlobalSpacesInsideParens=true
+Actionscript.putCatchOnNewLine=true
+ASRearr_ElementSortNamespaces=true
+Actionscript.putElseOnNewLine=true
+MXML.spacesBeforeEmptyTagEnd=0
+ASRearr_ElementSortStaticFunctions=true
+Actionscript.wrapIndentStyle=1000
+ASRearr_MetatagOrder=ArrayElementType,Bindable,DefaultProperty,Deprecated,Effect,Embed,Event,Exclude,ExcludeClass,IconFile,Inspectable,InstanceType,NonCommittingChangeEvent,RemoteClass,Style,SWF,Transient,
+Actionscript.braceStyle=4
+ASRearr_UseElementFunctionVisibilityOrder=true
+Actionscript.spacesAroundBinarySymbolicOperator=1
+Actionscript.keepSLCommentsOnColumn1=true
+MXML.tagsCanFormat=mx\:List,fx\:List,
+MXML.sortAttrData=
+Actionscript.blankLinesBeforeClasses=1
+MXML.tagsToHaveBlankLinesAddedBeforeThem=
+MXML.useAttrsToKeepOnSameLine=false
+ASRearr_UseImportOrder=true
+MXML.blankLinesBetweenSiblingTags=0
+Actionscript.collapseSpacesForAdjacentParens=true
+Actionscript.advancedSpacesInsideArrayDeclBrackets=1
+Actionscript.advancedSpacesInsideParens=0
+Actionscript.advancedWrappingGraceColumns=5
+MXML.tagsCannotFormat=mx\:String,fx\:String,
+MXML.attrsPerLine=1
+ASRearr_ImportOrder=adobe,com,flash,mx,
+MXML.addNewlineAfterLastAttr=false
+MXML.tagsWithASContent=.*\:add,.*\:added,.*\:activate,.*\:addedToStage,.*\:buttonDown,.*\:change,.*\:childAdd,.*\:childIndexChange,.*\:childRemove,.*\:clickHandler,.*\:clear,.*\:click,.*\:complete,.*\:contextMenu,.*\:copy,.*\:creationComplete,.*\:currentStateChange,.*\:currentStateChanging,.*\:cut,.*\:dataChange,.*\:deactivate,.*\:doubleClick,.*\:dragComplete,.*\:dragDrop,.*\:dragEnter,.*\:dragExit,.*\:dragOver,.*\:dragStart,.*\:effectEnd,.*\:effectStart,.*\:enterFrame,.*\:enterState,.*\:exitFrame,.*\:exitState,.*\:focusIn,.*\:focusOut,.*\:frameConstructed,.*\:hide,.*\:httpStatus,.*\:init,.*\:initialize,.*\:invalid,.*\:ioError,.*\:itemClick,.*\:itemRollOut,.*\:itemRollOver,.*\:keyDown,.*\:keyFocusChange,.*\:keyUp,.*\:menuHide,.*\:menuShow,.*\:middleClick,.*\:middleMouseDown,.*\:middleMouseUp,.*\:mouseDown,.*\:mouseUp,.*\:mouseOver,.*\:mouseMove,.*\:mouseOut,.*\:mouseFocusChange,.*\:mouseWheel,.*\:mouseDownOutside,.*\:mouseWheelOutside,.*\:move,.*\:nativeDragComplete,.*\:nativeDragDrop,.*\:nativeDragEnter,.*\:nativeDragExit,.*\:nativeDragOver,.*\:nativeDragStart,.*\:nativeDragUpdate,.*\:open,.*\:paste,.*\:preinitialize,.*\:progress,.*\:record,.*\:remove,.*\:removed,.*\:removedFromStage,.*\:render,.*\:resize,.*\:rightClick,.*\:rightMouseDown,.*\:rightMouseUp,.*\:rollOut,.*\:rollOver,.*\:scroll,.*\:securityError,.*\:selectAll,.*\:show,.*\:tabChildrenChange,.*\:tabEnabledChange,.*\:tabIndexChange,.*\:thumbDrag,.*\:thumbPress,.*\:thumbRelease,.*\:toolTipCreate,.*\:toolTipEnd,.*\:toolTipHide,.*\:toolTipShow,.*\:toolTipShown,.*\:toolTipStart,.*\:updateComplete,.*\:unload,.*\:valid,.*\:valueCommit,.*\:Script,
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/libs/maveninstalllib.txt
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/libs/maveninstalllib.txt	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/libs/maveninstalllib.txt	(revision 1843)
@@ -0,0 +1,1 @@
+mvn install:install-file -DgroupId=com.adobe -DartifactId=as3corelib -Dversion=0.92.1 -Dpackaging=swc -Dfile=as3corelib-0.92.1.swc -DgeneratePom=true
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/pom.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/pom.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/pom.xml	(revision 1843)
@@ -0,0 +1,131 @@
+<?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">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>clarin.cmdi</groupId>
+        <artifactId>componentRegistry.parent</artifactId>
+        <version>1.0</version>
+    </parent>
+    <groupId>clarin.cmdi</groupId>
+    <artifactId>ComponentBrowserGui</artifactId>
+    <version>${ComponentBrowserGui.version}</version>
+    <packaging>swf</packaging>
+    <name>ComponentBrowserGui</name>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <flexDebug>true</flexDebug>
+    </properties>
+
+    <profiles>
+	<profile>
+	    <id>clarin</id>
+	    <properties>
+	    	<flexDebug>false</flexDebug>
+	    </properties>
+	</profile>
+    </profiles>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.adobe.flex.framework</groupId>
+            <artifactId>flex-framework</artifactId>
+            <version>3.6.0.16321</version>
+            <type>pom</type>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.adobe.flex.framework</groupId>
+                    <artifactId>playerglobal</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.adobe.flex.framework</groupId>
+            <artifactId>playerglobal</artifactId>
+            <version>3.6.0.16321</version>
+            <classifier>10</classifier>
+            <type>swc</type>
+        </dependency>
+        <dependency>
+            <groupId>com.adobe</groupId>
+            <artifactId>as3corelib</artifactId>
+            <version>0.92.1</version>
+            <type>swc</type>
+        </dependency>
+        <dependency>
+            <groupId>com.adobe.flexunit</groupId>
+            <artifactId>flexunit</artifactId>
+            <version>0.90</version>
+            <type>swc</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.flexspy</groupId>
+            <artifactId>flexspy</artifactId>
+            <version>1.3</version>
+            <type>swc</type>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <sourceDirectory>src/main/flex</sourceDirectory>
+        <plugins>
+            <plugin>
+                <groupId>org.sonatype.flexmojos</groupId>
+                <artifactId>flexmojos-maven-plugin</artifactId>
+                <version>3.9</version>
+                <extensions>true</extensions>
+                <configuration>
+                    <debug>${flexDebug}</debug>
+                    <generateHtmlWrapper>true</generateHtmlWrapper>
+                    <targetPlayer>10.0.0</targetPlayer>
+                    <definesDeclaration>
+					  <property>
+						<name>APPINFO::version</name>
+						<value>"${ComponentBrowserGui.version}"</value>
+					  </property>
+					</definesDeclaration>                    
+                </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>com.adobe.flex</groupId>
+                        <artifactId>compiler</artifactId>
+                        <version>3.6.0.16321</version>
+                        <type>pom</type>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <repositories>
+        <repository>
+            <id>forge</id>
+            <url>http://repository.sonatype.org/content/groups/flexgroup</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>forge</id>
+            <url>http://repository.sonatype.org/content/groups/flexgroup</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </pluginRepository>
+    </pluginRepositories>
+
+
+</project>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/TestRunner.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/TestRunner.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/TestRunner.mxml	(revision 1843)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
+				xmlns="*"
+				xmlns:flexunit="flexunit.flexui.*"
+				creationComplete="onCreationComplete()">
+
+	<mx:Script>
+		<![CDATA[
+		    import clarin.cmdi.componentregistry.editor.model.CMDSpecTest;
+			import clarin.cmdi.componentregistry.editor.model.CMDAttributeTest;
+			import clarin.cmdi.componentregistry.editor.model.CMDComponentElementTest;
+			import clarin.cmdi.componentregistry.editor.model.CMDComponentTest;
+			import flexunit.framework.TestSuite;
+
+			// Create the test suite and run the tests
+			private function onCreationComplete():void {
+				testRunner.test = createSuite();
+				testRunner.startTest();
+			}
+
+			// Creates the test suite to run
+			private function createSuite():TestSuite {
+				var testSuite:TestSuite = new TestSuite();
+
+				testSuite.addTestSuite(CMDSpecTest);
+				testSuite.addTestSuite(CMDComponentTest);
+				testSuite.addTestSuite(CMDComponentElementTest);
+				testSuite.addTestSuite(CMDAttributeTest);
+
+				return testSuite;
+			}
+		]]>
+	</mx:Script>
+
+	<!-- FlexUnit GUI Component -->
+	<flexunit:TestRunnerBase id="testRunner"
+							 width="100%"
+							 height="100%"/>
+</mx:Application>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/Browse.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/Browse.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/Browse.mxml	(revision 1843)
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
+		   xmlns:browser="clarin.cmdi.componentregistry.browser.*"
+		   initialize="init()"
+		   creationComplete="creationComplete()"
+		   width="100%"
+		   height="100%"
+		   label="Browse..."
+		   implements="clarin.cmdi.componentregistry.common.components.RegistryView">
+	<mx:Metadata>
+		[Event(name="startItemLoaded",type="flash.events.Event")]
+	</mx:Metadata>
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.services.BrowserService;
+			import clarin.cmdi.componentregistry.services.Config;
+			import clarin.cmdi.componentregistry.services.ComponentInfoService;
+			import clarin.cmdi.componentregistry.services.ProfileInfoService;
+			import clarin.cmdi.componentregistry.services.ProfileListService;
+			import mx.events.CollectionEvent;
+			import mx.collections.ArrayCollection;
+			import clarin.cmdi.componentregistry.common.components.RegistryViewStack;
+			import clarin.cmdi.componentregistry.common.components.BrowseContextMenu;
+			import clarin.cmdi.componentregistry.services.DeleteService;
+			import clarin.cmdi.componentregistry.services.ComponentListService;
+			import clarin.cmdi.componentregistry.common.ItemDescription;
+			import mx.controls.Alert;
+			import clarin.cmdi.componentregistry.browser.BrowserSelectionEvent;
+			import clarin.cmdi.componentregistry.common.Profile;
+
+			public static const START_ITEM_LOADED:String = "startItemLoaded";
+			
+			private var startupItemLoaded:Boolean = false;
+
+			[Bindable]
+			private var componentsSrv:ComponentListService = ComponentListService.getInstance(Config.instance.userSpace);
+			[Bindable]
+			private var profilesSrv:ProfileListService = ProfileListService.getInstance(Config.instance.userSpace);
+			[Bindable]
+			private var profileSrv:ProfileInfoService = new ProfileInfoService();
+			[Bindable]
+			private var componentSrv:ComponentInfoService = new ComponentInfoService();
+
+			private var deleteSrv:DeleteService = DeleteService.instance;
+
+			[Bindable]
+			private var profilesMenu:BrowseContextMenu;
+			[Bindable]
+			private var componentsMenu:BrowseContextMenu;
+			[Bindable]
+			private var selectedProfileItem:ItemDescription;
+			[Bindable]
+			private var selectedComponentItem:ItemDescription;
+			private var startupItemId:String = null;
+
+			public function init():void {
+				profilesMenu = new BrowseContextMenu();
+				profilesMenu.viewStack = this.parent as RegistryViewStack;
+				profilesMenu.deleteService = deleteSrv;
+				componentsMenu = new BrowseContextMenu(true);
+				componentsMenu.viewStack = this.parent as RegistryViewStack;
+				componentsMenu.deleteService = deleteSrv;
+				deleteSrv.addEventListener(DeleteService.ITEM_DELETED, handleItemDeleted);
+				Config.instance.addEventListener(Config.USER_SPACE_TOGGLE_EVENT, toggleUserSpace);
+			}
+
+			private function toggleUserSpace(event:Event):void {
+				var userSpace:Boolean = Config.instance.userSpace;
+				componentsSrv = ComponentListService.getInstance(userSpace);
+				profilesSrv = ProfileListService.getInstance(userSpace);
+				refresh();
+			}
+
+			private function creationComplete():void { 
+				refresh();
+			}
+
+            public function loadStartup():void {
+				startupItemId = Config.instance.startupItem;
+				if (startupItemId) { //only load this once on startup
+					componentsSrv.addEventListener(BrowserService.ITEMS_LOADED, componentsLoaded);
+					profilesSrv.addEventListener(BrowserService.ITEMS_LOADED, profilesLoaded);
+				}
+				refresh();
+            }
+
+			public function refresh():void {
+				componentsSrv.load();
+				profilesSrv.load();
+			}
+
+			private function profilesLoaded(event:Event):void {
+				var item:ItemDescription = ProfileListService.findDescription(startupItemId);
+				loadStartupItem(item);
+				profilesSrv.removeEventListener(BrowserService.ITEMS_LOADED, profilesLoaded);
+			}
+
+			private function componentsLoaded(event:Event):void {
+				var item:ItemDescription = ComponentListService.findDescription(startupItemId);
+				loadStartupItem(item);
+				componentsSrv.removeEventListener(BrowserService.ITEMS_LOADED, componentsLoaded);
+			}
+			
+			private function loadStartupItem(item:ItemDescription):void {
+				if (item) {
+					setSelectedDescription(item);
+					startupItemId = null;
+					dispatchEvent(new Event(START_ITEM_LOADED));
+				} else if (startupItemLoaded) {
+				    dispatchEvent(new Event(START_ITEM_LOADED));
+				}
+				startupItemLoaded = true;
+			}
+
+			private function loadProfileInfoPage(event:BrowserSelectionEvent):void {
+				profileSrv.load(event.itemDescription);
+			}
+
+			private function loadComponentInfoPage(event:BrowserSelectionEvent):void {
+				componentSrv.load(event.itemDescription);
+			}
+
+			public function setSelectedDescription(desc:ItemDescription):void {
+				if (desc.isProfile) {
+					tabnav.selectedIndex = 0;
+					this.selectedProfileItem = desc;
+					profileSrv.load(desc);
+				} else {
+					tabnav.selectedIndex = 1;
+					this.selectedComponentItem = desc;
+					componentSrv.load(desc);
+				}
+			}
+
+			public function getSelectedStartItem():ItemDescription {
+				if (this.selectedProfileItem) {
+					return selectedProfileItem;
+				} else {
+					return selectedComponentItem;
+				}
+			}
+
+			private function handleItemDeleted(event:Event):void {
+				refresh();
+			}
+
+			public function getType():String {
+				return Config.VIEW_BROWSE;
+			}
+		]]>
+	</mx:Script>
+
+
+	<browser:BrowserColumns id="browserColumns"/>
+
+
+	<mx:VBox borderStyle="none"
+			 horizontalAlign="center"
+			 height="100%"
+			 width="100%">
+
+		<mx:TabNavigator id="tabnav"
+						 width="100%"
+						 height="100%"
+						 color="0x323232"
+						 y="59"
+						 borderStyle="outset">
+			<mx:VDividedBox label="Profiles"
+							width="100%">
+				<browser:BrowserOverviewList id="profilesOverview"
+											 browserColumns="{browserColumns.getProfileColumns()}"
+											 browserDataProvider="{profilesSrv.itemDescriptions}"
+											 browserItemSelected="{loadProfileInfoPage(event)}"
+											 itemToScrollTo="{selectedProfileItem}"
+											 width="100%"
+											 height="70%"
+											 browseMenu="{profilesMenu}"/>
+				<browser:ProfileInfoPage id="profileInfoPage"
+										 profile="{profileSrv.profile}"
+										 width="100%"
+										 height="50%"
+										 contextMenu="{profilesMenu.cm}"/>
+			</mx:VDividedBox>
+
+			<mx:VDividedBox label="Components"
+							width="100%">
+				<browser:BrowserOverviewList id="componentsOverview"
+											 browserColumns="{browserColumns.getComponentColumns()}"
+											 browserDataProvider="{componentsSrv.itemDescriptions}"
+											 browserItemSelected="{loadComponentInfoPage(event)}"
+											 itemToScrollTo="{selectedComponentItem}"
+											 width="100%"
+											 height="70%"
+											 browseMenu="{componentsMenu}"/>
+				<browser:ComponentInfoPage id="componentInfoPage"
+										   component="{componentSrv.component}"
+										   width="100%"
+										   height="50%"
+										   contextMenu="{componentsMenu.cm}"/>
+
+			</mx:VDividedBox>
+		</mx:TabNavigator>
+	</mx:VBox>
+</mx:Canvas>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserColumns.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserColumns.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserColumns.as	(revision 1843)
@@ -0,0 +1,94 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import mx.collections.Sort;
+	import mx.collections.SortField;
+	import mx.controls.dataGridClasses.DataGridColumn;
+	import mx.utils.ObjectUtil;
+	
+	public class BrowserColumns {
+		public function BrowserColumns() {
+		}
+		
+		public function getProfileColumns():Array {
+			var columns:Array = new Array();
+			columns.push(createColumn("name", "Name"));
+			columns.push(createColumn("groupName", "Group Name"));
+			columns.push(createColumn("domainName", "Domain Name"));
+			columns.push(createColumn("creatorName", "Creator"));
+			columns.push(createColumn("description", "Description"));
+			columns.push(createDateColumn());
+			columns.push(createCommentsColumn());
+			return columns;
+		}
+		
+		public function getComponentColumns():Array {
+			var columns:Array = new Array();
+			columns.push(createColumn("name", "Name"));
+			columns.push(createColumn("groupName", "Group Name"));
+			columns.push(createColumn("domainName", "Domain Name"));
+			columns.push(createColumn("creatorName", "Creator Name"));
+			columns.push(createColumn("description", "Description"));
+			columns.push(createDateColumn());
+			columns.push(createCommentsColumn());
+			return columns;
+		}
+		
+		private function createColumn(dataField:String, headerText:String):DataGridColumn {
+			var c:DataGridColumn = new DataGridColumn();
+			c.dataField = dataField;
+			c.headerText = headerText;
+			c.dataTipField = dataField;
+			c.sortCompareFunction = function(itemA:Object, itemB:Object):int { //Sort all string fields case insensitive
+				return ObjectUtil.stringCompare(itemA[dataField], itemB[dataField], true);
+			}
+			return c;
+		}
+		
+		public static function getInitialSortForProfiles():Sort {
+			var sort:Sort = new Sort();
+			var sortByGroup:SortField = new SortField("groupName", true);
+			var sortByName:SortField = new SortField("name", true);
+			var sortByDate:SortField = new SortField("registrationDate", true, true);
+			sortByDate.compareFunction = compareRegistrationDate;
+			sort.fields = [sortByGroup, sortByName, sortByDate];
+			return sort
+		}
+		
+		public static function getInitialSortForComponents():Sort {
+			var sort:Sort = new Sort();
+			var sortByGroup:SortField = new SortField("groupName", true);
+			var sortByName:SortField = new SortField("name", true);
+			var sortByDate:SortField = new SortField("registrationDate", true, true);
+			sortByDate.compareFunction = compareRegistrationDate;
+			sort.fields = [sortByGroup, sortByName, sortByDate];
+			return sort
+		}
+		
+		private function createDateColumn():DataGridColumn {
+			var c:DataGridColumn = createColumn("registrationDate", "Registration Date");
+			c.sortCompareFunction = compareRegistrationDate;
+			return c;
+		}
+		
+		private static function compareRegistrationDate(itemA:Object, itemB:Object):int {
+			return ObjectUtil.dateCompare(itemA.registrationDateValue, itemB.registrationDateValue);
+		}
+		
+		private function createCommentsColumn():DataGridColumn {
+			var c:DataGridColumn = createColumn("commentsCount","Comments");
+			c.width = 75;
+			c.sortCompareFunction = compareCommentsCount;
+			return c;
+		}
+		
+		private static function compareCommentsCount(objectA:Object, objectB:Object):int {
+			//var stringA:String = itemA.toString();
+			//var stringB:String = itemB.toString();
+			var itemA:ItemDescription = ItemDescription(objectA);
+			var itemB:ItemDescription = ItemDescription(objectB);
+			return ObjectUtil.numericCompare(itemA.commentsCount, itemB.commentsCount);
+		}
+		
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserOverviewList.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserOverviewList.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserOverviewList.mxml	(revision 1843)
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 xmlns:comp="clarin.cmdi.componentregistry.common.components.*"
+		 xmlns:common="clarin.cmdi.componentregistry.common.*"
+		 xmlns:rictus="com.rictus.controls.*"
+		 initialize="init();"
+		 creationComplete="scrollToSelected()">
+
+	<mx:Metadata>
+		[Event(name="browserItemSelected",type="clarin.cmdi.componentregistry.browser.BrowserSelectionEvent")]
+	</mx:Metadata>
+
+	<mx:Array id="browserColumns"/>
+
+
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.common.Credentials;
+			import clarin.cmdi.componentregistry.common.Login;
+			import mx.collections.ArrayList;
+			import com.adobe.utils.ArrayUtil;
+			import clarin.cmdi.componentregistry.common.StyleConstants;
+			import clarin.cmdi.componentregistry.services.Config;
+			import clarin.cmdi.componentregistry.common.components.BrowseContextMenu;
+			import mx.collections.ArrayCollection;
+			import mx.events.CollectionEvent;
+			import clarin.cmdi.componentregistry.browser.BrowserSelectionEvent;
+			import clarin.cmdi.componentregistry.common.ItemDescription;
+
+			private static const USERSPACE_LABEL:String = "Work space";
+			private static const PUBLICSPACE_LABEL:String = "Public space";
+
+			private var defaultColor:Object;
+			private var currentSelectedItem:ItemDescription;
+			[Bindable]
+			private var menu:BrowseContextMenu;
+
+			private var _itemToScrollTo:ItemDescription;
+			[Bindable]
+			public var spaces:ArrayCollection = new ArrayCollection([{label: PUBLICSPACE_LABEL, data: 1}, {label: USERSPACE_LABEL, data: 2}]);
+
+			public function set browserDataProvider(dataProvider:ArrayCollection):void {
+				if (dataProvider) {
+					var data:ArrayCollection = new ArrayCollection(dataProvider.toArray().slice());
+					this.dataGrid.dataProvider = data
+					dataGrid.doFiltering();
+					scrollToSelected();
+				}
+			}
+
+			private function dispatchBrowserSelectionEvent():void {
+				if (this.dataGrid.selectedItem != null) {
+					var item:ItemDescription = dataGrid.selectedItem as ItemDescription
+					if (currentSelectedItem == null || currentSelectedItem.id != item.id) { //Only update when the item selected is different.
+						currentSelectedItem = item;
+						var event:BrowserSelectionEvent = new BrowserSelectionEvent(item);
+						dispatchEvent(event);
+					}
+				}
+			}
+
+			public function set itemToScrollTo(itemToScrollTo:ItemDescription):void {
+				_itemToScrollTo = itemToScrollTo;
+				scrollToSelected();
+			}
+
+			private function scrollToSelected():void {
+				if (_itemToScrollTo && dataGrid.dataProvider) {
+					for (var i:int; i < dataGrid.dataProvider.length; i++) {
+						var item:ItemDescription = dataGrid.dataProvider.getItemAt(i) as ItemDescription;
+						if (item.id == _itemToScrollTo.id) {
+							dataGrid.selectedItem = item;
+							dispatchBrowserSelectionEvent();
+							dataGrid.setFocus();
+							dataGrid.scrollToIndex(i);
+							break;
+						}
+					}
+				}
+			}
+
+			public function set browseMenu(browseMenu:BrowseContextMenu):void {
+				this.menu = browseMenu;
+				menu.dataGrid = dataGrid;
+			}
+
+			private function handleKeyUp(event:KeyboardEvent):void {
+				if (event.keyCode == Keyboard.DELETE) {
+					menu.deleteSelectedItems();
+				}
+			}
+
+			private function init():void {
+				Config.instance.addEventListener(Config.USER_SPACE_TOGGLE_EVENT, setUserSpace);
+				setUserSpace();
+			}
+
+			private function setUserSpace(event:Event = null):void {
+				if (Config.instance.userSpace) {
+					userSpaceCB.selectedIndex = 1;
+				} else {
+					userSpaceCB.selectedIndex = 0;
+				}
+			}
+
+			private function userSpaceCloseHandler(event:Event):void {
+				if (Credentials.instance.isLoggedIn()) {
+					Config.instance.userSpace = ComboBox(event.target).selectedItem.data == 2;
+				} else if (userSpaceCB.selectedIndex != 0) {
+					userSpaceCB.selectedIndex = 0;
+					new Login().show(this, Config.VIEW_BROWSE, Config.SPACE_USER, null);
+				}
+
+			}
+		]]>
+	</mx:Script>
+
+	<mx:HBox horizontalAlign="center"
+			 verticalAlign="middle"
+			 width="100%">
+
+
+		<mx:ComboBox id="userSpaceCB"
+					 dataProvider="{spaces}"
+					 width="110"
+					 close="userSpaceCloseHandler(event);"/>
+
+
+		<rictus:SearchBox id="searchBox"
+						  label="filter..."/>
+		<mx:Label text="Showing {dataGrid.dataProvider.length} of {dataGrid.unfilteredLength}"/>
+	</mx:HBox>
+
+	<comp:FilteringDataGrid id="dataGrid"
+							x="0"
+							y="112"
+							width="100%"
+							height="100%"
+							click="dispatchBrowserSelectionEvent()"
+							columns="{browserColumns}"
+							contextMenu="{menu.cm}"
+							allowMultipleSelection="true"
+							searchInput="{searchBox}"
+							keyUp="handleKeyUp(event)"
+							useRollOver="false"
+							showDataTips="true">
+	</comp:FilteringDataGrid>
+</mx:VBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserSelectionEvent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserSelectionEvent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/BrowserSelectionEvent.as	(revision 1843)
@@ -0,0 +1,27 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+
+	import flash.events.Event;
+
+	public class BrowserSelectionEvent extends Event {
+
+		public static const BROWSER_ITEM_SELECTED:String = "browserItemSelected";
+		private var _itemDescription:ItemDescription;
+
+		public function BrowserSelectionEvent(itemDescription:ItemDescription, bubbles:Boolean = false, cancelable:Boolean = false) {
+			super(BROWSER_ITEM_SELECTED, bubbles, cancelable);
+			_itemDescription = itemDescription;
+		}
+
+		public function get itemDescription():ItemDescription {
+			return _itemDescription;
+		}
+
+		override public function clone():Event {
+			return new BrowserSelectionEvent(_itemDescription, bubbles, cancelable);
+		}
+
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CMDComponentXMLBrowser.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CMDComponentXMLBrowser.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CMDComponentXMLBrowser.as	(revision 1843)
@@ -0,0 +1,147 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.CMDSpecRenderer;
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.ExpandingComponentLabel;
+	import clarin.cmdi.componentregistry.editor.model.CMDAttribute;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	import clarin.cmdi.componentregistry.editor.model.CMDSpec;
+
+	import flash.utils.getTimer;
+
+	import mx.collections.ArrayCollection;
+	import mx.containers.HBox;
+	import mx.containers.VBox;
+	import mx.controls.HRule;
+	import mx.controls.Label;
+	import mx.controls.Spacer;
+	import mx.core.Container;
+	import mx.managers.IFocusManagerComponent;
+
+	/**
+	 * Browser view created from CMDComponent xml
+	 */
+	public class CMDComponentXMLBrowser extends VBox implements IFocusManagerComponent, CMDSpecRenderer {
+
+		private var _spec:CMDSpec;
+		private var _firstComponent:CMDComponent;
+
+		public function CMDComponentXMLBrowser() {
+			super();
+			styleName = StyleConstants.XMLBROWSER;
+			focusEnabled = true;
+			tabEnabled = true;
+		}
+
+		public function set cmdSpec(cmdSpec:CMDSpec):void {
+			_spec = cmdSpec;
+			createNewBrowser();
+		}
+
+		[Bindable]
+		public function get cmdSpec():CMDSpec {
+			return _spec;
+		}
+
+		private function createNewBrowser():void {
+			var start:int = getTimer();
+			removeAllChildren()
+			checkFirstDefiningComponent(_spec.cmdComponents);
+			var componentLink:HBox = CMDComponentXMLBrowser.createComponentLink(_firstComponent);
+			if (!componentLink) {
+				handleHeader(_firstComponent.name);
+			} else {
+				handleHeader(_spec.headerName);
+				//FirstComponent is link so creating that.
+				addChild(componentLink);
+				if (_firstComponent.cardinalityMin != "" || _firstComponent.cardinalityMax != "") {
+					addChild(new XMLBrowserLine(LabelConstants.CARDINALITY, _firstComponent.cardinalityMin + " - " + _firstComponent.cardinalityMax));
+				}
+			}
+			handleCMDAttributeList(this, _firstComponent.attributeList, 0);
+			handleElements(_firstComponent.cmdElements);
+			handleComponents(_firstComponent.cmdComponents);
+			trace("Created browser view in " + (getTimer() - start) + " ms.");
+		}
+
+		public static function handleCMDAttributeList(parent:Container, attributes:ArrayCollection, indent:int):void {
+			if (attributes.length > 0) {
+				var heading:HBox = new HBox();
+				var label:Label = new Label();
+				label.text = LabelConstants.ATTRIBUTELIST;
+				label.styleName = StyleConstants.XMLBROWSER_FIELD;
+				var smallIndent:Spacer = new Spacer();
+				smallIndent.width = 5;
+				if (indent > 0)
+					heading.addChild(getIndentSpacer(indent));
+				heading.addChild(smallIndent);
+				heading.addChild(label);
+				parent.addChild(heading);
+				for each (var attribute:CMDAttribute in attributes) {
+					var child:XMLBrowserValueSchemeLine = new XMLBrowserValueSchemeLine(attribute.name, indent+1, attribute.valueSchemeSimple, attribute.valueSchemePattern, attribute.valueSchemeEnumeration, attribute.conceptLink);
+					parent.addChild(child);
+				}
+			}
+		}
+
+		public static function getIndentSpacer(indent:int):Spacer {
+			var result:Spacer = new Spacer();
+			result.width = 56 * indent;
+			return result;
+		}
+
+		/**
+		 * The xml model allows more component to be defined but we force only one component at the "root" level.
+		 */
+		private function checkFirstDefiningComponent(components:ArrayCollection):void {
+			if (components.length != 1) {
+				throw new Error("A profile/component must have 1 component defined at root level.");
+			} else {
+				_firstComponent = components.getItemAt(0) as CMDComponent;
+			}
+		}
+
+		private function handleHeader(name:String):void {
+			addChild(new XMLBrowserLine(LabelConstants.NAME, name, StyleConstants.XMLBROWSER_FIELD, StyleConstants.XMLBROWSER_HEADER));
+			if(_spec.groupName){
+				addChild(new XMLBrowserLine(LabelConstants.GROUP_NAME, _spec.groupName));
+			}
+			addChild(new XMLBrowserLine(LabelConstants.DESCRIPTION, _spec.headerDescription));
+			if (_firstComponent.conceptLink) {
+				addChild(new XMLBrowserConceptLinkLine(LabelConstants.CONCEPTLINK, _firstComponent.conceptLink));
+			}
+			var ruler:HRule = new HRule();
+			ruler.percentWidth = 80;
+			addChild(ruler);
+		}
+
+		private function handleElements(elements:ArrayCollection):void {
+			for each (var element:CMDComponentElement in elements) {
+				var elementBrowse:ElementBrowse = new ElementBrowse(element);
+				elementBrowse.createAndAddChildren(this, 1);
+			}
+		}
+
+		private function handleComponents(components:ArrayCollection):void {
+			for each (var component:CMDComponent in components) {
+				var componentBrowse:ComponentBrowse = new ComponentBrowse(component);
+				componentBrowse.createAndAddChildren(this);
+			}
+		}
+
+		public static function createComponentLink(component:CMDComponent):HBox {
+			if (component.componentId != "" && component.componentId != null) {
+				var result:HBox = new HBox();
+				var labelName:Label = new Label();
+				labelName.styleName = StyleConstants.XMLBROWSER_HEADER;
+				labelName.text = LabelConstants.COMPONENT;
+				result.addChild(labelName);
+				result.addChild(new ExpandingComponentLabel(component.componentId, false));
+				return result;
+			}
+			return null;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentPanel.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentPanel.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentPanel.as	(revision 1843)
@@ -0,0 +1,58 @@
+package clarin.cmdi.componentregistry.browser
+{
+	import clarin.cmdi.componentregistry.common.Comment;
+	
+	import mx.containers.HBox;
+	import mx.containers.VBox;
+	import mx.controls.HRule;
+	import mx.controls.Label;
+	import mx.controls.Text;
+
+	public class CommentPanel extends VBox
+	{
+		private var userNameLabel:Label = new Label();
+		private var dateLabel:Label = new Label();
+		private var commentText:Text = new Text();
+		private var comment:Comment;
+		
+		public function CommentPanel(comment:Comment)
+		{
+			super();
+			this.comment = comment;
+			
+			initLayout();
+			setValues();
+		}
+		
+		private function initLayout():void{
+			this.width = 400;
+			
+			var header:HBox = new HBox();
+			header.percentWidth = 100;
+			header.addChild(userNameLabel);
+			header.addChild(dateLabel);
+			
+			userNameLabel.setStyle("fontWeight","bold");
+			userNameLabel.setStyle("textDecoration","underline");
+			userNameLabel.percentWidth = 70;
+			dateLabel.setStyle("textAlign", "right");
+			dateLabel.setStyle("fontWeight","bold");
+			dateLabel.percentWidth = 30;
+			
+			addChild(header);
+			
+			commentText.percentWidth = 100;
+			addChild(commentText);
+
+			var rule:HRule = new HRule();
+			rule.percentWidth = 100;
+			addChild(rule);
+		}
+		
+		private function setValues():void{
+			userNameLabel.text = comment.userName;
+			dateLabel.text = comment.commentDate;
+			commentText.text = comment.comments;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentsPanel.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentsPanel.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/CommentsPanel.as	(revision 1843)
@@ -0,0 +1,97 @@
+package clarin.cmdi.componentregistry.browser
+{
+	import clarin.cmdi.componentregistry.common.Comment;
+	import clarin.cmdi.componentregistry.common.Credentials;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.services.CommentListService;
+	import clarin.cmdi.componentregistry.services.CommentPostService;
+	
+	import flash.events.Event;
+	
+	import mx.containers.VBox;
+	import mx.controls.HRule;
+	import mx.controls.Label;
+	
+	[Event(name="commentsLoaded",type="flash.events.Event")]
+	public class CommentsPanel extends VBox
+	{
+		public static const COMMENTS_LOADED:String = "commentsLoaded";
+		
+		[Bindable]
+		private var _itemDescription:ItemDescription;
+		private var service:CommentListService;
+		private var commentsBox:VBox;
+		
+		public function get commentListService():CommentListService {
+			return service;
+		}
+		
+		public function set itemDescription(itemDescription:ItemDescription):void {
+			_itemDescription = itemDescription;
+		}
+		
+		public function CommentsPanel()
+		{ 
+			this.setStyle("paddingLeft", 5);
+			this.setStyle("paddingTop", 5);
+			this.setStyle("paddingBottom", 5);
+		}
+		
+		public function load():void{
+			removeAllChildren();
+			
+			// A box for the comments (will be loaded in callback but should be shown first)
+			commentsBox = new VBox();
+			addChild(commentsBox);
+			
+			// A panel for posting a comment (or a message 'login to post');
+			addPostPanel();
+			
+			// Do actual loading
+			service = new CommentListService(_itemDescription, _itemDescription.isInUserSpace);
+			service.addEventListener(CommentListService.COMMENTS_LOADED, commentsLoaded);
+			service.load();
+		}
+		
+		private function addPostPanel():void{
+			if(Credentials.instance.isLoggedIn()){
+				var postPanel:commentPostPanel = new commentPostPanel();
+				postPanel.itemDescription = _itemDescription;
+				postPanel.commentPostService.addEventListener(CommentPostService.POST_COMPLETE, postCompleteHandler);
+				addChild(postPanel);
+			} else{
+				var loginToPostLabel:Label = new Label();
+				loginToPostLabel.setStyle("fontWeight","bold");
+				loginToPostLabel.text = "Login to leave a comment!";
+				addChild(loginToPostLabel);
+			}
+		}
+		
+		private function commentsLoaded(event:Event):void{
+			if(service) {
+				var commentsCount:int = service.comments.length;
+				_itemDescription.commentsCount = commentsCount;
+				
+				if(commentsCount > 0) {
+					for each(var comment:Comment in service.comments) {
+						var panel:CommentPanel = new CommentPanel(comment);
+						commentsBox.addChild(panel);
+					}
+				} else {
+					var noCommentsPostedLabel:Label = new Label();
+					noCommentsPostedLabel.text = "No comments have been posted thus far.";
+					commentsBox.addChild(noCommentsPostedLabel);
+					
+					var rule:HRule = new HRule();
+					rule.percentWidth = 100;
+					commentsBox.addChild(rule);
+				}
+			}
+			dispatchEvent(new Event(COMMENTS_LOADED));
+		}
+		
+		private function postCompleteHandler(event:Event):void{
+			load();
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentBrowse.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentBrowse.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentBrowse.as	(revision 1843)
@@ -0,0 +1,81 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+
+	import mx.collections.ArrayCollection;
+	import mx.containers.HBox;
+	import mx.controls.HRule;
+	import mx.core.Container;
+
+	public class ComponentBrowse {
+		private var _component:CMDComponent;
+		private var container:Container;
+		private var indent:int = 0;
+
+		public function ComponentBrowse(component:CMDComponent) {
+			super();
+			_component = component;
+		}
+
+		public function createAndAddChildren(container:Container, indent:int = 0):void {
+			this.container = container;
+			this.indent = indent;
+			if (indent == 0) {
+				var ruler:HRule = new HRule();
+				ruler.percentWidth = 80;
+				container.addChild(ruler);
+			}
+			var componentLink:HBox = CMDComponentXMLBrowser.createComponentLink(_component);
+			if (componentLink != null) {
+				addChild(componentLink);
+				addCardinalityLine();
+			} else {
+				addChild(new XMLBrowserLine(LabelConstants.COMPONENT, _component.name, StyleConstants.XMLBROWSER_HEADER, StyleConstants.XMLBROWSER_HEADER));
+				if (_component.conceptLink) {
+					addChild(new XMLBrowserConceptLinkLine(LabelConstants.CONCEPTLINK, _component.conceptLink));
+				}
+				addCardinalityLine();
+				CMDComponentXMLBrowser.handleCMDAttributeList(container, _component.attributeList, indent);
+				handleElements(_component.cmdElements);
+				handleComponents(_component.cmdComponents); //recursion
+			}
+		}
+
+		private function handleElements(elements:ArrayCollection):void {
+			for each (var element:CMDComponentElement in elements) {
+				var elementBrowse:ElementBrowse = new ElementBrowse(element);
+				elementBrowse.createAndAddChildren(container, indent + 1);
+			}
+		}
+
+		private function handleComponents(components:ArrayCollection):void {
+			for each (var component:CMDComponent in components) {
+				var componentBrowse:ComponentBrowse = new ComponentBrowse(component);
+				componentBrowse.createAndAddChildren(container, indent + 1);
+			}
+		}
+
+
+		private function addCardinalityLine():void {
+			if (_component.cardinalityMin != "" || _component.cardinalityMax != "")
+				addChild(new XMLBrowserLine(LabelConstants.CARDINALITY, _component.cardinalityMin + " - " + _component.cardinalityMax));
+
+		}
+
+		private function addLine(name:String, value:String):void {
+			if (value) {
+				addChild(new XMLBrowserLine(name, value));
+			}
+		}
+
+		private function addChild(child:HBox):void {
+			if (indent > 0) {
+				child.addChildAt(CMDComponentXMLBrowser.getIndentSpacer(indent), 0);
+			}
+			this.container.addChild(child);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentInfoPage.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentInfoPage.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ComponentInfoPage.mxml	(revision 1843)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 xmlns:common="clarin.cmdi.componentregistry.common.*"
+		 xmlns:browser="clarin.cmdi.componentregistry.browser.*"
+		 width="100%"
+		 backgroundColor="#DDE3EF"
+		 >
+
+	<common:Component id="component"/>
+
+	<browser:infoPage id="infoPanel"
+				   cmdComponent="{component.componentMD.xml}"
+				   itemDescription="{component.description}"
+				   headerLabel="{component.description.name}"
+				   width="100%"
+				   height="100%"
+				   visible="{component != null}"/>
+
+</mx:VBox>
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ElementBrowse.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ElementBrowse.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ElementBrowse.as	(revision 1843)
@@ -0,0 +1,69 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	
+	import mx.containers.HBox;
+	import mx.controls.Label;
+	import mx.core.Container;
+	import mx.core.UIComponent;
+
+	public class ElementBrowse {
+		private var _element:CMDComponentElement;
+		private var container:Container;
+				private var _indent:int = 0;
+		
+
+		public function ElementBrowse(element:CMDComponentElement) {
+			super();
+			_element = element;
+		}
+
+		public function createAndAddChildren(container:Container, indent:int = 0):void {
+			this.container = container;
+			this._indent = indent;
+			addHeading();
+			if (_element.conceptLink)
+				addChild(new XMLBrowserConceptLinkLine(LabelConstants.CONCEPTLINK, _element.conceptLink), _indent);
+			addLine(LabelConstants.DOCUMENTATION, _element.documentation);
+			addLine(LabelConstants.DISPLAY_PRIORITY, _element.displayPriority);
+			if (_element.cardinalityMin != "" || _element.cardinalityMax != "") {
+				addLine(LabelConstants.CARDINALITY, _element.cardinalityMin + " - " + _element.cardinalityMax);
+			}
+			if (_element.valueSchemeSimple && _element.valueSchemeSimple == "string") {
+			    addLine(LabelConstants.MULTILINGUAL, _element.multilingual);
+			}
+			CMDComponentXMLBrowser.handleCMDAttributeList(container, _element.attributeList, _indent - 1);
+		}
+
+		private function addHeading():void {
+			var line:HBox = new HBox();
+			var heading:Label = new Label();
+			heading.text = LabelConstants.ELEMENT;
+			heading.styleName = StyleConstants.XMLBROWSER_HEADER;
+			var name:Label = new Label();
+			name.text = _element.name;
+			name.styleName = StyleConstants.XMLBROWSER_HEADER;
+			var value:UIComponent = XMLBrowserValueSchemeLine.createValueScheme(_element.valueSchemeSimple, _element.valueSchemePattern, _element.valueSchemeEnumeration);
+			value.styleName = StyleConstants.XMLBROWSER_FIELD_VALUE;
+			line.addChild(heading);
+			line.addChild(name);
+			line.addChild(value);
+			addChild(line, _indent - 1);
+		}
+
+		private function addLine(name:String, value:String):void {
+			if (value) {
+				addChild(new XMLBrowserLine(name, value), _indent);
+			}
+		}
+
+		private function addChild(child:HBox, indent:int):void {
+			if(indent > 0) {
+				child.addChildAt(CMDComponentXMLBrowser.getIndentSpacer(indent), 0);
+			}
+			this.container.addChild(child);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ProfileInfoPage.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ProfileInfoPage.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/ProfileInfoPage.mxml	(revision 1843)
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 xmlns:common="clarin.cmdi.componentregistry.common.*"
+		 xmlns:browser="clarin.cmdi.componentregistry.browser.*"
+		 width="100%"
+		 backgroundColor="#DDE3EF">
+
+	<common:Profile id="profile"/>
+
+	<browser:infoPage id="infoPanel"
+				   cmdComponent="{profile.profileSource}"
+				   itemDescription="{profile.description}"
+				   headerLabel="{profile.description.name}"
+				   width="100%"
+				   height="100%"
+				   visible="{profile != null}"/>
+
+</mx:VBox>
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserConceptLinkLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserConceptLinkLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserConceptLinkLine.as	(revision 1843)
@@ -0,0 +1,28 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.LinkRenderer;
+	
+	import mx.containers.HBox;
+	import mx.controls.Label;
+
+	public class XMLBrowserConceptLinkLine extends HBox {
+
+		private var nameLabel:Label = new Label();
+		private var fieldValue:LinkRenderer = new LinkRenderer();
+
+		public function XMLBrowserConceptLinkLine(name:String, value:String) {
+			super();
+			nameLabel.text = name;
+			nameLabel.styleName = StyleConstants.XMLBROWSER_FIELD;
+			fieldValue.text = value;
+			fieldValue.styleName = StyleConstants.XMLBROWSER_FIELD_VALUE;
+			fieldValue.width = 500;
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(nameLabel);
+			addChild(fieldValue);
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserLine.as	(revision 1843)
@@ -0,0 +1,34 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.containers.HBox;
+	import mx.controls.Label;
+	import mx.controls.Text;
+
+	public class XMLBrowserLine extends HBox {
+
+		private var nameLabel:Label = new Label();
+		private var fieldValue:Text = null;
+
+		public function XMLBrowserLine(name:String, value:String, nameStyle:String=StyleConstants.XMLBROWSER_FIELD_VALUE, valueStyle:String=StyleConstants.XMLBROWSER_FIELD_VALUE) {
+			super();
+			nameLabel.text = name;
+			nameLabel.styleName = nameStyle;
+			if (value) {
+				fieldValue = new Text();
+				fieldValue.text = value;
+				fieldValue.styleName = valueStyle;
+				fieldValue.width = 500;
+			}
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(nameLabel);
+			if (fieldValue != null) {
+				addChild(fieldValue);
+			}
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserValueSchemeLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserValueSchemeLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/XMLBrowserValueSchemeLine.as	(revision 1843)
@@ -0,0 +1,92 @@
+package clarin.cmdi.componentregistry.browser {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.LinkRenderer;
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+	
+	import flash.display.DisplayObject;
+	
+	import mx.collections.ArrayCollection;
+	import mx.containers.HBox;
+	import mx.controls.ComboBox;
+	import mx.controls.Label;
+	import mx.controls.Text;
+	import mx.core.ClassFactory;
+	import mx.core.UIComponent;
+
+	public class XMLBrowserValueSchemeLine extends HBox {
+		private var nameLabel:Label = new Label();
+		private var conceptLink:LinkRenderer;
+		private var valueObject:DisplayObject;
+		private var _indent:int = 0;
+
+		public function XMLBrowserValueSchemeLine(name:String, indent:int, value:String = null, valuePattern:String = null, valueList:ArrayCollection = null, conceptLinkValue:String = null) {
+			super();
+			_indent = indent;
+			nameLabel.text = name;
+			nameLabel.styleName = StyleConstants.XMLBROWSER_FIELD;
+			valueObject = createValueScheme(value, valuePattern, valueList);
+			conceptLink = createConceptLink(conceptLinkValue);
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			if (_indent > 0)
+				addChild(CMDComponentXMLBrowser.getIndentSpacer(_indent));
+			addChild(nameLabel);
+			addChild(valueObject);
+			if(conceptLink){
+				addChild(conceptLink);
+			}
+		}
+		
+		public static function createConceptLink(linkValue:String):LinkRenderer{
+			if(linkValue){
+				var conceptLink:LinkRenderer = new LinkRenderer();
+				conceptLink.text = linkValue;
+				conceptLink.styleName = StyleConstants.XMLBROWSER_FIELD_VALUE;
+				return conceptLink;
+			} else {
+				return null;
+			}
+		}
+
+		public static function createValueScheme(value:String = null, valuePattern:String = null, valueList:ArrayCollection = null):UIComponent {
+			if (valueList) {
+				return createEnumeration(valueList);
+			} else if (valuePattern) {
+				return createText(valuePattern);
+			} else {
+				return createText(value);
+			}
+		}
+
+		private static function createText(value:String):UIComponent {
+			var result:Text = new Text();
+			result.text = value;
+			result.styleName = StyleConstants.XMLBROWSER_FIELD_VALUE;
+			return result;
+		}
+
+		private static function createEnumeration(enumeration:ArrayCollection):UIComponent {
+			var result:ComboBox = createValueSchemeComboBox();
+			result.dataProvider = enumeration;
+			return result;
+		}
+
+		public static function createValueSchemeComboBox():ComboBox {
+			var result:ComboBox = new ComboBox();
+			result.itemRenderer = new ClassFactory(Label);
+			result.labelFunction = function(item:Object):String {
+			    var valueSchemeItem:ValueSchemeItem = item as ValueSchemeItem;
+			    if (item.appInfo != "") {
+			        return item.item + "-" + item.appInfo;
+			    } else {
+			        return item.item;
+			    }
+			};
+			return result;
+		}
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/commentPostPanel.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/commentPostPanel.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/commentPostPanel.mxml	(revision 1843)
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" xmlns:common="clarin.cmdi.componentregistry.common.*" xmlns:services="clarin.cmdi.componentregistry.services.*">
+	
+	<common:ItemDescription id="itemDescription" />
+	
+	<services:CommentPostService id="commentPostService" 
+								 postComplete="postCompleteHandler(event)"
+								 />
+	
+	<mx:Label text="Enter your comment below:" />
+	
+	<mx:Text id="errorMessageField"
+			 text="{commentPostService.message}"
+			 visible='{errorMessageField.text != ""}'
+			 includeInLayout='{errorMessageField.text != ""}'/>
+	
+	<mx:TextArea width="100%" id="comments" minHeight="100" />
+	<mx:Button label="Submit" 
+			   id="submitButton"
+			   click="postComment()"
+			   />
+	<mx:HRule width="100%" />
+	
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.common.Comment;
+			import clarin.cmdi.componentregistry.services.CommentPostService;
+			
+			private function postComment():void{
+				var comment:Comment = new Comment();
+				// Leave username, date empty so web service will fill them out
+				comment.userName = "";
+				comment.commentDate = "";
+
+				comment.comments = comments.text;
+				if(itemDescription.isProfile){
+					comment.profileDescriptionId = itemDescription.id;
+				} else{
+					comment.componentDescriptionId = itemDescription.id;
+				}
+				commentPostService.upload(comment, itemDescription);
+			}
+
+			protected function postCompleteHandler(event:Event):void
+			{
+				comments.text = "";
+			}
+
+		]]>
+	</mx:Script>
+</mx:VBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/infoPage.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/infoPage.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/infoPage.mxml	(revision 1843)
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 xmlns:comp="clarin.cmdi.componentregistry.common.components.*"
+		 xmlns:common="clarin.cmdi.componentregistry.common.*"
+		 xmlns:browser="clarin.cmdi.componentregistry.browser.*"
+		 >
+
+	<mx:XML id="cmdComponent"/>
+	<mx:String id="headerLabel"/>
+
+	<mx:HBox horizontalAlign="center"
+			 verticalAlign="middle"
+			 width="100%">
+		<mx:Label id="header"
+				  text="{headerLabel}"
+				  fontWeight="bold"
+				  fontSize="14"/>
+		<mx:ToggleButtonBar id="toggleBar"
+							dataProvider="{infoViewStack}"/>
+	</mx:HBox>
+
+	<mx:ViewStack id="infoViewStack"
+				  height="100%"
+				  width="100%"
+				  styleName="borderStyles">
+
+		<browser:xmlBrowsePanel id="viewPanel"
+								label="view"
+								cmdComponent="{cmdComponent}"
+								itemDescription="{_itemDescription}"/>
+		<browser:xmlPanel id="xmlPanel"
+						  label="xml"
+						  cmdComponent="{cmdComponent}"/>
+		<browser:CommentsPanel id="commentsPanel"
+							   label="{commentsLabel}"
+							   itemDescription="{_itemDescription}" 
+							   show="commentsPanel.load()"
+							   commentsLoaded="commentsLoadedHandler(event)"
+							   />
+	</mx:ViewStack>
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.common.ItemDescription;
+			import clarin.cmdi.componentregistry.services.CommentListService;
+			
+			import mx.events.FlexEvent;
+			
+			[Bindable]
+			private var _itemDescription:ItemDescription;
+			
+			public function set itemDescription(itemDescription:ItemDescription):void{
+				_itemDescription = itemDescription;
+				commentsPanel.label = commentsLabel;
+				if(infoViewStack.selectedChild == commentsPanel){
+					commentsPanel.load();
+				}
+			}
+			
+			private function get commentsLabel():String{
+				return "Comments (" + _itemDescription.commentsCount + ")";
+			}
+			
+			private function commentsLoadedHandler(event:Event):void {
+				// After loading, re-create string for comments label because number of comments might have changed (e.g. after a post)
+				commentsPanel.label = commentsLabel;
+			}
+
+		]]>
+	</mx:Script>
+</mx:VBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlBrowsePanel.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlBrowsePanel.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlBrowsePanel.mxml	(revision 1843)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
+		   xmlns:common="clarin.cmdi.componentregistry.common.*"
+		   xmlns:browser="clarin.cmdi.componentregistry.browser.*">
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.editor.model.CMDModelFactory;
+		]]>
+	</mx:Script>
+
+	<mx:XML id="cmdComponent"/>
+	<common:ItemDescription id="itemDescription"/>
+
+	<browser:CMDComponentXMLBrowser id="xmlBrowse"
+									cmdSpec="{CMDModelFactory.createModel(cmdComponent, itemDescription)}"
+									width="100%"
+									height="100%"
+									paddingLeft="5"
+									paddingTop="5"
+									/>
+</mx:Canvas>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlPanel.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlPanel.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/browser/xmlPanel.mxml	(revision 1843)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 xmlns:comp="clarin.cmdi.componentregistry.common.components.*">
+
+	<mx:XML id="cmdComponent"/>
+	<comp:ScrollableTextArea id="infoTextArea"
+							 styleName="xmlTextArea"
+							 editable="false"
+							 text="{cmdComponent}"
+							 width="100%"
+							 height="100%"
+							 paddingLeft="5"
+							 paddingTop="5"
+							 />
+</mx:VBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/AboutPopup.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/AboutPopup.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/AboutPopup.mxml	(revision 1843)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
+				title="About the Clarin Component Registry"
+				showCloseButton="true"
+				close="cleanUp();"
+				backgroundColor="#DDE3EF"
+				initialize="init();"
+				preinitialize="preinit();"
+				>
+	
+	<mx:Script>
+		<![CDATA[
+			import mx.managers.PopUpManager;
+			
+			private var version:String;
+			
+			private function preinit():void{
+				var APPINFO:Namespace = new Namespace("APPINFO");
+				if(APPINFO != null){
+					try{
+						version = APPINFO::version;
+					} catch(err:ReferenceError){
+						// Version set at compilation
+						version = "?";
+					}
+				}
+			}
+			
+			private function init():void{
+				aboutText.htmlText 
+					= "The Clarin Component Registry provides long term storage and\n"
+					+ "easy browsing, creation and editing of components and profiles.\n"
+					+ "\n"
+					+"Version: " + version + "\n"
+					+"Written by: Patrick Duin and Twan Goosen\n"
+					+"\n"
+					+"Go to <u><a target=\"_blank\" href=\"http://www.clarin.eu/cmdi\">www.clarin.eu/cmdi</a></u> for more information.\n"
+					+"Email <u><a href=\"mailto:cmdi@clarin.eu\">cmdi@clarin.eu</a></u> for questions/support.\n";
+			}
+			
+			private function cleanUp():void {
+				PopUpManager.removePopUp(this);
+			}
+			
+		]]>
+	</mx:Script>
+	
+	<mx:Text id="aboutText">
+	</mx:Text>
+</mx:TitleWindow>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/CMDSpecRenderer.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/CMDSpecRenderer.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/CMDSpecRenderer.as	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.common
+{
+    import clarin.cmdi.componentregistry.editor.model.CMDSpec;
+    
+    public interface CMDSpecRenderer
+    {
+        
+        function set cmdSpec(cmdSpec:CMDSpec):void;
+        function get cmdSpec():CMDSpec;
+        
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Comment.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Comment.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Comment.as	(revision 1843)
@@ -0,0 +1,45 @@
+package clarin.cmdi.componentregistry.common
+{
+	public class Comment implements XmlAble
+	{
+		[Bindable]
+		public var comments:String;
+		
+		[Bindable]
+		public var userName:String;
+		
+		[Bindable]
+		public var commentDate:String;
+		
+		public var componentDescriptionId:String;
+		public var profileDescriptionId:String;
+		public var id:String;
+		
+		public function Comment():void{
+			
+		}
+		
+		public function create(comment:XML):void{
+			this.comments = comment.comments;
+			this.commentDate  = DateUtils.formatDateString(comment.commentDate);
+			this.componentDescriptionId = comment.componentDescriptionId;
+			this.profileDescriptionId = comment.profileDescriptionId;
+			this.id = comment.id;
+			this.userName = comment.userName;
+		}
+		
+		public function toXml():XML {
+			var result:XML = <comment></comment>;
+			result.appendChild(<comments>{comments}</comments>);
+			result.appendChild(<commentDate>{commentDate}</commentDate>);
+			if(profileDescriptionId){
+				result.appendChild(<profileDescriptionId>{profileDescriptionId}</profileDescriptionId>);
+			}
+			if(componentDescriptionId){
+				result.appendChild(<componentDescriptionId>{componentDescriptionId}</componentDescriptionId>);
+			}
+			result.appendChild(<userName>{userName}</userName>);
+			return result;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Component.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Component.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Component.as	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.common {
+
+	[Bindable]
+	public class Component {
+		public var description:ItemDescription;
+		public var componentMD:ComponentMD;
+
+		public function Component() {
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ComponentMD.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ComponentMD.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ComponentMD.as	(revision 1843)
@@ -0,0 +1,44 @@
+package clarin.cmdi.componentregistry.common {
+	import mx.collections.ArrayCollection;
+
+	[Bindable]
+	public class ComponentMD {
+	    
+	    /** 
+	    * Claring Metadata xml constants
+	    */
+	    //Element Names
+	    public static const CONCEPTLINK:String = "ConceptLink";
+	    public static const COMPONENTID:String = "ComponentId";
+	    public static const CMD_COMPONENT:String = "CMD_Component";
+	    public static const CMD_ELEMENT:String = "CMD_Element";
+	    public static const HEADER:String = "Header";
+	    public static const ENUMERATION:String = "enumeration";
+	    public static const PATTERN:String = "pattern";
+	    public static const TYPE:String = "Type";
+	    public static const VALUE_SCHEME:String = "ValueScheme";
+	    public static const ATTRIBUTE:String = "Attribute";
+	    public static const ATTRIBUTE_LIST:String = "AttributeList";
+	    public static const DESCRIPTION:String = "Description";
+        //Attribute Names
+        public static const APP_INFO:String = "AppInfo";
+        public static const NAME:String = "name";
+
+		public var name:String;
+
+
+		private var _xml:XML;
+
+		public function ComponentMD() {
+		}
+
+		public function set xml(xml:XML):void {
+			_xml = xml;
+		}
+
+		public function get xml():XML {
+			return _xml;
+		}
+	}
+   
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Credentials.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Credentials.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Credentials.as	(revision 1843)
@@ -0,0 +1,34 @@
+package clarin.cmdi.componentregistry.common {
+
+	public class Credentials {
+		private static var _instance:Credentials = new Credentials();
+
+		[Bindable]
+		public var userName:String = "";
+
+		public function Credentials() {
+			if (_instance != null) {
+				throw new Error("Config can only be accessed through Credentials.instance");
+			}
+		}
+		
+        public function isLoggedIn():Boolean {
+            return userName && userName != "" && userName != "anonymous";
+        }
+
+		private function init(applicationParameters:Object):void {
+			if (applicationParameters.hasOwnProperty("userName")) {
+				userName = applicationParameters.userName;
+			}
+		}
+
+		public static function create(applicationParameters:Object):void {
+			_instance.init(applicationParameters);
+		}
+
+
+		public static function get instance():Credentials {
+			return _instance;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/DateUtils.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/DateUtils.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/DateUtils.as	(revision 1843)
@@ -0,0 +1,48 @@
+package clarin.cmdi.componentregistry.common
+{
+	import mx.formatters.DateFormatter;
+
+	public class DateUtils
+	{
+		public static function convertDate(dateString:String):Date {
+			var validator:DateFormatter = new DateFormatter();
+			var s:String = parseDate(dateString);
+			var n:Number = Date.parse(s);
+			var registrationDateValue:Date = new Date(n);
+			var result:String;
+			if (isNaN(n)) {
+				trace("cannot convert date: " + dateString);
+				return null;
+			} 
+			return registrationDateValue;
+		}
+		
+		public static function formatDateString(dateString:String):String {
+			var s:String = parseDate(dateString);
+			var n:Number = Date.parse(s);
+			var registrationDateValue:Date = new Date(n);
+			var result:String;
+			if (isNaN(n)) {
+				trace("cannot convert date: " + dateString);
+				result = dateString;
+			} else {
+				result = convertDateToString(registrationDateValue);
+			}
+			return result;
+		}
+		
+		public static function convertDateToString(date:Date):String{
+			var validator:DateFormatter = new DateFormatter();
+			validator.formatString = "DD MMMM YYYY H:NN:SS"; //e.g. 02 December 2009 13:48:39 
+			return validator.format(date);
+		}
+		
+		public static function parseDate(value:String):String {
+			var dateStr:String = value;
+			dateStr = dateStr.replace(/-/g, "/");
+			dateStr = dateStr.replace("T", " ");
+			dateStr = dateStr.replace("+00:00", " GMT-0000");
+			return dateStr;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ItemDescription.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ItemDescription.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ItemDescription.as	(revision 1843)
@@ -0,0 +1,52 @@
+package clarin.cmdi.componentregistry.common {
+	import clarin.cmdi.componentregistry.services.Config;
+
+	[Bindable]
+	public class ItemDescription {
+
+		public var id:String;
+		public var name:String;
+		public var description:String;
+		public var creatorName:String;
+		public var groupName:String;
+		public var domainName:String = "";
+		public var dataUrl:String;
+		public var isProfile:Boolean;
+		public var registrationDate:String;
+		public var registrationDateValue:Date;
+		public var isInUserSpace:Boolean;
+		public var commentsCount:int;
+
+		public function ItemDescription() {
+
+		}
+
+		private function create(itemDescription:XML, infoUrl:String, isProfileValue:Boolean, isInUserSpace:Boolean):void {
+			this.id = itemDescription.id;
+			this.name = itemDescription.name;			
+			this.description = itemDescription.description;
+			this.creatorName = itemDescription.creatorName;
+			this.groupName = itemDescription.groupName;
+			this.domainName = itemDescription.domainName;
+			this.dataUrl = infoUrl + itemDescription.id;
+			this.commentsCount = itemDescription.commentsCount;
+			this.isProfile = isProfileValue;
+			this.isInUserSpace = isInUserSpace;
+			
+			// getting ISO-8601 (GMT/UTC timezone) dates from the server. Need to convert this, flex does not support ISO-8601 times out of the box.
+			this.registrationDateValue = DateUtils.convertDate(itemDescription.registrationDate);
+			if(registrationDateValue){
+				this.registrationDate = DateUtils.convertDateToString(registrationDateValue);
+			}
+		}
+
+		public function createProfile(itemDescription:XML, isInUserSpace:Boolean):void {
+			create(itemDescription, Config.instance.profileInfoUrl, true, isInUserSpace);
+		}
+
+		public function createComponent(itemDescription:XML, isInUserSpace:Boolean):void {
+			create(itemDescription, Config.instance.componentInfoUrl, false, isInUserSpace);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/LabelConstants.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/LabelConstants.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/LabelConstants.as	(revision 1843)
@@ -0,0 +1,64 @@
+package clarin.cmdi.componentregistry.common {
+    import mx.collections.ArrayCollection;
+    
+
+	public class LabelConstants {
+
+		//Label names
+		public static const NAME:String = "Name:";
+		public static const CONCEPTLINK:String = "ConceptLink:";
+		public static const COMPONENT:String = "Component:";
+		public static const COMPONENT_ID:String = "ComponentId:";
+		public static const DESCRIPTION:String = "Description:";
+		public static const CARDINALITY_MIN:String = "Min Occurrences:";
+		public static const CARDINALITY_MAX:String = "Max Occurrences:";
+		public static const CARDINALITY:String = "Number of occurrences:"
+		public static const DOCUMENTATION:String = "Documentation:";
+		public static const DISPLAY_PRIORITY:String = "DisplayPriority:";
+		public static const ATTRIBUTELIST:String = "AttributeList:"
+		public static const ELEMENT:String = "Element:";
+		public static const VALUESCHEME:String = "Type:";
+		public static const GROUP_NAME:String = "Group Name:";
+		public static const DOMAIN_NAME:String = "Domain Name:";
+        public static const DOMAIN_NAME_PROMPT:String = "Select a domain...";
+        public static const MULTILINGUAL:String = "Multilingual:";
+
+		//tooltip
+		public static const DISPLAY_PRIORITY_TOOLTIP:String = "Display preference for external tools, 1 means highest priority. Element with name='Name' or name='Title' is usually a good candidate to set to highest priority. Put the value to on 0 and the attribute will not be added to the element."        
+
+		//Data
+		public static const DOMAIN_NAME_DATA:ArrayCollection = new ArrayCollection([
+		{label: "Anthropological Linguistics", data: "anthropological_linguistics"},
+		{label: "Applied Linguistics", data: "applied_linguistics"},
+		{label: "Cognitive Science", data: "cognitive_science"},
+		{label: "Computational Linguistics", data: "computational_linguistics"},
+		{label: "Discourse Analysis", data: "discourse_analysis"},
+		{label: "Forensic Linguistics", data: "forensic_linguistics"},
+		{label: "General Linguistics", data: "general_linguistics"},
+		{label: "Historical Linguistics", data: "historical_linguistics"},
+		{label: "History of Linguistics", data: "history_of_linguistics"},
+		{label: "Language Acquisition", data: "language_acquisition"},
+		{label: "Language Documentation", data: "language_documentation"},
+		{label: "Lexicography", data: "lexicography"},
+		{label: "Linguistics and Literature", data: "linguistics_and_literature"},
+		{label: "Linguistic Theories", data: "linguistic_theories"},
+		{label: "Mathematical Linguistics", data: "mathematical_linguistics"},
+		{label: "Morphology", data: "morphology"},
+		{label: "Neurolinguistics", data: "neurolinguistics"},
+		{label: "Philosophy of Language", data: "philosophy_of_language"},
+		{label: "Phonetics", data: "phonetics"},
+		{label: "Phonology", data: "phonology"},
+		{label: "Pragmatics", data: "pragmatics"},
+		{label: "Psycholinguistics", data: "psycholinguistics"},
+		{label: "Semantics", data: "semantics"},
+		{label: "Sociolinguistics", data: "sociolinguistics"},
+		{label: "Syntax", data: "syntax"},
+		{label: "Text and Corpus Linguistics", data: "text_and_corpus_linguistics"},
+		{label: "Translating and Interpreting", data: "translating_and_interpreting"},
+		{label: "Typology", data: "typology"},
+		{label: "Writing Systems", data: "writing_systems"},
+		{label: "Other", data: "Other"},
+		{label: "Unknown", data: "Unknown"}]); //TODO PD, Dieter knows what to fill in here!
+			
+ }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Login.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Login.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Login.mxml	(revision 1843)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
+		  xmlns:common="clarin.cmdi.componentregistry.common.components.*"
+		  title="Login"
+		  horizontalScrollPolicy="off"
+		  verticalScrollPolicy="off">
+
+	<mx:Metadata>
+		[Event(name="failed",type="flash.events.Event")]
+	</mx:Metadata>
+
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.services.Config;
+			import mx.managers.PopUpManager;
+
+			public static const FAILED:String = "failed";
+			[Bindable]
+			private var _viewType:String;
+			[Bindable]
+			private var _spaceType:String;
+			[Bindable]
+			private var _itemId:String;
+
+			private function handleCancel(event:MouseEvent):void {
+				PopUpManager.removePopUp(this);
+				dispatchEvent(new Event(FAILED));
+			}
+
+			/**
+			 * viewType or spaceType can be null they will then be ignored.
+			 *
+			 * */
+			public function show(parent:DisplayObject, viewType:String, spaceType:String, itemId:String):void {
+				_viewType = viewType;
+				_spaceType = spaceType;
+			    _itemId = itemId;
+				PopUpManager.addPopUp(this, parent, true);
+				PopUpManager.centerPopUp(this);
+			}
+		]]>
+	</mx:Script>
+
+	<mx:VBox horizontalAlign="center">
+		<mx:Label text="You need to be logged in to do that, click the link to login."/>
+		<common:LoginLabelButton id="login"
+								 scaleX="1.5"
+								 scaleY="1.5"
+								 viewType="{_viewType}"
+								 spaceType="{_spaceType}"
+								 itemId="{_itemId}"/>
+		<mx:Button id="cancelBtn"
+				   label="Cancel"
+				   click="{handleCancel(event);}"/>
+	</mx:VBox>
+
+</mx:Panel>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Profile.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Profile.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/Profile.as	(revision 1843)
@@ -0,0 +1,16 @@
+package clarin.cmdi.componentregistry.common {
+	import mx.collections.ArrayCollection;
+
+    [Bindable]
+	public class Profile {
+	    
+		public var description:ItemDescription;
+		public var components:ArrayCollection;//ComponentMD
+		public var nrOfComponents:int;
+		public var profileSource:XML;
+
+		public function Profile() {
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ShowInfoPopUp.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ShowInfoPopUp.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/ShowInfoPopUp.mxml	(revision 1843)
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
+				xmlns:common="clarin.cmdi.componentregistry.common.components.*"
+				showCloseButton="true"
+				close="cleanUp();"
+				backgroundColor="#DDE3EF"
+				show="checkItem();">
+
+	<mx:Script>
+		<![CDATA[
+		    import clarin.cmdi.componentregistry.services.Config;
+			import mx.managers.PopUpManager;
+			
+			[Bindable]
+			private var item:ItemDescription;
+			[Bindable]
+			private var statusText:String;
+			
+			private function cleanUp():void {
+				PopUpManager.removePopUp(this);
+			}
+			
+			private function checkItem():void {
+			    if (item == null) {
+			        title = "select item first";
+			    } 
+			}
+			
+			public function setItem(item:ItemDescription):void {
+			    this.item = item;
+			    title = "Info for: "+item.name;
+			}
+			
+			private function copyXsdLink():void {
+			    System.setClipboard(xsdLink.text);
+			    status = "copied link";
+			}
+			
+			private function copyBookmarkLink():void {
+			    System.setClipboard(bookmarkLink.text);
+			    status = "copied bookmark";
+			}
+			
+			private function getBookmarkText():String {
+			    if (item.isInUserSpace) {
+			        return "Bookmark link (requires login):";
+			    } else {
+			        return "Bookmark link:";
+			    }
+			}
+
+		]]>
+	</mx:Script>
+
+	<mx:VBox width="100%">
+		<mx:HBox width="100%">
+			<mx:Label text="{getBookmarkText()}" styleName="{StyleConstants.SHOW_INFO_PAGE_LABEL}"/>
+			<common:LinkRenderer id="bookmarkLink" text="{Config.getBookmarkUrl(item)}"/>
+			<mx:Spacer width="100%"/>
+			<mx:Button label="copy to clipboard" toolTip="Click here to copy the url to your clipboard" click="copyBookmarkLink();" />
+		</mx:HBox>
+		<mx:HBox width="100%" visible="{item.isProfile}" includeInLayout="{item.isProfile}">
+			<mx:Label text="Link to xsd: " styleName="{StyleConstants.SHOW_INFO_PAGE_LABEL}"/>
+			<common:LinkRenderer id="xsdLink" text="{Config.getXsdLink(item)}"/>
+			<mx:Spacer width="100%"/>
+			<mx:Button label="copy to clipboard" toolTip="Click here to copy the url to your clipboard" click="copyXsdLink();"/>
+		</mx:HBox>
+	</mx:VBox>
+</mx:TitleWindow>
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/StyleConstants.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/StyleConstants.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/StyleConstants.as	(revision 1843)
@@ -0,0 +1,22 @@
+package clarin.cmdi.componentregistry.common {
+
+	public class StyleConstants {
+		//CSS style constant names
+		public static const XMLBROWSER:String = "xmlBrowser";
+		public static const XMLBROWSER_FIELD:String = "xmlBrowserField";
+		public static const XMLBROWSER_FIELD_VALUE:String = "xmlBrowserValueLabel";
+		public static const XMLBROWSER_HEADER:String = "xmlBrowserHeader";
+		public static const XMLEDITOR_EDIT_FIELD:String = "xmlEditorFieldEditField";
+		public static const EXPANDING_COMPONENT:String = "borderStyles";
+		public static const SHOW_INFO_PAGE_LABEL:String = "showInfoPageLabel";
+		
+
+		//		
+		public static const USER_BORDER_COLOR:String = "#F07048";
+
+		[Embed(source='/assets/images/layer-lower-3.png')]
+		public static const downIcon:Class;
+		[Embed(source='/assets/images/layer-raise-3.png')]
+		public static const upIcon:Class;
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/XmlAble.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/XmlAble.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/XmlAble.as	(revision 1843)
@@ -0,0 +1,7 @@
+package clarin.cmdi.componentregistry.common
+{
+    public interface XmlAble
+    {
+        function toXml():XML;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddAttributeLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddAttributeLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddAttributeLabelButton.as	(revision 1843)
@@ -0,0 +1,23 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+
+	import mx.controls.Label;
+
+	public class AddAttributeLabelButton extends Label {
+		public function AddAttributeLabelButton() {
+			super();
+			text = "+attribute";
+			toolTip = "click to add Attribute";
+			setStyle("color", "green");
+			addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "underline");
+				});
+			addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "none");
+				});
+
+
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddComponentLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddComponentLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddComponentLabelButton.as	(revision 1843)
@@ -0,0 +1,22 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+
+	import mx.controls.Label;
+
+	public class AddComponentLabelButton extends Label {
+		public function AddComponentLabelButton() {
+			super();
+			text = "+component";
+			toolTip = "click to add Component";
+			setStyle("color", "green");
+			addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "underline");
+				});
+			addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "none");
+				});
+
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddElementLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddElementLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/AddElementLabelButton.as	(revision 1843)
@@ -0,0 +1,23 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+	
+	import mx.controls.Label;
+
+	public class AddElementLabelButton extends Label {
+	    
+		public function AddElementLabelButton() {
+			super();
+			text = "+element";
+			toolTip = "click to add Element";
+			setStyle("color", "green");
+			addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "underline");
+				});
+			addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "none");
+				});
+
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BasicLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BasicLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BasicLabelButton.as	(revision 1843)
@@ -0,0 +1,24 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+
+	import mx.controls.Label;
+
+	public class BasicLabelButton extends Label {
+		public function BasicLabelButton(textString:String = null, tooltipString:String = null, color:String = null) {
+			if (textString)
+				text = textString;
+			if (tooltipString)
+				toolTip = tooltipString;
+			if (color)
+				setStyle("color", color);
+			addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "underline");
+				});
+			addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					event.currentTarget.setStyle("textDecoration", "none");
+				});
+
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BrowseContextMenu.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BrowseContextMenu.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/BrowseContextMenu.as	(revision 1843)
@@ -0,0 +1,146 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.ShowInfoPopUp;
+	import clarin.cmdi.componentregistry.services.DeleteService;
+	import clarin.cmdi.componentregistry.services.SaveItemDialog;
+
+	import flash.events.ContextMenuEvent;
+	import flash.geom.Point;
+	import flash.ui.ContextMenu;
+	import flash.ui.ContextMenuItem;
+
+	import mx.controls.Alert;
+	import mx.controls.DataGrid;
+	import mx.events.CloseEvent;
+	import mx.managers.PopUpManager;
+
+
+	public class BrowseContextMenu {
+
+		[Bindable]
+		public var cm:ContextMenu;
+
+		[Bindable]
+		public var viewStack:RegistryViewStack;
+		[Bindable]
+		public var deleteService:DeleteService;
+
+		[Bindable]
+		private var _dataGrid:DataGrid;
+
+		private var saveItemDialog:SaveItemDialog = new SaveItemDialog();
+		private var isComponent:Boolean = false;
+
+		public function BrowseContextMenu(isComponent:Boolean = false) {
+			this.isComponent = isComponent
+			cm = new ContextMenu();
+			cm.hideBuiltInItems();
+			cm.customItems = createMenuItems();
+		}
+
+		private function createMenuItems():Array {
+			var result:Array = new Array();
+			var cmi:ContextMenuItem = new ContextMenuItem("Show info");
+			cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, showInfo);
+			result.push(cmi);
+			cmi = new ContextMenuItem("Download as XML...");
+			cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveAsXml);
+			result.push(cmi);
+			if (!isComponent) {
+				cmi = new ContextMenuItem("Download as XSD...");
+				cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, saveAsXsd);
+				result.push(cmi);
+			}
+			cmi = new ContextMenuItem("Edit Item...");
+			cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, editItem);
+			result.push(cmi);
+			cmi = new ContextMenuItem("Delete Item...", true);
+			cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, handleDelete);
+			result.push(cmi);
+
+			return result;
+		}
+
+		public function set dataGrid(dataGrid:DataGrid):void {
+			_dataGrid = dataGrid;
+		}
+
+
+
+		private function showInfo(event:ContextMenuEvent):void {
+			var item:ItemDescription = _dataGrid.selectedItem as ItemDescription;
+			if (!item) {
+				showSelectAlert();
+				return;
+			}
+			var showInfoPanel:ShowInfoPopUp = new ShowInfoPopUp();
+			showInfoPanel.setItem(item);
+			var point:Point = new Point();
+			point.x = event.mouseTarget.mouseX;
+			point.y = event.mouseTarget.mouseY;
+			point = event.mouseTarget.localToGlobal(point);
+			showInfoPanel.x = point.x;
+			showInfoPanel.y = point.y;
+			PopUpManager.addPopUp(showInfoPanel, event.mouseTarget);
+		}
+
+		private function saveAsXml(event:ContextMenuEvent):void {
+			var item:ItemDescription = _dataGrid.selectedItem as ItemDescription;
+			if (!item) {
+				showSelectAlert();
+				return;
+			}
+			saveItemDialog.saveAsXML(item);
+		}
+
+		private function saveAsXsd(event:ContextMenuEvent):void {
+			var item:ItemDescription = _dataGrid.selectedItem as ItemDescription;
+			if (!item) {
+				showSelectAlert();
+				return;
+			}
+			saveItemDialog.saveAsXSD(item);
+		}
+
+		private function editItem(event:ContextMenuEvent):void {
+			var item:ItemDescription = _dataGrid.selectedItem as ItemDescription;
+			if (!item) {
+			    showSelectAlert();
+			    return;
+			}
+			viewStack.switchToEditor(item);
+		}
+
+		private function showSelectAlert():void {
+			Alert.show("First select a profile or component");
+		}
+
+		private function handleDelete(event:ContextMenuEvent):void {
+   			if (!_dataGrid.selectedItem) {
+			    showSelectAlert();
+			    return;
+			}
+			deleteSelectedItems();
+		}
+
+		public function deleteSelectedItems():void {
+			var message:String = "";
+			for each (var item:ItemDescription in _dataGrid.selectedItems) {
+				if (message != "") {
+					message += "\n";
+				}
+				message += item.name;
+			}
+			Alert.show("You will delete the following item(s):\n" + message + "\n\n This cannot be undone.", "Delete items", Alert.OK | Alert.CANCEL, null, handleDeleteAlert);
+		}
+
+		private function handleDeleteAlert(event:CloseEvent):void {
+			if (event.detail == Alert.OK) {
+				for each (var item:ItemDescription in _dataGrid.selectedItems) {
+					deleteService.deleteItem(item);
+				}
+			}
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/DownIconButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/DownIconButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/DownIconButton.as	(revision 1843)
@@ -0,0 +1,17 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+
+	import mx.controls.Button;
+
+	public class DownIconButton extends Button {
+		public function DownIconButton() {
+			super();
+			setStyle("icon", StyleConstants.downIcon);
+			setStyle("paddingTop", 18);
+			width = 5;
+			height = 0;
+			toolTip = "move down";
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ExpandingComponentLabel.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ExpandingComponentLabel.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ExpandingComponentLabel.as	(revision 1843)
@@ -0,0 +1,124 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.browser.CMDComponentXMLBrowser;
+	import clarin.cmdi.componentregistry.common.CMDSpecRenderer;
+	import clarin.cmdi.componentregistry.common.Component;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.editor.CMDComponentXMLEditor;
+	import clarin.cmdi.componentregistry.editor.model.CMDModelFactory;
+	import clarin.cmdi.componentregistry.services.ComponentInfoService;
+	import clarin.cmdi.componentregistry.services.ComponentListService;
+
+	import flash.display.DisplayObject;
+	import flash.events.MouseEvent;
+
+	import mx.containers.VBox;
+	import mx.controls.Label;
+	import mx.managers.CursorManager;
+
+	public class ExpandingComponentLabel extends VBox {
+
+		[Bindable]
+		public var isExpanded:Boolean = false;
+		private var expandBusy:Boolean = false;
+
+		private var expanded:DisplayObject;
+		private var componentId:String;
+		private var item:ItemDescription;
+		private var componentSrv:ComponentInfoService = new ComponentInfoService();
+
+		private var editable:Boolean;
+
+		public function ExpandingComponentLabel(componentId:String, editable:Boolean = false) {
+			super();
+			this.editable = editable;
+			this.componentId = componentId;
+			this.item = ComponentListService.findDescription(componentId);
+			styleName = StyleConstants.EXPANDING_COMPONENT;
+			if (item && item.isInUserSpace) {
+				this.setStyle("borderColor", StyleConstants.USER_BORDER_COLOR);
+			}
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			var id:Label = new Label();
+			if (item) {
+				id.text = item.name;
+				id.styleName = StyleConstants.XMLBROWSER_HEADER;
+				id.addEventListener(MouseEvent.CLICK, handleClick);
+				id.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
+				id.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
+			} else {
+				id.text = "Component cannot be found (might not exist anymore).";
+			}
+			addChild(id);
+		}
+
+		private function handleClick(event:MouseEvent):void {
+			if (!expandBusy) {
+				expandStart();
+				try {
+					if (isExpanded) {
+						isExpanded = false;
+						unexpand();
+					} else {
+						isExpanded = true;
+						expand();
+					}
+				} catch (err:Error) {
+					trace(err);
+					CursorManager.removeBusyCursor();
+				}
+			}
+		}
+
+		private function expandStart():void {
+			expandBusy = true;
+			CursorManager.setBusyCursor();
+		}
+
+		private function expandFinished():void {
+			expandBusy = false;
+			CursorManager.removeBusyCursor();
+		}
+
+
+		private function unexpand():void {
+			if (expanded != null) {
+				removeChild(expanded);
+				expanded = null;
+			}
+			expandFinished();
+		}
+
+		private function expand():void {
+			componentSrv.addEventListener(ComponentInfoService.COMPONENT_LOADED, handleComponentLoaded);
+			componentSrv.load(item);
+		}
+
+		private function handleComponentLoaded(event:Event):void {
+			var comp:Component = componentSrv.component;
+			if (editable) {
+				expanded = new CMDComponentXMLEditor();
+			} else {
+				expanded = new CMDComponentXMLBrowser();
+			}
+			(expanded as CMDSpecRenderer).cmdSpec = CMDModelFactory.createModel(comp.componentMD.xml, comp.description);
+			addChild(expanded);
+			expandFinished();
+		}
+
+
+		private function mouseOver(event:MouseEvent):void {
+			event.currentTarget.setStyle("color", "0x0000FF");
+			event.currentTarget.setStyle("textDecoration", "underline");
+		}
+
+		private function mouseOut(event:MouseEvent):void {
+			event.currentTarget.setStyle("color", "0x000000");
+			event.currentTarget.setStyle("textDecoration", "none");
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/FilteringDataGrid.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/FilteringDataGrid.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/FilteringDataGrid.as	(revision 1843)
@@ -0,0 +1,74 @@
+package clarin.cmdi.componentregistry.common.components {
+	import com.rictus.controls.SearchBox;
+	
+	import flash.events.Event;
+	
+	import mx.collections.ICollectionView;
+	import mx.controls.DataGrid;
+	import mx.controls.dataGridClasses.DataGridColumn;
+	import mx.core.ClassFactory;
+	import mx.core.IFactory;
+
+	public class FilteringDataGrid extends DataGrid {
+
+		private var _searchText:String = "";
+		private var _searchInput:SearchBox;
+		[Bindable]
+		public var unfilteredLength:int = 0;
+
+        private var highlightSelectionRenderer:IFactory = new ClassFactory(HighlightSelectionItemRenderer);
+
+		public function FilteringDataGrid() {
+			super();
+		}
+		
+		override public function set columns(columns:Array):void {
+		    for each (var column:DataGridColumn in columns) {
+		        column.itemRenderer = highlightSelectionRenderer;
+		    }
+		    super.columns = columns;
+		}
+
+		override public function set dataProvider(dataProvider:Object):void {
+			var data:ICollectionView = dataProvider as ICollectionView;
+			data.filterFunction = filter;
+			unfilteredLength = data.length
+			super.dataProvider = data;
+		}
+
+		public function set searchInput(searchInput:SearchBox):void {
+			_searchInput = searchInput;
+			_searchInput.addEventListener(Event.CHANGE, doFiltering);
+		}
+
+        public function get searchText():String {
+            return _searchText;
+        }
+        
+		public function doFiltering(changeEvent:Event=null):void {
+			_searchText = _searchInput.text;
+			if (columns.length > 0) //Sometimes columns are not set yet resulting in empty list, so do not refresh in this case (only happens on startup).
+			    dataProvider.refresh();
+			validateNow();
+		}
+
+		private function filter(item:Object):Boolean {
+			return findMatchInColumns(item, _searchText);
+		}
+
+		private function findMatchInColumns(item:Object, searchText:String):Boolean {
+			for each (var column:DataGridColumn in columns) {
+				var value:String = item[column.dataField];
+				if (getIndexOfMatch(value, searchText) != -1) {
+					return true; //We have a match so whole row is in, can avoid matching the other columns
+				}
+			}
+			return false;
+		}
+
+		public function getIndexOfMatch(value:String, searchText:String):int {
+			var index:int = value.toLowerCase().indexOf(searchText.toLowerCase());
+			return index;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/HighlightSelectionItemRenderer.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/HighlightSelectionItemRenderer.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/HighlightSelectionItemRenderer.as	(revision 1843)
@@ -0,0 +1,41 @@
+package clarin.cmdi.componentregistry.common.components {
+	import mx.controls.Label;
+
+	public class HighlightSelectionItemRenderer extends Label {
+
+		private static const OPEN_TAG:String = "<b>";
+		private static const CLOSE_TAG:String = "</b>";
+
+
+		public function HighlightSelectionItemRenderer() {
+			super();
+		}
+
+		override public function set text(value:String):void {
+			var highlight:Boolean = false;
+			if (listData && listData.owner is FilteringDataGrid) {
+				var _grid:FilteringDataGrid = listData.owner as FilteringDataGrid;
+				var searchText:String = _grid.searchText;
+				if (searchText != null && searchText.length > 0) {
+					var index:int = _grid.getIndexOfMatch(value, searchText);
+					if (index != -1) {
+						value = highlightMatch(value, searchText.length, index);
+						highlight = true;
+					}
+				}
+			}
+			if (highlight) {
+				super.htmlText = value;
+			} else {
+				super.text = value;
+			}
+		}
+
+		private function highlightMatch(value:String, len:int, index:int):String {
+			return value.substr(0, index).concat(OPEN_TAG, value.substr(index, len), CLOSE_TAG, value.substr(index + len));
+		}
+
+
+	}
+}
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LinkRenderer.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LinkRenderer.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LinkRenderer.mxml	(revision 1843)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" click="linkListener(event)" mouseOver="mouseOver(event)" 
+				mouseOut="mouseOut(event)">
+ 
+	<mx:Script>
+		<![CDATA[
+			private function mouseOver(event:MouseEvent):void {
+			   event.currentTarget.setStyle("color","0x0000FF");
+			   event.currentTarget.setStyle("textDecoration","underline");
+			}
+ 
+			private function mouseOut(event:MouseEvent):void {
+			   event.currentTarget.setStyle("color","0x000000");
+			   event.currentTarget.setStyle("textDecoration","none");
+			}
+ 
+			private function linkListener(event:MouseEvent):void {
+			   var request:URLRequest = 
+				new URLRequest(event.currentTarget.text);
+			   navigateToURL(request, "_blank");
+			}
+		]]>
+	</mx:Script>
+</mx:Label>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LoginLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LoginLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/LoginLabelButton.as	(revision 1843)
@@ -0,0 +1,49 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.services.Config;
+
+	import com.adobe.net.URI;
+
+	import flash.events.MouseEvent;
+	import flash.net.URLRequest;
+	import flash.net.navigateToURL;
+
+	import mx.controls.Label;
+
+	public class LoginLabelButton extends Label {
+
+		[Bindable]
+		public var viewType:String;
+		[Bindable]
+		public var spaceType:String;
+		[Bindable]
+		public var itemId:String;
+
+		public function LoginLabelButton() {
+			super();
+			text = "login";
+			toolTip = "Click to login";
+			setStyle("color", "green");
+			setStyle("textDecoration", "underline")
+			addEventListener(MouseEvent.CLICK, handleLogin);
+		}
+
+		private function handleLogin(event:MouseEvent):void {
+			var req:URLRequest = new URLRequest();
+
+			var uri:URI = new URI(Config.instance.serviceRootUrl);
+			uri.setQueryValue("shhaaDo", "lI");
+			if (viewType) {
+				uri.setQueryValue(Config.REGISTRY_PARAM_VIEW, viewType);
+			}
+			if (spaceType) {
+				uri.setQueryValue(Config.REGISTRY_PARAM_SPACE, spaceType);
+			}
+			if (itemId) {
+				uri.setQueryValue(Config.REGISTRY_PARAM_ITEM, itemId);
+			}
+			req.url = uri.toString();
+			navigateToURL(req, "_top");
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryView.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryView.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryView.as	(revision 1843)
@@ -0,0 +1,7 @@
+package clarin.cmdi.componentregistry.common.components {
+
+
+	public interface RegistryView {
+		function getType():String;
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryViewStack.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryViewStack.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RegistryViewStack.as	(revision 1843)
@@ -0,0 +1,102 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.browser.Browse;
+	import clarin.cmdi.componentregistry.common.Credentials;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.Login;
+	import clarin.cmdi.componentregistry.editor.Editor;
+	import clarin.cmdi.componentregistry.importer.Importer;
+	import clarin.cmdi.componentregistry.services.Config;
+
+	import flash.events.Event;
+
+	import mx.containers.ViewStack;
+	import mx.events.FlexEvent;
+
+	public class RegistryViewStack extends ViewStack {
+		public var browse:Browse = new Browse();
+		private var editor:Editor = new Editor();
+		private var importer:Importer = new Importer();
+
+		private var loginPanel:Login;
+		private var selectedItem:ItemDescription;
+
+		public function RegistryViewStack() {
+			loginPanel = new Login();
+			loginPanel.addEventListener(Login.FAILED, loginFailed);
+			browse.addEventListener(Browse.START_ITEM_LOADED, switchWithStartupItem);
+			addChild(browse); //everyone can browse
+
+			if (!Config.instance.debug) {
+				editor.addEventListener(FlexEvent.SHOW, checkLogin);
+				importer.addEventListener(FlexEvent.SHOW, checkLogin);
+			}
+			addChild(editor);
+			addChild(importer);
+		}
+
+		private function switchWithStartupItem(even:Event):void {
+			var item:ItemDescription = browse.getSelectedStartItem();
+			switchView(Config.instance.view, item);
+		}
+
+		public function loadStartup():void {
+			if (Config.instance.space == Config.SPACE_USER && !Credentials.instance.isLoggedIn()) {
+				checkLogin();
+			} else {
+				if (Config.instance.startupItem) {
+					browse.loadStartup();
+				} else {
+					switchView(Config.instance.view);
+				}
+			}
+		}
+
+		private function switchView(view:String, item:ItemDescription = null):void {
+			if (view == Config.VIEW_BROWSE) {
+				switchToBrowse(item);
+			} else if (view == Config.VIEW_EDIT) {
+				switchToEditor(item);
+			} else if (view == Config.VIEW_IMPORT) {
+				switchToImport();
+			}
+		}
+
+		public function switchToBrowse(itemDescription:ItemDescription):void {
+			if (itemDescription != null) {
+				if (Config.instance.userSpace == itemDescription.isInUserSpace) {
+					browse.refresh();
+				} else {
+					Config.instance.userSpace = itemDescription.isInUserSpace;
+				}
+				browse.setSelectedDescription(itemDescription);
+			}
+			this.selectedItem = itemDescription;
+			this.selectedChild = browse;
+		}
+
+		public function switchToEditor(itemDescription:ItemDescription):void {
+			this.selectedChild = editor;
+			this.selectedItem = itemDescription;
+			editor.setDescription(itemDescription);
+		}
+
+		public function switchToImport():void {
+			this.selectedChild = importer;
+		}
+
+		private function checkLogin(event:Event = null):void {
+			if (!Credentials.instance.isLoggedIn()) {
+				var itemId:String = Config.instance.startupItem;
+				if (selectedItem) {
+					itemId = selectedItem.id;
+				}
+				loginPanel.show(this, RegistryView(this.selectedChild).getType(), Config.instance.space, itemId);
+			}
+		}
+
+		private function loginFailed(event:Event):void {
+			this.selectedChild = browse;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RemoveLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RemoveLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/RemoveLabelButton.as	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+
+	public class RemoveLabelButton extends BasicLabelButton {
+		public function RemoveLabelButton() {
+			super("X", "click to remove", "red");
+		}
+
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ScrollableTextArea.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ScrollableTextArea.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/ScrollableTextArea.as	(revision 1843)
@@ -0,0 +1,39 @@
+package clarin.cmdi.componentregistry.common.components {
+	import flash.events.MouseEvent;
+	
+	import mx.controls.TextArea;
+	import mx.events.ScrollEvent;
+	import mx.events.ScrollEventDirection;
+
+    [Inspectable]
+	public class ScrollableTextArea extends TextArea {
+		public function ScrollableTextArea() {
+			super();
+		}
+
+		/**
+		 * Overrides the handler to be able to scroll, this is only needed for the shiny Macs out there. Implementation copied from mx.core.ScrollControlBase.as
+		 * Use this instead of mx.controls.TextArea
+		 **/
+		override protected function mouseWheelHandler(event:MouseEvent):void {
+			if (verticalScrollBar && verticalScrollBar.visible) {
+				event.stopPropagation();
+
+				var scrollDirection:int = event.delta <= 0 ? 1 : -1;
+
+				// Make sure we scroll by at least one line
+				var scrollAmount:Number = Math.max(Math.abs(event.delta), verticalScrollBar.lineScrollSize);
+
+				// Multiply by 3 to make scrolling a little faster
+				var oldPosition:Number = verticalScrollPosition;
+				verticalScrollPosition += 3 * scrollAmount * scrollDirection;
+
+				var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
+				scrollEvent.direction = ScrollEventDirection.VERTICAL;
+				scrollEvent.position = verticalScrollPosition;
+				scrollEvent.delta = verticalScrollPosition - oldPosition;
+				dispatchEvent(scrollEvent);
+			}
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UpIconButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UpIconButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UpIconButton.as	(revision 1843)
@@ -0,0 +1,18 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.controls.Button;
+
+	public class UpIconButton extends Button {
+		public function UpIconButton() {
+			super();
+			setStyle("icon", StyleConstants.upIcon);
+			setStyle("paddingTop", 15);
+			setStyle("paddingLeft", 18);
+			width = 5;
+			height = 0;
+			toolTip = "move up";
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UserSettingsLabelButton.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UserSettingsLabelButton.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/common/components/UserSettingsLabelButton.as	(revision 1843)
@@ -0,0 +1,36 @@
+package clarin.cmdi.componentregistry.common.components {
+	import clarin.cmdi.componentregistry.services.Config;
+
+	import com.adobe.net.URI;
+
+	import flash.events.MouseEvent;
+	import flash.net.URLRequest;
+	import flash.net.navigateToURL;
+
+	import mx.controls.Label;
+
+	public class UserSettingsLabelButton extends Label {
+
+		[Bindable]
+		public var viewType:String;
+		[Bindable]
+		public var spaceType:String;
+		[Bindable]
+		public var itemId:String;
+
+		public function UserSettingsLabelButton() {
+			super();
+			text = "settings";
+			toolTip = "Click for user settings";
+			setStyle("color", "green");
+			setStyle("textDecoration", "underline")
+			addEventListener(MouseEvent.CLICK, handleClick);
+		}
+
+		private function handleClick(event:MouseEvent):void {
+			var req:URLRequest = new URLRequest(Config.instance.userSettingsUrl);
+			navigateToURL(req, "_blank");
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/AttributeListEdit.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/AttributeListEdit.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/AttributeListEdit.as	(revision 1843)
@@ -0,0 +1,165 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.AddAttributeLabelButton;
+	import clarin.cmdi.componentregistry.common.components.RemoveLabelButton;
+	import clarin.cmdi.componentregistry.editor.model.CMDAttribute;
+	import clarin.cmdi.componentregistry.editor.model.ValueSchemeInterface;
+	
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.binding.utils.ChangeWatcher;
+	import mx.collections.ArrayCollection;
+	import mx.containers.Form;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.Label;
+	import mx.core.UIComponent;
+	import mx.events.PropertyChangeEvent;
+
+	[Event(name="removeAttribute", type="flash.events.Event")]
+	public class AttributeListEdit extends Form {
+		private static const ATTRIBUTE_CHANGE_EVENT:String = "attributeChange";
+
+		private var _attributes:ArrayCollection;
+		private var _parent:UIComponent;
+		private var noAttributesLabel:Label = new Label();
+		[Bindable]
+		public var hasNoAttributes:Boolean = true;
+		private var addAttributeLabelButton:AddAttributeLabelButton;
+
+		public function AttributeListEdit(attributes:ArrayCollection, parent:UIComponent) {
+			super();
+			_attributes = attributes;
+			hasNoAttributes = _attributes.length == 0;
+			_parent = parent;
+			styleName = StyleConstants.XMLBROWSER;
+			noAttributesLabel.text = "No Attributes";
+			BindingUtils.bindProperty(noAttributesLabel, "visible", this, "hasNoAttributes");
+			noAttributesLabel.styleName = StyleConstants.XMLBROWSER_FIELD_VALUE;
+		}
+
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(createHeading());
+			if (_attributes.length > 0) {
+				for each (var attribute:CMDAttribute in _attributes) {
+					addAttribute(createAttributeBox(attribute));
+				}
+			}
+			addAttributeButton();
+		}
+
+		private function addAttributeButton():void {
+			addAttributeLabelButton = new AddAttributeLabelButton();
+			addAttributeLabelButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+					var attr:CMDAttribute = CMDAttribute.createEmptyAttribute();
+					_attributes.addItem(attr);
+					hasNoAttributes = _attributes.length == 0;
+					addAttribute(createAttributeBox(attr));
+				});
+			addAttributeLabelButton.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					drawFocus(true);
+				});
+			addAttributeLabelButton.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					drawFocus(false);
+				});
+			addChild(addAttributeLabelButton);
+		}
+
+		private function createAttributeBox(attribute:CMDAttribute):Form {
+			var attributeBox:Form = new Form();
+			attributeBox.styleName = StyleConstants.XMLBROWSER;
+			addEditBar(attribute, attributeBox);
+			attributeBox.addChild(createAndAddValueScheme(attribute));
+			
+			attributeBox.addChild(new ConceptLinkInput(LabelConstants.CONCEPTLINK, attribute.conceptLink, function(val:String):void {
+				attribute.conceptLink = val;
+			}));
+			
+			return attributeBox;
+		}
+
+		private function addAttribute(attributeBox:Form):void {
+			if (!addAttributeLabelButton) {
+				addChild(attributeBox);
+			} else {
+				addChildAt(attributeBox, getChildIndex(addAttributeLabelButton));
+			}
+
+		}
+
+		/**
+		 * Public utility method to create ValueScheme Component. By lack of better placed put in this class
+		 **/
+		public static function createAndAddValueScheme(valueScheme:ValueSchemeInterface):UIComponent {
+			var valueSchemeInput:ValueSchemeInput = new ValueSchemeInput(LabelConstants.VALUESCHEME);
+			if (valueScheme.valueSchemeEnumeration == null) {
+				if (valueScheme.valueSchemePattern) {
+					valueSchemeInput.valueSchemePattern = valueScheme.valueSchemePattern;
+				} else {
+					valueSchemeInput.valueSchemeSimple = valueScheme.valueSchemeSimple;
+				}
+			} else {
+				valueSchemeInput.valueSchemeEnumeration = valueScheme.valueSchemeEnumeration;
+			}
+			ChangeWatcher.watch(valueSchemeInput, "valueSchemeSimple", function(e:PropertyChangeEvent):void {
+					valueScheme.valueSchemeSimple = e.newValue as String;
+					valueScheme.valueSchemePattern = "";
+					valueScheme.valueSchemeEnumeration = null;
+				});
+			ChangeWatcher.watch(valueSchemeInput, "valueSchemePattern", function(e:PropertyChangeEvent):void {
+					valueScheme.valueSchemePattern = e.newValue as String;
+					valueScheme.valueSchemeEnumeration = null;
+					valueScheme.valueSchemeSimple = "";
+				});
+			ChangeWatcher.watch(valueSchemeInput, "valueSchemeEnumeration", function(e:PropertyChangeEvent):void {
+					valueScheme.valueSchemeEnumeration = e.newValue as ArrayCollection;
+					valueScheme.valueSchemeSimple = "";
+					valueScheme.valueSchemePattern = "";
+				});
+			return valueSchemeInput;
+		}
+
+		private function addEditBar(attribute:CMDAttribute, attributeBox:Form):void {
+			var name:NameInputLine = new NameInputLine(attribute.name, function(val:String):void {
+					attribute.name = val;
+				}, InputValidators.getNameValidator());
+			name.direction = FormItemDirection.HORIZONTAL
+			var removeButton:Label = new RemoveLabelButton();
+			removeButton.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+					attributeBox.drawFocus(false);
+					removeAttribute(attribute);
+					removeChild(attributeBox);
+				});
+			removeButton.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					attributeBox.drawFocus(true);
+				});
+			removeButton.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					attributeBox.drawFocus(false);
+				});
+			attributeBox.addChild(name);
+			name.addChild(removeButton);
+		}
+
+		private function removeAttribute(attribute:CMDAttribute):void {
+			var index:int = _attributes.getItemIndex(attribute);
+			if (index != -1) {
+				_attributes.removeItemAt(index);
+			}
+			hasNoAttributes = _attributes.length == 0;
+		}
+
+		private function createHeading():FormItem {
+			var heading:FormItem = new FormItem();
+			heading.label = LabelConstants.ATTRIBUTELIST;
+			heading.styleName = StyleConstants.XMLBROWSER_HEADER;
+			heading.addChild(noAttributesLabel);
+			return heading;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDComponentXMLEditor.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDComponentXMLEditor.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDComponentXMLEditor.as	(revision 1843)
@@ -0,0 +1,346 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.CMDSpecRenderer;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.AddComponentLabelButton;
+	import clarin.cmdi.componentregistry.common.components.AddElementLabelButton;
+	import clarin.cmdi.componentregistry.common.components.RemoveLabelButton;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	import clarin.cmdi.componentregistry.editor.model.CMDSpec;
+	import clarin.cmdi.componentregistry.services.IsocatService;
+	
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	import flash.utils.Dictionary;
+	import flash.utils.getTimer;
+	
+	import mx.collections.ArrayCollection;
+	import mx.containers.Form;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.Label;
+	import mx.controls.Spacer;
+	import mx.core.Container;
+	import mx.core.UIComponent;
+	import mx.events.ChildExistenceChangedEvent;
+	import mx.events.DragEvent;
+	import mx.managers.DragManager;
+	import mx.managers.IFocusManagerComponent;
+
+	[Event(name="editorChange", type="flash.events.Event")]
+	public class CMDComponentXMLEditor extends Form implements IFocusManagerComponent, CMDSpecRenderer {
+
+		public static const DRAG_NEW_COMPONENT:String = "newComponent";
+		public static const DRAG_NEW_ELEMENT:String = "newElement";
+		public static const DRAG_NEW_ATTRIBUTE:String = "newAttribute";
+		private static const DRAG_ITEMS:String = "items";
+
+		public static const EDITOR_CHANGE_EVENT:String = "editorChange";
+
+		private var _spec:CMDSpec;
+		private var _firstComponent:CMDComponent;
+		private var addComponentLabel:Label
+		private var addElementLabel:Label
+
+
+		public function CMDComponentXMLEditor() {
+			super();
+			focusEnabled = true;
+			tabEnabled = true;
+			styleName = StyleConstants.XMLBROWSER;
+			addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
+			addEventListener(DragEvent.DRAG_OVER, dragOverHandler);
+			addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
+			addEventListener(ChildExistenceChangedEvent.CHILD_ADD, dispatchEditorChangeEvent);
+			addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, dispatchEditorChangeEvent);
+		}
+
+		public function validate():Boolean {
+			var componentDisplayPrioMap:Dictionary = new Dictionary(true);
+			componentDisplayPrioMap[this] = new ArrayCollection();
+			var result:Boolean = validateChildren(getChildren(), componentDisplayPrioMap, this);
+			result = validateDisplayPriorityFields(componentDisplayPrioMap) && result;
+			return result;
+		}
+
+		private function validateChildren(children:Array, componentDisplayPrioMap:Dictionary, key:Object):Boolean {
+			var result:Boolean = true;
+			for each (var o:Object in children) {
+				if (o is CMDValidator) {
+					var validatorResult : Boolean = CMDValidator(o).validate();
+					if(!validatorResult){
+						CMDValidator(o).validate();
+					}
+					result = validatorResult && result;
+				}
+				if (o is Container) {
+					var newKey:Object = key;
+					if (o is ComponentEdit) {
+						componentDisplayPrioMap[o] = new ArrayCollection();
+						newKey = o;
+					}
+					result = validateChildren(Container(o).getChildren(), componentDisplayPrioMap, newKey) && result;
+					if (o is DisplayPriorityInput) {
+						componentDisplayPrioMap[newKey].addItem(o);
+					}
+				}
+			}
+			return result;
+		}
+
+		private function validateDisplayPriorityFields(componentDisplayPrioMap:Dictionary):Boolean {
+			var result:Boolean = true;
+			for (var key:Object in componentDisplayPrioMap) {
+				var displayPrioritySet:Boolean = false;
+				var displayPriorityFields:ArrayCollection = componentDisplayPrioMap[key];
+				for each (var input:DisplayPriorityInput in displayPriorityFields) { // get values
+					if (input.getValue() > 0) {
+						displayPrioritySet = true;
+						break;
+					}
+				}
+				for each (var inputF:DisplayPriorityInput in displayPriorityFields) { // set results
+					if (displayPrioritySet) {
+						result = inputF.validate(input.getValue()) && result;
+					} else {
+						result = inputF.validate(null) && result;
+					}
+				}
+			}
+			return result;
+		}
+
+		private function dragEnterHandler(event:DragEvent):void {
+			DragManager.acceptDragDrop(event.currentTarget as UIComponent);
+			UIComponent(event.currentTarget).drawFocus(true);
+		}
+
+
+		private function dragOverHandler(event:DragEvent):void {
+			if (event.dragSource.hasFormat(DRAG_ITEMS)) {
+				DragManager.showFeedback(DragManager.COPY);
+			} else {
+				DragManager.showFeedback(DragManager.NONE);
+			}
+		}
+
+		private function dragDropHandler(event:DragEvent):void {
+			if (event.dragSource.hasFormat(DRAG_ITEMS)) {
+				var items:Array = event.dragSource.dataForFormat(DRAG_ITEMS) as Array;
+				for each (var item:ItemDescription in items) {
+					var comp:CMDComponent = new CMDComponent();
+					comp.componentId = item.id;
+					_firstComponent.cmdComponents.addItem(comp);
+					addComponent(comp);
+				}
+			}
+		}
+
+		public function set cmdSpec(cmdSpec:CMDSpec):void {
+			_spec = cmdSpec;
+			createNewEditor();
+			dispatchEditorChangeEvent();
+		}
+
+		private function dispatchEditorChangeEvent(event:Event = null):void {
+			dispatchEvent(new Event(EDITOR_CHANGE_EVENT));
+		}
+
+		[Bindable]
+		public function get cmdSpec():CMDSpec {
+			return _spec;
+		}
+
+		private function createNewEditor():void {
+			var start:int = getTimer();
+			addComponentLabel = null
+			addElementLabel = null
+			removeAllChildren();
+			checkFirstDefiningComponent(_spec.cmdComponents);
+			handleHeader(_spec);
+			handleElements(_firstComponent.cmdElements);
+			addElementAddButton();
+			handleComponents(_firstComponent.cmdComponents);
+			addComponentAddButton();
+			trace("Created editor view in " + (getTimer() - start) + " ms.");
+		}
+
+		private function clearEditor(event:Event):void {
+			if (_spec && !_spec.isProfile) {
+				cmdSpec = CMDSpec.createEmptyComponent();
+			} else {
+				cmdSpec = CMDSpec.createEmptyProfile();
+			}
+			dispatchEditorChangeEvent();
+		}
+
+		/**
+		 * The xml model allows more component to be defined but we force only one component at the "root" level.
+		 */
+		private function checkFirstDefiningComponent(components:ArrayCollection):void {
+			if (components.length != 1) {
+				throw new Error("A profile/component must have 1 component defined at root level.");
+			} else {
+				_firstComponent = components.getItemAt(0) as CMDComponent;
+				if (_firstComponent.componentId != "" && _firstComponent.componentId != null) {
+					_firstComponent = new CMDComponent();
+					_firstComponent.name = _spec.headerName;
+					_firstComponent.cmdComponents = _spec.cmdComponents;
+					_spec.cmdComponents = new ArrayCollection();
+					_spec.cmdComponents.addItem(_firstComponent);
+				}
+			}
+		}
+
+		private function handleHeader(spec:CMDSpec):void {
+			var head:FormItem = new FormItem();
+			head.direction = FormItemDirection.HORIZONTAL;
+			var buttons:FormItem = new SelectTypeRadioButtons(spec);
+			head.addChild(buttons);
+			var startOverLabel:Label = createStartOverButton();
+			startOverLabel.setStyle("paddingTop", "2");
+			startOverLabel.height = buttons.height;
+			var space:Spacer = new Spacer();
+			space.width = 55;
+			head.addChild(space);
+			head.addChild(startOverLabel);
+			addChild(head);
+			
+			var nameInput:NameInputLine = new NameInputLine(_firstComponent.name, function(val:String):void {
+					_firstComponent.name = val;
+					_spec.headerName = val;
+				}, InputValidators.getNameValidator());
+			addChild(nameInput);
+			
+			var groupNameInput:FormItemInputLine = new FormItemInputLine(LabelConstants.GROUP_NAME, spec.groupName, function(val:String):void {
+					spec.groupName = val;
+				}); // editable, not required
+			addChild(groupNameInput);
+			
+			var descriptionInput:FormItemInputText = new FormItemInputText(LabelConstants.DESCRIPTION, spec.headerDescription, function(val:String):void {
+					spec.headerDescription = val;
+				}, InputValidators.getIsRequiredValidator()); //editable, required
+			addChild(descriptionInput);
+			
+			var domainInput:ComboBoxInputLine = new ComboBoxInputLine(LabelConstants.DOMAIN_NAME, _spec.domainName, LabelConstants.DOMAIN_NAME_DATA, LabelConstants.DOMAIN_NAME_PROMPT, function(val:Object):void {
+					if (val) {
+						_spec.domainName = val.data;
+					}
+				}); // editable, not required
+			addChild(domainInput);
+
+//			var idInput:FormItemInputLine = new FormItemInputLine(XMLBrowser:"Id", spec.headerId, function(val:String):void {
+//					spec.headerId = val;
+//				}, false);
+//			idInput.toolTip = "Id will be generated";
+//			addChild(idInput);
+			var link:ConceptLinkInput = new ConceptLinkInput(LabelConstants.CONCEPTLINK, _firstComponent.conceptLink, function(val:String):void {
+					_firstComponent.conceptLink = val;
+				}, IsocatService.TYPE_CONTAINER);
+			addChild(link);
+			
+			addChild(new AttributeListEdit(_firstComponent.attributeList, this))
+		}
+
+		private function addComponentAddButton():void {
+			addComponentLabel = new AddComponentLabelButton();
+			addComponentLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+					var comp:CMDComponent = CMDComponent.createEmptyComponent();
+					_firstComponent.cmdComponents.addItem(comp);
+					addComponent(comp);
+
+				});
+			addComponentLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					drawFocus(true);
+				});
+			addComponentLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					drawFocus(false);
+				});
+			addChild(addComponentLabel);
+		}
+
+		private function addElementAddButton():void {
+			addElementLabel = new AddElementLabelButton();
+			addElementLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+					var element:CMDComponentElement = CMDComponentElement.createEmptyElement();
+					_firstComponent.cmdElements.addItem(element);
+					addElement(element);
+
+				});
+			addElementLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					drawFocus(true);
+				});
+			addElementLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					drawFocus(false);
+				});
+			addChild(addElementLabel);
+		}
+
+		/* private function createOptionalGroupNameInput(spec:CMDSpec):FormItem {
+		   var result:FormItemInputLine = new FormItemInputLine(LabelConstants.GROUP_NAME, spec.groupName, function(val:String):void {
+		   spec.groupName = val;
+		   }, true, InputValidators.getIsRequiredValidator());
+		   BindingUtils.bindSetter(function(val:Boolean):void {
+		   result.visible = !val;
+		   }, spec, "isProfile");
+		   return result;
+		 }  */
+
+		private function handleComponents(components:ArrayCollection):void {
+			for each (var component:CMDComponent in components) {
+				addComponent(component);
+			}
+		}
+
+		public function addComponent(component:CMDComponent):void {
+			var comp:Container = new ComponentEdit(component, this, _firstComponent);
+			comp.addEventListener(ComponentEdit.REMOVE_COMPONENT_EVENT, removeComponent);
+			if (!addComponentLabel) {
+				addChild(comp);
+			} else {
+				addChildAt(comp, getChildIndex(addComponentLabel)); //Add components at the place of the button so button moves down
+			}
+		}
+
+		private function removeComponent(event:Event):void {
+			var comp:CMDComponent = ComponentEdit(event.currentTarget).component;
+			_firstComponent.removeComponent(comp);
+			removeChild(event.currentTarget as DisplayObject);
+		}
+
+
+		private function handleElements(elements:ArrayCollection):void {
+			for each (var element:CMDComponentElement in elements) {
+				addElement(element);
+			}
+		}
+
+		public function addElement(element:CMDComponentElement):void {
+			var elem:Container = new ElementEdit(element, this, _firstComponent);
+			elem.setStyle("paddingLeft", "50");
+			elem.addEventListener(ElementEdit.REMOVE_ELEMENT_EVENT, removeElement);
+			if (!addElementLabel) {
+				addChild(elem);
+			} else {
+				addChildAt(elem, getChildIndex(addElementLabel));
+			}
+		}
+
+		private function removeElement(event:Event):void {
+			var elem:CMDComponentElement = ElementEdit(event.currentTarget).element;
+			_firstComponent.removeElement(elem);
+			removeChild(event.currentTarget as DisplayObject);
+		}
+
+		private function createStartOverButton():Label {
+			var startOverButton:Label = new RemoveLabelButton();
+			startOverButton.addEventListener(MouseEvent.CLICK, clearEditor);
+			startOverButton.toolTip = "Clears all input and removes added components";
+			startOverButton.text = "start over";
+			return startOverButton;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDValidator.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDValidator.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CMDValidator.as	(revision 1843)
@@ -0,0 +1,7 @@
+package clarin.cmdi.componentregistry.editor
+{
+    public interface CMDValidator
+    {
+        function validate():Boolean;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CardinalityInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CardinalityInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CardinalityInput.as	(revision 1843)
@@ -0,0 +1,43 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+
+	import mx.binding.utils.BindingUtils;
+	import mx.collections.ArrayCollection;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.ComboBox;
+
+	public class CardinalityInput extends FormItem {
+		private var numericList:ComboBox = new ComboBox();
+
+		private static var cardinalityData:ArrayCollection = createCardinalityData();
+
+		private static function createCardinalityData():ArrayCollection {
+			var result:ArrayCollection = new ArrayCollection([{label: "unbounded", data: "unbounded"}]);
+			for (var i:int = 0; i < 10; i++) {
+				result.addItem({label: i, data: i});
+			}
+			return result;
+		}
+
+		public function CardinalityInput(name:String, value:String, bindingFunction:Function, editable:Boolean = true) {
+			super();
+			label = name;
+			direction = FormItemDirection.HORIZONTAL;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			BindingUtils.bindSetter(bindingFunction, numericList, "text");
+			numericList.width = 300;
+			numericList.editable = true;
+			numericList.prompt = value;
+			numericList.toolTip = "Pick a value or type any number";
+			numericList.dataProvider = cardinalityData;
+		}
+
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(numericList);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CheckboxInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CheckboxInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/CheckboxInput.as	(revision 1843)
@@ -0,0 +1,31 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.collections.ArrayCollection;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.CheckBox;
+	import mx.controls.ComboBox;
+
+	public class CheckboxInput extends FormItem {
+		private var checkbox:CheckBox = new CheckBox();
+
+		public function CheckboxInput(name:String, value:Boolean, bindingFunction:Function) {
+			super();
+			label = name;
+			direction = FormItemDirection.HORIZONTAL;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			BindingUtils.bindSetter(bindingFunction, checkbox, "selected");
+			checkbox.width = 300;
+			checkbox.selected = value;
+		}
+
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(checkbox);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ChildNameValidator.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ChildNameValidator.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ChildNameValidator.as	(revision 1843)
@@ -0,0 +1,67 @@
+package clarin.cmdi.componentregistry.editor
+{
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	
+	import mx.events.ValidationResultEvent;
+	import mx.validators.RegExpValidator;
+	import mx.validators.ValidationResult;
+	
+	public class ChildNameValidator extends RegExpValidator
+	{
+		private var _parentComponent:CMDComponent;
+		private var _childObject:Object;
+		private var unique:Boolean;
+
+		public function ChildNameValidator(parentComponent:CMDComponent, childObject:Object)
+		{
+			_parentComponent = parentComponent;
+			_childObject = childObject;
+			
+			expression = "^[A-Za-z0-9_\-]+$";
+			required = true;
+			noMatchError = "Name can only contain A-Z, a-z, 0-9, or _";
+		}
+		
+		override protected function doValidation(value:Object):Array{
+			var validatorResults:Array = new Array();
+			validatorResults = super.doValidation(value);
+			
+			unique = true;
+			if(_parentComponent){						
+				var name:String = String(value);
+				if(_childObject != null){
+					for each (var component:CMDComponent in _parentComponent.cmdComponents) {
+						if(component != _childObject && component.name == name){
+							unique = false;
+							validatorResults = new Array();
+							validatorResults.push(new ValidationResult(true,null,"Duplicate component name","Name must be unqiue among siblings"));
+							return validatorResults;
+						}
+					}
+					for each (var element:CMDComponentElement in _parentComponent.cmdElements) {
+						if(element != _childObject && element.name == name){
+							unique = false;
+							validatorResults = new Array();
+							validatorResults.push(new ValidationResult(true,null,"Duplicate element name","Name must be unqiue among siblings"));
+							return validatorResults;
+						}
+					}
+				}
+			}
+			
+			return validatorResults; 
+		}
+		
+		override protected function handleResults(errorResults:Array):ValidationResultEvent{
+			var result:ValidationResultEvent = super.handleResults(errorResults);
+			if(result.type == ValidationResultEvent.VALID){
+				if(!unique){
+					result = new ValidationResultEvent(ValidationResultEvent.INVALID);
+					result.results = errorResults;
+				}
+			}
+			return result;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComboBoxInputLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComboBoxInputLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComboBoxInputLine.as	(revision 1843)
@@ -0,0 +1,36 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.collections.ArrayCollection;
+	import mx.containers.FormItem;
+	import mx.controls.ComboBox;
+
+	public class ComboBoxInputLine extends FormItem {
+
+		public var box:ComboBox = new ComboBox();
+
+
+		public function ComboBoxInputLine(name:String, value:String, dataProvider:ArrayCollection, prompt:String, bindingFunction:Function) {
+			super();
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			box.width = 300;
+			box.dataProvider = dataProvider;
+			box.selectedIndex = -1;
+			if (!value) {
+			    box.prompt = prompt;
+			} else {
+			    box.prompt = value;
+			}
+			BindingUtils.bindSetter(bindingFunction, box, "selectedItem");
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(box);
+		}
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComponentEdit.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComponentEdit.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ComponentEdit.as	(revision 1843)
@@ -0,0 +1,294 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.AddComponentLabelButton;
+	import clarin.cmdi.componentregistry.common.components.AddElementLabelButton;
+	import clarin.cmdi.componentregistry.common.components.DownIconButton;
+	import clarin.cmdi.componentregistry.common.components.ExpandingComponentLabel;
+	import clarin.cmdi.componentregistry.common.components.RemoveLabelButton;
+	import clarin.cmdi.componentregistry.common.components.UpIconButton;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	
+	import flash.display.DisplayObject;
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	
+	import mx.collections.ArrayCollection;
+	import mx.containers.Form;
+	import mx.containers.FormItem;
+	import mx.containers.HBox;
+	import mx.controls.Button;
+	import mx.controls.HRule;
+	import mx.controls.Label;
+	import mx.core.Container;
+	import mx.core.UIComponent;
+	import mx.events.DragEvent;
+	import mx.managers.DragManager;
+	
+	[Event(name="removeComponent", type="flash.events.Event")]
+	public class ComponentEdit extends Form {
+		public static const REMOVE_COMPONENT_EVENT:String = "removeComponent";
+		private static const DRAG_ITEMS:String = "items";
+		
+		private var _parent:UIComponent;
+		private var _component:CMDComponent;
+		private var _parentComponent:CMDComponent;
+		private var addComponentLabel:Label
+		private var addElementLabel:Label
+		
+		
+		public function ComponentEdit(component:CMDComponent, parent:UIComponent, parentComponent:CMDComponent) {
+			super();
+			_component = component;
+			_parentComponent = parentComponent;
+			_parent = parent;
+			styleName = StyleConstants.XMLBROWSER;
+			if (!component.componentId) { // new empty component, otherwise it would be an already existed component which cannot be edited.
+				addEventListener(DragEvent.DRAG_ENTER, dragEnterHandler);
+				addEventListener(DragEvent.DRAG_OVER, dragOverHandler);
+				addEventListener(DragEvent.DRAG_DROP, dragDropHandler);
+			}
+		}
+		
+		public function get component():CMDComponent {
+			return _component;
+		}
+		
+		public function get parentComponent():CMDComponent {
+			return _parentComponent;
+		}
+		
+		private function dragEnterHandler(event:DragEvent):void {
+			DragManager.acceptDragDrop(event.currentTarget as UIComponent);
+			UIComponent(event.currentTarget).drawFocus(true);
+		}
+		
+		
+		private function dragOverHandler(event:DragEvent):void {
+			if (event.dragSource.hasFormat(DRAG_ITEMS)) {
+				DragManager.showFeedback(DragManager.COPY);
+			} else {
+				DragManager.showFeedback(DragManager.NONE);
+			}
+		}
+		
+		private function dragDropHandler(event:DragEvent):void {
+			if (event.dragSource.hasFormat(DRAG_ITEMS)) {
+				var items:Array = event.dragSource.dataForFormat(DRAG_ITEMS) as Array;
+				for each (var item:ItemDescription in items) {
+					var comp:CMDComponent = new CMDComponent();
+					comp.componentId = item.id;
+					_component.cmdComponents.addItem(comp);
+					addComponent(comp);
+				}
+			}
+		}
+		
+		private function fireRemoveComponent(mouseEvent:MouseEvent):void {
+			drawFocus(false);
+			var event:Event = new Event(REMOVE_COMPONENT_EVENT);
+			dispatchEvent(event);
+		}
+		
+		protected override function createChildren():void {
+			super.createChildren();
+			addRuler();
+			createComponentEditBar();
+			
+			var componentLink:FormItem = createComponentLink(_component);
+			if (componentLink != null) {
+				addCardinalityInput();
+				addChild(componentLink);
+			} else {
+				addNameInput();
+				addConceptLink();
+				addCardinalityInput();
+				handleCMDAttributeList();
+				handleElements(_component.cmdElements);
+				addElementAddButton();
+				handleComponents(_component.cmdComponents); //recursion
+				addComponentAddButton();
+			}
+		}
+		
+		private function addComponentAddButton():void {
+			addComponentLabel = new AddComponentLabelButton();
+			addComponentLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+				var comp:CMDComponent = CMDComponent.createEmptyComponent();
+				_component.cmdComponents.addItem(comp);
+				addComponent(comp);
+			});
+			addComponentLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+				drawFocus(true);
+			});
+			addComponentLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+				drawFocus(false);
+			});
+			addChild(addComponentLabel);
+		}
+		
+		private function addElementAddButton():void {
+			addElementLabel = new AddElementLabelButton();
+			addElementLabel.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
+				var element:CMDComponentElement = CMDComponentElement.createEmptyElement();
+				_component.cmdElements.addItem(element);
+				addElement(element);
+				
+			});
+			addElementLabel.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+				drawFocus(true);
+			});
+			addElementLabel.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+				drawFocus(false);
+			});
+			addChild(addElementLabel);
+		}
+		
+		private function addConceptLink():void {
+			addChild(new ConceptLinkInput(LabelConstants.CONCEPTLINK, _component.conceptLink, function(val:String):void {
+				_component.conceptLink = val;
+			}));
+		}
+		
+		private function addRuler():void {
+			var ruler:HRule = new HRule();
+			ruler.percentWidth = 80;
+			addChild(ruler);
+		}
+		
+		private function addNameInput():void {
+			var nameInput:FormItemInputLine = new NameInputLine(_component.name, function(val:String):void {
+				_component.name = val;	
+			}, new ChildNameValidator(_parentComponent, component));
+			addChild(nameInput);
+		}
+		
+		private function addCardinalityInput():void {
+			addChild(new CardinalityInput(LabelConstants.CARDINALITY_MIN, _component.cardinalityMin, function(val:String):void {
+				_component.cardinalityMin = val;
+			}));
+			addChild(new CardinalityInput(LabelConstants.CARDINALITY_MAX, _component.cardinalityMax, function(val:String):void {
+				_component.cardinalityMax = val;
+			}));
+		}
+		
+		private function createComponentEditBar():void {
+			var editBar:HBox = new HBox();
+			editBar.addChild(createHeading());
+			var removeButton:Label = new RemoveLabelButton();
+			addFocusListeners(removeButton).addEventListener(MouseEvent.CLICK, fireRemoveComponent);
+			editBar.addChild(removeButton);
+			
+			var downButton:Button = new DownIconButton();
+			addFocusListeners(downButton).addEventListener(MouseEvent.CLICK, moveDownComponent);
+			editBar.addChild(downButton);
+			
+			var upButton:Button = new UpIconButton();
+			addFocusListeners(upButton).addEventListener(MouseEvent.CLICK, moveUpComponent);
+			editBar.addChild(upButton);
+			addChild(editBar);
+		}
+		
+		private function moveDownComponent(event:Event):void {
+			var comp:CMDComponent = component;
+			if (parentComponent.moveDownComponent(comp)) {
+				var index:int = _parent.getChildIndex(this);
+				if (index != _parent.numChildren - 1) {
+					_parent.removeChild(this);
+					_parent.addChildAt(this, index + 1);
+				}
+			}
+		}
+		
+		private function moveUpComponent(event:Event):void {
+			var comp:CMDComponent = component;
+			if (parentComponent.moveUpComponent(comp)) {
+				var index:int = _parent.getChildIndex(this);
+				if (index != 0) {
+					_parent.removeChild(this);
+					_parent.addChildAt(this, index - 1);
+				}
+			}
+		}
+		
+		private function addFocusListeners(comp:UIComponent):UIComponent {
+			comp.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+				drawFocus(true);
+			});
+			comp.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+				drawFocus(false);
+			});
+			return comp;
+		}
+		
+		private function createComponentLink(component:CMDComponent):FormItem {
+			if (component.componentId != "" && component.componentId != null) {
+				var result:FormItem = new FormItem();
+				result.styleName = StyleConstants.XMLBROWSER_FIELD;
+				result.label = LabelConstants.COMPONENT_ID;
+				result.addChild(new ExpandingComponentLabel(component.componentId, false));
+				return result;
+			}
+			return null;
+		}
+		
+		private function handleCMDAttributeList():void {
+			addChild(new AttributeListEdit(_component.attributeList, this));
+		}
+		
+		private function handleComponents(components:ArrayCollection):void {
+			for each (var component:CMDComponent in components) {
+				addComponent(component);
+			}
+		}
+		
+		public function addComponent(component:CMDComponent):void {
+			var comp:Container = new ComponentEdit(component, this, _component);
+			comp.addEventListener(ComponentEdit.REMOVE_COMPONENT_EVENT, removeComponent);
+			comp.setStyle("paddingLeft", "50");
+			if (!addComponentLabel) {
+				addChild(comp);
+			} else {
+				addChildAt(comp, getChildIndex(addComponentLabel));
+			}
+		}
+		
+		private function removeComponent(event:Event):void {
+			var comp:CMDComponent = ComponentEdit(event.currentTarget).component;
+			_component.removeComponent(comp);
+			removeChild(event.currentTarget as DisplayObject);
+		}
+		
+		private function handleElements(elements:ArrayCollection):void {
+			for each (var element:CMDComponentElement in elements) {
+				addElement(element);
+			}
+		}
+		
+		public function addElement(element:CMDComponentElement):void {
+			var elem:Container = new ElementEdit(element, this, _component);
+			elem.setStyle("paddingLeft", "50");
+			elem.addEventListener(ElementEdit.REMOVE_ELEMENT_EVENT, removeElement);
+			if (!addElementLabel) {
+				addChild(elem);
+			} else {
+				addChildAt(elem, getChildIndex(addElementLabel));
+			}
+		}
+		
+		private function removeElement(event:Event):void {
+			var elem:CMDComponentElement = ElementEdit(event.currentTarget).element;
+			_component.removeElement(elem);
+			removeChild(event.currentTarget as DisplayObject);
+		}
+		
+		private function createHeading():FormItem {
+			var heading:FormItem = new FormItem();
+			heading.label = LabelConstants.COMPONENT;
+			heading.styleName = StyleConstants.XMLBROWSER_HEADER;
+			return heading;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ConceptLinkInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ConceptLinkInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ConceptLinkInput.as	(revision 1843)
@@ -0,0 +1,65 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.services.IsocatService;
+	
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.Button;
+	import mx.controls.TextInput;
+	import mx.managers.PopUpManager;
+	
+	public class ConceptLinkInput extends FormItem {
+		
+		private var editField:TextInput = new TextInput();
+		private var searchConceptLink:Button = new Button();
+		private var isocatPopup:IsocatSearchPopUp;
+		private var conceptType:String;
+		
+		public function ConceptLinkInput(name:String, value:String, bindingFunction:Function, conceptType:String = null) {
+			super();
+			direction = FormItemDirection.HORIZONTAL;
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			editField.styleName = StyleConstants.XMLEDITOR_EDIT_FIELD;
+			editField.width = 300;
+			editField.text = value;
+			BindingUtils.bindSetter(bindingFunction, editField, "text");
+			createSearchConceptLinkButton();
+			editField.addEventListener(Event.CHANGE, function():void {
+				editField.toolTip = null
+			});
+			this.conceptType = conceptType;
+		}
+		
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(editField);
+			addChild(searchConceptLink);
+		}
+		
+		private function createSearchConceptLinkButton():void {
+			searchConceptLink.label = "Search in isocat...";
+			searchConceptLink.addEventListener(MouseEvent.CLICK, handleButtonClick);
+		}
+		
+		private function getIsocatPopup():IsocatSearchPopUp {
+			if (!isocatPopup) {
+				isocatPopup = EditorManager.getIsocatSearchPopUp(conceptType);
+				isocatPopup.addEventListener(IsocatSearchPopUp.OK_EVENT, function(e:Event):void {
+					editField.text = isocatPopup.editField.text;
+					editField.toolTip = isocatPopup.editField.toolTip;
+				});
+			}
+			return isocatPopup;
+		}
+		
+		private function handleButtonClick(event:MouseEvent):void {
+			PopUpManager.addPopUp(getIsocatPopup(), this.parent, false);
+		}
+		
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/DisplayPriorityInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/DisplayPriorityInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/DisplayPriorityInput.as	(revision 1843)
@@ -0,0 +1,36 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+
+	import mx.binding.utils.BindingUtils;
+	import mx.events.ValidationResultEvent;
+	import mx.validators.Validator;
+
+	public class DisplayPriorityInput extends NumericStepperInputLine {
+		private var _validator:Validator;
+
+		public function DisplayPriorityInput(name:String, value:String, bindingFunction:Function) {
+			super(name, value, bindingFunction);
+			toolTip = LabelConstants.DISPLAY_PRIORITY_TOOLTIP;
+			_validator = InputValidators.getIsRequiredValidator();
+			_validator.listener = this.editField;
+			_validator.requiredFieldError = "At least one element should have it's displayPriority set to 1 or higher.";
+		}
+
+		public function getValue():Number {
+			return editField.value;
+		}
+
+		/**
+		 * Validate with given input because the DisplayPriority is a global setting 
+		 * which needs to be checked outside this class
+		 **/
+		public function validate(value:Object):Boolean {
+			if (_validator && this.visible) {
+				var result:ValidationResultEvent = _validator.validate(value);
+				return result.type == ValidationResultEvent.VALID;
+			}
+			return true;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/Editor.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/Editor.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/Editor.mxml	(revision 1843)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
+		   xmlns:browser="clarin.cmdi.componentregistry.browser.*"
+		   xmlns:common="clarin.cmdi.componentregistry.common.*"
+		   xmlns:editor="clarin.cmdi.componentregistry.editor.*"
+		   width="100%"
+		   height="100%"
+		   label="Edit..."
+		   creationComplete="init()"
+		   implements="clarin.cmdi.componentregistry.common.components.RegistryView"
+		   >
+	
+	<mx:Script source="EditorAS.as"/>
+	
+	<mx:VBox width="100%" height="100%">
+		
+		<mx:VBox width="100%" minHeight="30">
+			<editor:EditorButtonBar id="buttonBar"
+									width="100%"
+									height="25"
+									saveClick="saveSpec(true, UploadService.UPDATE)"
+									saveAsNewClick="saveSpec(true, UploadService.NEW)"
+									publishClick="publishSpec()"/>
+			<mx:Text id="errorMessageField"
+					 text="{uploadService.message}"
+					 visible='{errorMessageField.text != ""}'
+					 includeInLayout='{errorMessageField.text != ""}'/>
+			<mx:ProgressBar id="uploadProgress"
+							label=""
+							mode="manual"
+							visible="false"
+							includeInLayout="false"/>
+		</mx:VBox>
+		
+		<mx:VDividedBox width="100%" height="100%" verticalScrollPolicy="off">
+			<mx:VBox width="100%" height="60%">
+				<editor:CMDComponentXMLEditor id="xmlEditor"
+											  cmdSpec="{cmdSpec}"
+											  editorChange="handleEditorChange(event)"
+											  width="100%"
+											  />
+			</mx:VBox>
+			
+			<mx:VBox styleName="borderStyles" width="100%" height="40%">
+				<mx:Label text="Drag existing components onto edit canvas"/>
+				<browser:BrowserOverviewList id="componentsPaletteOverview"
+											 width="100%" height="90%"
+											 browserDataProvider="{componentsSrv.itemDescriptions}"
+											 browserColumns="{browserColumns.getComponentColumns()}"
+											 creationComplete="initPaletteOverview();"/>
+			</mx:VBox>
+			
+		</mx:VDividedBox>
+	</mx:VBox>
+	
+</mx:Canvas>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorAS.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorAS.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorAS.as	(revision 1843)
@@ -0,0 +1,173 @@
+// ActionScript file
+import clarin.cmdi.componentregistry.browser.BrowserColumns;
+import clarin.cmdi.componentregistry.common.ItemDescription;
+import clarin.cmdi.componentregistry.editor.model.CMDModelFactory;
+import clarin.cmdi.componentregistry.editor.model.CMDSpec;
+import clarin.cmdi.componentregistry.importer.UploadCompleteEvent;
+import clarin.cmdi.componentregistry.services.ComponentInfoService;
+import clarin.cmdi.componentregistry.services.ComponentListService;
+import clarin.cmdi.componentregistry.services.ComponentUsageCheckEvent;
+import clarin.cmdi.componentregistry.services.ComponentUsageService;
+import clarin.cmdi.componentregistry.services.Config;
+import clarin.cmdi.componentregistry.services.ProfileInfoService;
+import clarin.cmdi.componentregistry.services.UploadService;
+
+import flash.events.Event;
+
+import mx.controls.Alert;
+import mx.events.CloseEvent;
+import mx.managers.CursorManager;
+
+
+private var profileSrv:ProfileInfoService = new ProfileInfoService();
+private var componentSrv:ComponentInfoService = new ComponentInfoService();
+private var itemDescription:ItemDescription;
+
+[Bindable]
+private var componentsSrv:ComponentListService = ComponentListService.getInstance(Config.instance.userSpace);
+
+[Bindable]
+public var cmdComponent:XML;
+
+[Bindable]
+private var cmdSpec:CMDSpec;
+
+[Bindable]
+private var browserColumns:BrowserColumns = new BrowserColumns();
+
+[Bindable]
+private var uploadService:UploadService = new UploadService();
+
+
+public function init():void {
+	cmdSpec  = CMDSpec.createEmptyProfile();
+	profileSrv.addEventListener(ProfileInfoService.PROFILE_LOADED, profileLoaded);
+	componentSrv.addEventListener(ComponentInfoService.COMPONENT_LOADED, componentLoaded);
+	uploadService.addEventListener(UploadCompleteEvent.UPLOAD_COMPLETE, handleSaveComplete);
+	uploadService.init(uploadProgress);
+	Config.instance.addEventListener(Config.USER_SPACE_TOGGLE_EVENT, toggleUserSpace);
+}
+
+private function toggleUserSpace(event:Event):void {
+	componentsSrv = ComponentListService.getInstance(Config.instance.userSpace);
+}
+
+private function determineSaveButtonEnabled():void {
+	buttonBar.saveBtn.enabled = (itemDescription != null && itemDescription.isInUserSpace && null != itemDescription.id && null != xmlEditor.cmdSpec.headerId); 
+}
+
+private function profileLoaded(event:Event):void {
+	var cmdComponent:XML = profileSrv.profile.profileSource;
+	this.cmdSpec = CMDModelFactory.createModel(cmdComponent, profileSrv.profile.description);
+	determineSaveButtonEnabled();
+	CursorManager.removeBusyCursor();
+}
+
+private function componentLoaded(event:Event):void {
+	var cmdComponent:XML = componentSrv.component.componentMD.xml;
+	this.cmdSpec = CMDModelFactory.createModel(cmdComponent, componentSrv.component.description);
+	determineSaveButtonEnabled();
+	CursorManager.removeBusyCursor();
+}
+
+
+public function setDescription(itemDescription:ItemDescription):void {
+	if (itemDescription) {
+		this.itemDescription = itemDescription;
+		CursorManager.setBusyCursor();
+		if (itemDescription.isProfile) {
+			profileSrv.load(itemDescription);
+		} else {
+			componentSrv.load(itemDescription);
+		}
+		buttonBar.saveBtn.enabled = false;
+	}
+}
+
+private function publishSpec():void {
+	Alert.show("If your profile/component is ready to be used by other people press ok, otherwise press cancel and save it in your workspace or continue editing.", "Publish", Alert.OK | Alert.CANCEL, null, handlePublishAlert);
+}
+
+private function handlePublishAlert(event:CloseEvent):void {
+	if (event.detail == Alert.OK) {
+		saveSpec(false, UploadService.PUBLISH);
+	}
+}
+
+private function saveSpec(inUserSpace:Boolean, uploadAction:int):void {
+	//	Alert.show(xmlEditor.cmdSpec.toXml());
+	if (xmlEditor.validate()) {
+		var item:ItemDescription = new ItemDescription();
+		item.description = xmlEditor.cmdSpec.headerDescription;
+		item.name = xmlEditor.cmdSpec.headerName;
+		item.isProfile = xmlEditor.cmdSpec.isProfile;
+		item.groupName = xmlEditor.cmdSpec.groupName;
+		item.domainName = xmlEditor.cmdSpec.domainName;
+		item.isInUserSpace = inUserSpace;
+		if (itemDescription && itemDescription.isInUserSpace) {
+			item.id = xmlEditor.cmdSpec.headerId;
+		}
+		
+		// Private components that are in updated require usage check call. If in use, the user can choose whether or not to save the changes .
+		if(inUserSpace && uploadAction == UploadService.UPDATE && !item.isProfile){
+			checkUsage(item, inUserSpace);
+		}else{
+			doUpload(uploadAction,item);
+		}
+	} else {
+		errorMessageField.text = "Validation errors: red colored fields are invalid.";
+	}
+}
+
+/**
+ * Calls usage check for the specified component. If in use, asks user whether to proceed; if positive, initiates update.
+ */
+private function checkUsage(item:ItemDescription, inUserSpace:Boolean = true, uploadAction:int = UploadService.UPDATE):void{
+	var componentUsageService:ComponentUsageService = new ComponentUsageService(item,inUserSpace);
+	componentUsageService.addEventListener(ComponentUsageCheckEvent.COMPONENT_IN_USE, 
+		function (event:ComponentUsageCheckEvent):void{
+			if(event.isComponentInUse){
+				var messageBody:String = "The component you are about to save is used by the following component(s) and/or profile(s):\n\n";
+				for each(var name:String in event.itemUsingComponent){
+					messageBody += " - " + name + "\n";
+				}
+				messageBody += "\nChanges in this component will affect the above. Do you want to proceed?";
+				Alert.show(messageBody,"Component is used", Alert.YES|Alert.NO,null,
+					function (eventObj:CloseEvent):void{
+						if(eventObj.detail == Alert.YES){
+							doUpload(uploadAction, item);
+						}
+					});
+			} else {
+				doUpload(uploadAction,item);
+			}
+		});
+	componentUsageService.checkUsage();
+}
+
+private function doUpload(uploadAction:int, item:ItemDescription):void{
+	uploadService.upload(uploadAction, item, xmlEditor.cmdSpec.toXml());
+}
+
+private function handleSaveComplete(event:UploadCompleteEvent):void {
+	setDescription(event.itemDescription);
+	parentApplication.viewStack.switchToBrowse(event.itemDescription);
+}
+
+
+private function handleEditorChange(event:Event):void {
+	errorMessageField.text = "";
+	uploadProgress.visible = false;
+	uploadProgress.includeInLayout = false;
+	determineSaveButtonEnabled();
+}
+
+private function initPaletteOverview():void {
+	componentsPaletteOverview.dataGrid.dragEnabled = true;
+	componentsPaletteOverview.dataGrid.allowMultipleSelection = true;
+	componentsPaletteOverview.dataGrid.resizableColumns = true;
+}
+
+public function getType():String {
+	return Config.VIEW_EDIT;
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorButtonBar.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorButtonBar.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorButtonBar.mxml	(revision 1843)
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
+		 width="400"
+		 height="40"
+		 >
+	<mx:Metadata>
+		[Event(name="saveClick", type="flash.events.MouseEvent")]
+		[Event(name="saveAsNewClick", type="flash.events.MouseEvent")]
+		[Event(name="publishClick", type="flash.events.MouseEvent")]
+	</mx:Metadata>
+	<mx:Button id="saveBtn"
+			   label="save"
+			   click="dispatchEvent(new MouseEvent('saveClick'))"
+			   enabled="false"
+			   />
+	<mx:Button id="saveAsNewBtn"
+			   label="save as new"
+			   click="dispatchEvent(new MouseEvent('saveAsNewClick'))"/>
+	<mx:Button id="publishBtn"
+			   label="publish in public space"
+			   click="dispatchEvent(new MouseEvent('publishClick'))"/>
+</mx:HBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorManager.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorManager.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/EditorManager.as	(revision 1843)
@@ -0,0 +1,22 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.services.IsocatService;
+
+
+	/**
+	 * Manages static Editor components
+	 *
+	 **/
+	public final class EditorManager {
+
+		/**
+		 * Specify isocatSearchType see IsocatService. default is null which means search in all types
+		 **/
+		public static function getIsocatSearchPopUp(isocatSearchType:String = null):IsocatSearchPopUp {
+			var isocatSearchPopUp:IsocatSearchPopUp = new IsocatSearchPopUp();
+			isocatSearchPopUp.searchService = new IsocatService();
+			isocatSearchPopUp.isocatSearchType = isocatSearchType;
+			return isocatSearchPopUp;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ElementEdit.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ElementEdit.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ElementEdit.as	(revision 1843)
@@ -0,0 +1,156 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.common.components.DownIconButton;
+	import clarin.cmdi.componentregistry.common.components.RemoveLabelButton;
+	import clarin.cmdi.componentregistry.common.components.UpIconButton;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponent;
+	import clarin.cmdi.componentregistry.editor.model.CMDComponentElement;
+	
+	import flash.events.Event;
+	import flash.events.MouseEvent;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.containers.Form;
+	import mx.containers.FormItem;
+	import mx.containers.HBox;
+	import mx.controls.Button;
+	import mx.controls.Label;
+	import mx.core.Container;
+	import mx.core.UIComponent;
+
+	[Event(name="removeElement", type="flash.events.Event")]
+	public class ElementEdit extends Form {
+		public static const REMOVE_ELEMENT_EVENT:String = "removeElement";
+		private var _element:CMDComponentElement;
+		private var _parentComponent:CMDComponent;
+		private var _parent:UIComponent;
+
+		public function ElementEdit(element:CMDComponentElement, parent:UIComponent, parentComponent:CMDComponent) {
+			super();
+			this._element = element;
+			this._parentComponent = parentComponent;
+			this._parent = parent;
+			styleName = StyleConstants.XMLBROWSER;
+		}
+
+		public function get element():CMDComponentElement {
+			return _element;
+		}
+
+		public function get parentComponent():CMDComponent {
+			return _parentComponent;
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(createEditBar());
+			addNameInput();
+			addChild(new ConceptLinkInput(LabelConstants.CONCEPTLINK, _element.conceptLink, function(val:String):void {
+					_element.conceptLink = val;
+				}));
+			addChild(new FormItemInputLine(LabelConstants.DOCUMENTATION, _element.documentation, function(val:String):void {
+					_element.documentation = val;
+				}));
+			addChild(new DisplayPriorityInput(LabelConstants.DISPLAY_PRIORITY, _element.displayPriority, function(val:String):void {
+					_element.displayPriority = val;
+				}));
+			addChild(new CardinalityInput(LabelConstants.CARDINALITY_MIN, _element.cardinalityMin, function(val:String):void {
+					_element.cardinalityMin = val;
+				}));
+			addChild(new CardinalityInput(LabelConstants.CARDINALITY_MAX, _element.cardinalityMax, function(val:String):void {
+					_element.cardinalityMax = val;
+				}));
+			addChild(AttributeListEdit.createAndAddValueScheme(_element));
+			var multiLingualCheck:CheckboxInput = new CheckboxInput(LabelConstants.MULTILINGUAL, _element.multilingual == "true", function(val:Boolean):void {
+					_element.multilingual = String(val);
+				});
+			multiLingualCheck.toolTip = "Can the value of this element be in multiple languages?";
+			BindingUtils.bindSetter(function(val:String):void {
+					var show:Boolean = "string" == val;
+					multiLingualCheck.visible = show;
+					multiLingualCheck.includeInLayout = show;
+					if (!show) {
+						_element.multilingual = null;
+					}
+				}, _element, "valueSchemeSimple");
+
+			addChild(multiLingualCheck);
+			handleCMDAttributeList();
+		}
+
+		private function createEditBar():HBox {
+			var editBar:HBox = new HBox();
+			editBar.addChild(createHeading());
+			var removeButton:Label = new RemoveLabelButton();
+			addFocusListeners(removeButton).addEventListener(MouseEvent.CLICK, fireRemoveComponent);
+			editBar.addChild(removeButton);
+
+			var downButton:Button = new DownIconButton();
+			addFocusListeners(downButton).addEventListener(MouseEvent.CLICK, moveDownElement);
+			editBar.addChild(downButton);
+
+			var upButton:Button = new UpIconButton();
+			addFocusListeners(upButton).addEventListener(MouseEvent.CLICK, moveUpElement);
+			editBar.addChild(upButton);
+			return editBar;
+		}
+
+		private function moveDownElement(event:Event):void {
+			var elem:CMDComponentElement = element;
+			if (parentComponent.moveDownElement(elem)) {
+				var index:int = _parent.getChildIndex(this);
+				if (index != numChildren - 1) {
+					_parent.removeChild(this);
+					_parent.addChildAt(this, index + 1);
+				}
+			}
+		}
+
+		private function moveUpElement(event:Event):void {
+			var elem:CMDComponentElement = element;
+			if (parentComponent.moveUpElement(elem)) {
+				var index:int = _parent.getChildIndex(this);
+				if (index != 0) {
+					_parent.removeChild(this);
+					_parent.addChildAt(this, index - 1);
+				}
+			}
+		}
+
+		private function addFocusListeners(comp:UIComponent):UIComponent {
+			comp.addEventListener(MouseEvent.MOUSE_OVER, function(event:MouseEvent):void {
+					drawFocus(true);
+				});
+			comp.addEventListener(MouseEvent.MOUSE_OUT, function(event:MouseEvent):void {
+					drawFocus(false);
+				});
+			return comp;
+		}
+
+		private function fireRemoveComponent(mouseEvent:MouseEvent):void {
+			drawFocus(false);
+			var event:Event = new Event(REMOVE_ELEMENT_EVENT);
+			dispatchEvent(event);
+		}
+
+		private function handleCMDAttributeList():void {
+			var attributeEdit:Container = new AttributeListEdit(_element.attributeList, this);
+			addChild(attributeEdit);
+		}
+
+		private function createHeading():FormItem {
+			var heading:FormItem = new FormItem();
+			heading.label = LabelConstants.ELEMENT;
+			heading.styleName = StyleConstants.XMLBROWSER_HEADER;
+			return heading;
+		}
+
+		private function addNameInput():void {
+			var nameInput:NameInputLine = new NameInputLine(_element.name, function(val:String):void {
+					_element.name = val;
+			}, new ChildNameValidator(_parentComponent, element));
+			addChild(nameInput);
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputLine.as	(revision 1843)
@@ -0,0 +1,45 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.containers.FormItem;
+	import mx.controls.TextInput;
+	import mx.events.ValidationResultEvent;
+	import mx.validators.Validator;
+
+	public class FormItemInputLine extends FormItem implements CMDValidator {
+
+		public var editField:TextInput = new TextInput();
+
+		private var _validator:Validator;
+
+		public function FormItemInputLine(name:String, value:String, bindingFunction:Function, editable:Boolean = true, validator:Validator = null) {
+			super();
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			editField.styleName = StyleConstants.XMLEDITOR_EDIT_FIELD;
+			editField.width = 300;
+			editField.text = value;
+			editField.editable = editable;
+			BindingUtils.bindSetter(bindingFunction, editField, "text");
+			if (validator) {
+				_validator = validator;
+				_validator.listener = this.editField;
+			}
+		}
+
+		public function validate():Boolean {
+			if (_validator && this.visible) {
+				var result:ValidationResultEvent = _validator.validate(this.editField.text);
+				return result.type == ValidationResultEvent.VALID;
+			}
+			return true;
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(editField);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputText.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputText.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/FormItemInputText.as	(revision 1843)
@@ -0,0 +1,44 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.containers.FormItem;
+	import mx.controls.TextArea;
+	import mx.events.FlexEvent;
+	import mx.events.ValidationResultEvent;
+	import mx.validators.Validator;
+
+	public class FormItemInputText extends FormItem implements CMDValidator{
+
+		private var editArea:TextArea = new TextArea();
+		private var _validator:Validator;
+
+		public function FormItemInputText(name:String, value:String, bindingFunction:Function, validator:Validator = null) {
+			super();
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			editArea.styleName = StyleConstants.XMLEDITOR_EDIT_FIELD;
+			editArea.width = 300;
+			editArea.text = value;
+			BindingUtils.bindSetter(bindingFunction, editArea, "text");
+			if (validator) {
+			    _validator = validator;
+			    _validator.listener = this.editArea;
+			}
+		}
+
+		public function validate():Boolean {
+			if (_validator && this.visible) {
+				var result:ValidationResultEvent = _validator.validate(this.editArea.text);
+				return result.type == ValidationResultEvent.VALID;
+			}
+			return true;
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(editArea);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/InputValidators.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/InputValidators.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/InputValidators.as	(revision 1843)
@@ -0,0 +1,25 @@
+package clarin.cmdi.componentregistry.editor {
+	import mx.validators.RegExpValidator;
+	import mx.validators.Validator;
+
+
+	public final class InputValidators {
+		public function InputValidators() {
+		}
+
+		public static function getNameValidator():RegExpValidator {
+			var result:RegExpValidator = new RegExpValidator();
+			result.expression = "^[A-Za-z0-9_\-]+$";
+			result.required = true;
+			result.noMatchError = "Name can only contain A-Z, a-z, 0-9, or _";
+			return result;
+		}
+		
+		public static function getIsRequiredValidator():Validator {
+			var result:Validator = new Validator();
+			result.required = true;
+			return result;
+		}
+		
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/IsocatSearchPopUp.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/IsocatSearchPopUp.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/IsocatSearchPopUp.mxml	(revision 1843)
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
+				xmlns:rictus="com.rictus.controls.*"
+				showCloseButton="true"
+				creationComplete="PopUpManager.centerPopUp(this)"
+				close="cleanUp();"
+				title="Search in Isocat.org">
+
+	<mx:Metadata>
+		[Event(name="OK", type="flash.events.Event")]
+	</mx:Metadata>
+	<mx:Script>
+		<![CDATA[
+			import mx.controls.TextInput;
+			import clarin.cmdi.componentregistry.services.IsocatService;
+			import mx.managers.PopUpManager;
+
+			public static const OK_EVENT:String = "OK";
+
+			[Bindable]
+			public var searchService:IsocatService = null;
+
+			public var isocatSearchType:String = null;
+
+			//To store the result
+			public var editField:TextInput;
+
+			private function handleOkClick():void {
+				dispatchEvent(new Event(OK_EVENT));
+				cleanUp();
+			}
+
+			private function cleanUp():void {
+				searchService.close();
+				PopUpManager.removePopUp(this);
+			}
+
+			private function initializeDataGrid():void {
+				editField = new TextInput();
+			}
+
+			private function setItem():void {
+				var selectedItem:XML = dataGrid.selectedItem as XML;
+				if (selectedItem) {
+					editField.text = selectedItem.@pid;
+					editField.toolTip = selectedItem.@name + ": " + selectedItem.@definition;
+				}
+			}
+
+			private function handleSearch(event:KeyboardEvent):void {
+				if (event.keyCode == Keyboard.ENTER) {
+					searchService.load(searchBox.text, isocatSearchType);
+				}
+			}
+		]]>
+	</mx:Script>
+
+	<mx:VBox>
+		<mx:HBox>
+			<rictus:SearchBox id="searchBox"
+							  label="type keyword and press 'enter' to search"
+							  keyDown="handleSearch(event);"
+							  minWidth="300"/>
+			<mx:Label text="{dataGrid.dataProvider.length} results"/>
+		</mx:HBox>
+		<mx:DataGrid id="dataGrid"
+					 dataProvider="{searchService.searchResults}"
+					 initialize="initializeDataGrid()"
+					 itemClick="setItem()"
+					 resizableColumns="true"
+					 itemRenderer="mx.controls.Label"
+					 showDataTips="true">
+			<mx:columns>
+				<mx:DataGridColumn dataField="@name"
+								   dataTipField="@name"
+								   headerText="Name"/>
+				<mx:DataGridColumn dataField="@definition"
+								   dataTipField="@definition"
+								   headerText="Definition"/>
+				<mx:DataGridColumn dataField="@identifier"
+								   dataTipField="@identifier"
+								   headerText="Identifier"/>
+				<mx:DataGridColumn dataField="@owner"
+								   dataTipField="@owner"
+								   headerText="Owner"/>
+				<mx:DataGridColumn dataField="@pid"
+								   dataTipField="@pid"
+								   headerText="Persistent Identifier"
+								   width="130"
+								   itemRenderer="clarin.cmdi.componentregistry.common.components.LinkRenderer"/>
+				<mx:DataGridColumn dataField="@type"
+								   dataTipField="@type"
+								   headerText="Type"/>
+				<mx:DataGridColumn dataField="@version"
+								   dataTipField="@version"
+								   headerText="Version"/>
+			</mx:columns>
+		</mx:DataGrid>
+		<mx:HBox width="100%">
+			<mx:Spacer width="100%"/>
+			<mx:Button id="okBtn"
+					   label="OK"
+					   click="handleOkClick()"/>
+			<mx:Button label="Cancel"
+					   click="cleanUp()"/>
+		</mx:HBox>
+	</mx:VBox>
+</mx:TitleWindow>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NameInputLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NameInputLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NameInputLine.as	(revision 1843)
@@ -0,0 +1,16 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.LabelConstants;
+	
+	import mx.events.ValidationResultEvent;
+	import mx.validators.Validator;
+
+	public class NameInputLine extends FormItemInputLine {
+
+		private var validator:Validator;
+
+		public function NameInputLine(value:String, bindingFunction:Function, validator:Validator=null) {
+			super(LabelConstants.NAME, value, bindingFunction, true, validator);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NumericStepperInputLine.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NumericStepperInputLine.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/NumericStepperInputLine.as	(revision 1843)
@@ -0,0 +1,29 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	
+	import mx.binding.utils.BindingUtils;
+	import mx.containers.FormItem;
+	import mx.controls.NumericStepper;
+
+	public class NumericStepperInputLine extends FormItem {
+		protected var editField:NumericStepper = new NumericStepper();
+
+
+		public function NumericStepperInputLine(name:String, value:String, bindingFunction:Function) {
+			super();
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			editField.styleName = StyleConstants.XMLEDITOR_EDIT_FIELD;
+			editField.width = 300;
+			editField.value = Number(value);
+			editField.maximum = 10;
+			BindingUtils.bindSetter(bindingFunction, editField, "value");
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(editField);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/SelectTypeRadioButtons.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/SelectTypeRadioButtons.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/SelectTypeRadioButtons.as	(revision 1843)
@@ -0,0 +1,51 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+	import clarin.cmdi.componentregistry.editor.model.CMDSpec;
+	
+	import flash.events.MouseEvent;
+	
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.ButtonLabelPlacement;
+	import mx.controls.Label;
+	import mx.controls.RadioButton;
+
+	public class SelectTypeRadioButtons extends FormItem {
+
+		private var _spec:CMDSpec;
+
+		public function SelectTypeRadioButtons(spec:CMDSpec) {
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			_spec = spec;
+			direction = FormItemDirection.HORIZONTAL;
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			var isProfileButton:RadioButton = new RadioButton();
+			isProfileButton.groupName = "selectType";
+			isProfileButton.label = "Profile";
+			isProfileButton.selected = _spec.isProfile;
+			isProfileButton.labelPlacement = ButtonLabelPlacement.LEFT;
+			isProfileButton.addEventListener(MouseEvent.CLICK, handleIsProfile);
+			addChild(isProfileButton);
+
+			var isComponentButton:RadioButton = new RadioButton();
+			isComponentButton.groupName = "selectType";
+			isComponentButton.label = "Component";
+			isComponentButton.selected = !_spec.isProfile;
+			isComponentButton.labelPlacement = ButtonLabelPlacement.LEFT;
+			isComponentButton.addEventListener(MouseEvent.CLICK, handleIsComponent);
+			addChild(isComponentButton);
+		}
+
+		private function handleIsProfile(event:MouseEvent):void {
+			_spec.isProfile = true;
+		}
+
+		private function handleIsComponent(event:MouseEvent):void {
+			_spec.isProfile = false;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeEnumerationGrid.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeEnumerationGrid.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeEnumerationGrid.mxml	(revision 1843)
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
+	<mx:Script>
+		<![CDATA[
+			import mx.binding.utils.BindingUtils;
+			import mx.core.IDataRenderer;
+			import mx.controls.Button;
+			import mx.events.ListEvent;
+			import mx.events.DataGridEventReason;
+			import clarin.cmdi.componentregistry.common.ComponentMD;
+			import mx.collections.XMLListCollection;
+			import mx.controls.TextInput;
+			import mx.events.DataGridEvent;
+			import mx.collections.ArrayCollection;
+			import mx.managers.PopUpManager;
+
+			private static const ADD_ROW:String = "Click to add a row";
+
+			[Bindable]
+			public var valueSchemeEnumeration:ArrayCollection = new ArrayCollection();
+			[Bindable]
+			public var conceptLinkEdit:Boolean = false;
+			private var currentEditPosition:Object;
+
+			public function initEnumeration(valueSchemeData:ArrayCollection):void {
+				if (valueSchemeData) {
+					for each (var item:ValueSchemeItem in valueSchemeData) {
+						valueSchemeEnumeration.addItem(item);
+					}
+				}
+				valueSchemeEnumeration.addItem(new ValueSchemeItem(ADD_ROW, "", ""));
+			}
+
+			private function editEnd(e:DataGridEvent):void {
+				if (e.rowIndex == valueSchemeEnumeration.length - 1 && e.columnIndex == 0 && e.reason != DataGridEventReason.CANCELLED) {
+					var row:Object = valueSchemeEnumeration.getItemAt(valueSchemeEnumeration.length - 1);
+					var input:Object = TextInput(e.currentTarget.itemEditorInstance);
+					if (row.item == ADD_ROW && input.text != ADD_ROW) {
+						valueSchemeEnumeration.addItem(new ValueSchemeItem(ADD_ROW, "", ""));
+						//scroll down
+						dataGrid.validateNow();
+						dataGrid.selectedIndex = valueSchemeEnumeration.length - 1;
+						dataGrid.scrollToIndex(valueSchemeEnumeration.length);
+					}
+				}
+			}
+
+			private function checkEdit(event:DataGridEvent):void {
+				// Do not allow editing of "Add row" row except for "Click to Add" column
+				if (event.rowIndex == valueSchemeEnumeration.length - 1 && event.columnIndex != 0)
+					event.preventDefault();
+			}
+
+			public function setConceptLink(input:TextInput):void {
+				var currentEditRow:Object = valueSchemeEnumeration.getItemAt(currentEditPosition.rowIndex);
+				currentEditRow.conceptLink = input.text;
+				dataGrid.invalidateList();
+				conceptLinkEdit = false;
+			}
+
+			private function handleItemEditBegin(e:DataGridEvent):void {
+				if (e.rowIndex < valueSchemeEnumeration.length - 1 && e.columnIndex == 2) {
+					conceptLinkEdit = true;
+					currentEditPosition = dataGrid.editedItemPosition;
+				} else {
+					conceptLinkEdit = false;
+				}
+			}
+
+			private function handleKeyUp(event:KeyboardEvent):void {
+				if (event.keyCode == Keyboard.DELETE) {
+					deleteRow(event);
+				}
+			}
+
+			private function deleteRow(event:*):void {
+				var indices:Array = dataGrid.selectedIndices;
+				for each (var index:int in indices) {
+					if (index != valueSchemeEnumeration.length - 1) { //Don't delete last row
+						valueSchemeEnumeration.removeItemAt(index);
+					}
+				}
+				dataGrid.validateNow();
+			}
+
+			private function insertRowAbove(event:ContextMenuEvent):void {
+				var index:int = Math.max(0, dataGrid.selectedIndex);
+				valueSchemeEnumeration.addItemAt(new ValueSchemeItem(ADD_ROW, "", ""), index);
+			}
+
+			private function createContextMenu():ContextMenu {
+				var cm:ContextMenu = new ContextMenu();
+				cm.hideBuiltInItems();
+				var items:Array = new Array();
+				var cmi:ContextMenuItem = new ContextMenuItem("Insert row above selected row...");
+				cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, insertRowAbove);
+				items.push(cmi);
+				cmi = new ContextMenuItem("Delete row...", true);
+				cmi.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, deleteRow);
+				items.push(cmi);
+				cm.customItems = items;
+				return cm;
+			}
+		]]>
+	</mx:Script>
+
+	<mx:DataGrid id="dataGrid"
+				 editable="true"
+				 doubleClickEnabled="true"
+				 sortableColumns="false"
+				 dataProvider="{valueSchemeEnumeration}"
+				 itemEditEnd="editEnd(event)"
+				 itemEditBeginning="checkEdit(event)"
+				 itemEditBegin="handleItemEditBegin(event)"
+				 allowMultipleSelection="true"
+				 keyUp="handleKeyUp(event)"
+				 contextMenu="{createContextMenu()}"
+				 useRollOver="false">
+		<mx:columns>
+			<mx:DataGridColumn dataField="item"/>
+			<mx:DataGridColumn dataField="appInfo"/>
+			<mx:DataGridColumn dataField="conceptLink"/>
+		</mx:columns>
+	</mx:DataGrid>
+</mx:VBox>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeInput.as	(revision 1843)
@@ -0,0 +1,124 @@
+package clarin.cmdi.componentregistry.editor {
+	import clarin.cmdi.componentregistry.browser.XMLBrowserValueSchemeLine;
+	import clarin.cmdi.componentregistry.common.StyleConstants;
+
+	import flash.events.MouseEvent;
+
+	import mx.collections.ArrayCollection;
+	import mx.containers.FormItem;
+	import mx.containers.FormItemDirection;
+	import mx.controls.Button;
+	import mx.controls.ComboBox;
+	import mx.controls.TextInput;
+	import mx.events.ValidationResultEvent;
+	import mx.managers.PopUpManager;
+	import mx.validators.Validator;
+
+	public class ValueSchemeInput extends FormItem implements CMDValidator {
+
+		private var textField:TextInput = new TextInput();
+		private var enumeration:ComboBox;
+		private var valueSchemeButton:Button = new Button();
+		private var _valueSchemeEnumeration:ArrayCollection;
+		private var _valueSchemePattern:String = "";
+		private var _valueSchemeSimple:String = "";
+		private var _validator:Validator = InputValidators.getIsRequiredValidator();
+
+		public function ValueSchemeInput(name:String, required:Boolean = true) {
+			super();
+			direction = FormItemDirection.HORIZONTAL;
+			label = name;
+			styleName = StyleConstants.XMLBROWSER_FIELD;
+			createValueSchemeButton();
+			textField.styleName = StyleConstants.XMLEDITOR_EDIT_FIELD;
+			textField.width = 300;
+			textField.editable = false;
+			enumeration = createEnumeration();
+		}
+
+		protected override function createChildren():void {
+			super.createChildren();
+			addChild(valueSchemeButton);
+		}
+
+		[Bindable]
+		public function get valueSchemeSimple():String {
+			return _valueSchemeSimple;
+		}
+
+		public function set valueSchemeSimple(valueSchemeSimple:String):void {
+			_valueSchemeEnumeration = null
+			_valueSchemePattern = "";
+			_valueSchemeSimple = valueSchemeSimple
+			textField.text = valueSchemeSimple as String;
+			if (getChildren().length > 1) {
+				removeChildAt(0);
+			}
+			addChildAt(textField, 0);
+			_validator.listener = this.textField;
+		}
+
+		[Bindable]
+		public function get valueSchemePattern():String {
+			return _valueSchemePattern;
+		}
+
+		public function set valueSchemePattern(valueSchemePattern:String):void {
+			_valueSchemeEnumeration = null;
+			_valueSchemeSimple = "";
+			_valueSchemePattern = valueSchemePattern
+			textField.text = valueSchemePattern;
+			if (getChildren().length > 1) {
+				removeChildAt(0);
+			}
+			addChildAt(textField, 0);
+			_validator.listener = this.textField;
+		}
+
+		[Bindable]
+		public function get valueSchemeEnumeration():ArrayCollection {
+			return _valueSchemeEnumeration;
+		}
+
+		public function set valueSchemeEnumeration(valueScheme:ArrayCollection):void {
+			_valueSchemeEnumeration = valueScheme;
+			_valueSchemeSimple = "";
+			_valueSchemePattern = "";
+			if (getChildren().length > 1) {
+				removeChildAt(0);
+			}
+			enumeration = createEnumeration();
+			enumeration.dataProvider = valueScheme;
+			addChildAt(enumeration, 0);
+			_validator.listener = this.enumeration;
+		}
+
+		private function createEnumeration():ComboBox {
+			var result:ComboBox = XMLBrowserValueSchemeLine.createValueSchemeComboBox();
+			result.width = 300;
+			return result;
+
+		}
+
+		private function createValueSchemeButton():void {
+			valueSchemeButton.label = "Edit...";
+			valueSchemeButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
+		}
+
+		private function handleButtonClick(event:MouseEvent):void {
+			var popup:ValueSchemePopUp = new ValueSchemePopUp();
+			popup.valueSchemeInput = this;
+			PopUpManager.addPopUp(popup, this.parent, false);
+		}
+
+		public function validate():Boolean {
+			var result:ValidationResultEvent;
+			if (_valueSchemeEnumeration == null) {
+				result = _validator.validate(this.textField.text);
+			} else {
+				result = _validator.validate(this.enumeration.dataProvider);
+			}
+			return result.type == ValidationResultEvent.VALID;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeItem.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeItem.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemeItem.as	(revision 1843)
@@ -0,0 +1,19 @@
+package clarin.cmdi.componentregistry.editor
+{
+    public class ValueSchemeItem
+    {
+        
+        public var item:String;
+        public var appInfo:String;
+        public var conceptLink:String;
+        
+    
+        public function ValueSchemeItem(item:String, appInfo:String, conceptLink:String)
+        {
+            this.item = item;
+            this.appInfo = appInfo;
+            this.conceptLink = conceptLink;
+        }
+
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemePopUp.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemePopUp.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/ValueSchemePopUp.mxml	(revision 1843)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
+				showCloseButton="true"
+				close="cleanUp();"
+				creationComplete="PopUpManager.centerPopUp(this)"
+				title="Edit and choose a type"
+				xmlns:editor="clarin.cmdi.componentregistry.editor.*">
+
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.services.IsocatService;
+			import clarin.cmdi.componentregistry.common.ComponentMD;
+			import mx.collections.XMLListCollection;
+			import mx.controls.TextInput;
+			import mx.managers.PopUpManager;
+			import mx.collections.ArrayCollection;
+
+			//Stores the result
+			[Bindable]
+			public var valueSchemeInput:ValueSchemeInput;
+
+			public static const DEFAULT_VALUE:String = "string";
+			//Taken from http://www.clarin.eu/cmd/general-component-schema.xsd (allowed_attributetypes_type)
+			[Bindable]
+			private var simpleValueSchemeDataProvider:ArrayCollection = new ArrayCollection([{label: "anyURI", data: "anyURI"},
+				{label: "boolean", data: "boolean"},
+				{label: "date", data: "date"},
+				{label: "time", data: "time"},
+				{label: "decimal", data: "decimal"},
+				{label: "float", data: "float"},
+				{label: "gDay", data: "gDay"},
+				{label: "gMonth", data: "gMonth"},
+				{label: "gYear", data: "gYear"},
+				{label: "string", data: "string"},
+				{label: "dateTime", data: "dateTime"},]);
+
+			private var isocatPopup:IsocatSearchPopUp;
+
+			private function setType():void {
+				valueSchemeInput.valueSchemeSimple = simpleValueSchemeBox.selectedItem.data;
+				cleanUp();
+			}
+
+			private function setPattern():void {
+				valueSchemeInput.valueSchemePattern = patternInput.text;
+				cleanUp();
+			}
+
+			private function setControlledVocabulary():void {
+				var enumeration:ArrayCollection = new ArrayCollection();
+				for (var i:int = 0; i < enumerationGrid.valueSchemeEnumeration.length - 1; i++) { //copy except the "Add new"
+					var item:ValueSchemeItem = enumerationGrid.valueSchemeEnumeration.getItemAt(i) as ValueSchemeItem;
+					enumeration.addItem(item);
+				}
+				valueSchemeInput.valueSchemeEnumeration = enumeration;
+				cleanUp();
+			}
+
+			private function cleanUp():void {
+				PopUpManager.removePopUp(this);
+			}
+
+			private function getIsocatPopup():IsocatSearchPopUp {
+				if (!isocatPopup) {
+					isocatPopup = EditorManager.getIsocatSearchPopUp(IsocatService.TYPE_SIMPLE);
+					isocatPopup.addEventListener(IsocatSearchPopUp.OK_EVENT, function(e:Event):void {
+							enumerationGrid.setConceptLink(isocatPopup.editField);
+						});
+				}
+				return isocatPopup;
+			}
+
+			private function handleIsocatButtonClick(event:MouseEvent):void {
+				PopUpManager.addPopUp(getIsocatPopup(), this, false);
+			}
+		]]>
+	</mx:Script>
+
+
+	<mx:Label text="Select type:"/>
+	<mx:HBox width="100%">
+		<mx:ComboBox id="simpleValueSchemeBox"
+					 prompt="{valueSchemeInput.valueSchemeSimple}"
+					 dataProvider="{simpleValueSchemeDataProvider}">
+		</mx:ComboBox>
+		<mx:Spacer width="100%"/>
+		<mx:Button label="Use Type"
+				   click="setType()"/>
+	</mx:HBox>
+
+	<mx:Label text="Or enter pattern:"/>
+	<mx:HBox width="100%">
+		<mx:TextInput id="patternInput"
+					  text="{valueSchemeInput.valueSchemePattern}">
+			<!-- PD TODO how can I validate this -->
+		</mx:TextInput>
+		<mx:Spacer width="100%"/>
+		<mx:Button label="Use Pattern"
+				   click="setPattern()"/>
+	</mx:HBox>
+
+	<!-- PD  TODO how should we implement open vocabularies?? -->
+	<mx:Label text="Or create controlled vocabularies:"/>
+	<mx:HBox width="100%">
+		<editor:ValueSchemeEnumerationGrid id="enumerationGrid"
+										   creationComplete="enumerationGrid.initEnumeration(valueSchemeInput.valueSchemeEnumeration)"/>
+		<mx:VBox>
+			<mx:Button label="Use Controlled Vocabulary"
+					   click="setControlledVocabulary()"/>
+			<mx:Button label="Search in isocat..."
+					   click="handleIsocatButtonClick(event)"
+					   enabled="{enumerationGrid.conceptLinkEdit}"/>
+		</mx:VBox>
+	</mx:HBox>
+
+	<mx:HBox width="100%">
+		<mx:Spacer width="100%"/>
+		<mx:Button label="Cancel"
+				   click="cleanUp()"/>
+	</mx:HBox>
+</mx:TitleWindow>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttribute.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttribute.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttribute.as	(revision 1843)
@@ -0,0 +1,73 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.common.XmlAble;
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+	import clarin.cmdi.componentregistry.editor.ValueSchemePopUp;
+	
+	import mx.collections.ArrayCollection;
+
+	public class CMDAttribute implements XmlAble, ValueSchemeInterface {
+		//No Attributes
+
+		//Elements
+		public var name:String;
+		private var type:String;
+		public var conceptLink:String;
+		private var _valueSchemePattern:String; //pattern
+		private var _valueSchemeEnumeration:ArrayCollection; // enumeration 
+
+		public function CMDAttribute() {
+		}
+
+		public static function createEmptyAttribute():CMDAttribute {
+			var result:CMDAttribute = new CMDAttribute();
+			result.valueSchemeSimple = ValueSchemePopUp.DEFAULT_VALUE;
+			return result;
+		}
+
+		public function get valueSchemeSimple():String {
+			return this.type
+		}
+
+		public function set valueSchemeSimple(valueSchemeSimple:String):void {
+			this.type = valueSchemeSimple;
+		}
+
+		public function get valueSchemeEnumeration():ArrayCollection {
+			return this._valueSchemeEnumeration
+		}
+
+		public function set valueSchemeEnumeration(valueSchemeEnumeration:ArrayCollection):void {
+			this._valueSchemeEnumeration = valueSchemeEnumeration;
+		}
+
+		public function get valueSchemePattern():String {
+			return this._valueSchemePattern;
+		}
+
+		public function set valueSchemePattern(valueSchemePattern:String):void {
+			this._valueSchemePattern = valueSchemePattern;
+		}
+
+		public function toXml():XML {
+			var result:XML = <Attribute></Attribute>;
+			result.appendChild(<Name>{name}</Name>);
+			if (conceptLink) {
+				result.appendChild(<ConceptLink>{conceptLink}</ConceptLink>);
+			}
+			if (valueSchemePattern) {
+				result.appendChild(<ValueScheme><pattern>{valueSchemePattern}</pattern></ValueScheme>);
+			} else if (valueSchemeEnumeration) {
+				var enumerationScheme:XML = <enumeration></enumeration>;
+				for each (var item:ValueSchemeItem in valueSchemeEnumeration) {
+					enumerationScheme.appendChild(<item {ComponentMD.APP_INFO}={item.appInfo} {ComponentMD.CONCEPTLINK}={item.conceptLink}>{item.item}</item>);
+				}
+				result.appendChild(<ValueScheme>{enumerationScheme}</ValueScheme>);
+			} else {
+				result.appendChild(<Type>{type}</Type>);
+			}
+
+			return result
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttributeTest.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttributeTest.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDAttributeTest.as	(revision 1843)
@@ -0,0 +1,59 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+	
+	import flexunit.framework.TestCase;
+	import flexunit.framework.TestSuite;
+	
+	import mx.collections.ArrayCollection;
+
+	public class CMDAttributeTest extends TestCase {
+		public function CMDAttributeTest() {
+			super();
+		}
+
+		public static function suite():TestSuite {
+			return new TestSuite(CMDAttributeTest);
+		}
+
+		public function testToXml():void {
+			var result:CMDAttribute = new CMDAttribute();
+			result.name = "aap";
+			result.valueSchemeSimple = "string";
+			var expected:XML = <Attribute>
+					<Name>aap</Name>
+					<Type>string</Type>
+				</Attribute>;
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+		public function testToXmlValueSchemePattern():void {
+			var result:CMDAttribute = new CMDAttribute();
+			result.name = "aap";
+			result.valueSchemePattern = "[a-zA-Z]+";
+			var expected:XML = <Attribute>
+					<Name>aap</Name>
+					<ValueScheme>
+					    <pattern>[a-zA-Z]+</pattern>
+					</ValueScheme>
+				</Attribute>;
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+		public function testToXmlValueSchemeEnumeration():void {
+			var result:CMDAttribute = new CMDAttribute();
+			result.name = "aap";
+			result.valueSchemeEnumeration = new ArrayCollection();
+			result.valueSchemeEnumeration.addItem(new ValueSchemeItem("Male", "test", "test2"));
+			var expected:XML = <Attribute>
+					<Name>aap</Name>
+					<ValueScheme>
+						<enumeration>
+							<item AppInfo="test" ConceptLink="test2">Male</item>
+						</enumeration>
+					</ValueScheme>
+				</Attribute>;
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponent.as	(revision 1843)
@@ -0,0 +1,115 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.XmlAble;
+
+	import mx.collections.ArrayCollection;
+
+	public class CMDComponent implements XmlAble {
+
+		//Attributes
+		public var name:String;
+		public var componentId:String;
+		public var conceptLink:String;
+		public var filename:String;
+		public var cardinalityMin:String = "1";
+		public var cardinalityMax:String = "1";
+
+		//elements
+		public var attributeList:ArrayCollection = new ArrayCollection();
+		public var cmdElements:ArrayCollection = new ArrayCollection();
+		public var cmdComponents:ArrayCollection = new ArrayCollection();
+
+
+		public function CMDComponent() {
+		}
+
+		public static function createEmptyComponent():CMDComponent {
+			var result:CMDComponent = new CMDComponent();
+			return result;
+		}
+
+		public function removeComponent(component:CMDComponent):void {
+			var index:int = cmdComponents.getItemIndex(component);
+			if (index != -1) {
+				cmdComponents.removeItemAt(index);
+			}
+		}
+
+		public function removeElement(element:CMDComponentElement):void {
+			var index:int = cmdElements.getItemIndex(element);
+			if (index != -1) {
+				cmdElements.removeItemAt(index);
+			}
+		}
+
+		public function moveDownElement(element:CMDComponentElement):Boolean {
+			var index:int = cmdElements.getItemIndex(element);
+			if (index < cmdElements.length - 1) {
+				cmdElements.removeItemAt(index);
+    			cmdElements.addItemAt(element, index + 1);
+    			return true;
+			}
+			return false;
+		}
+		
+		public function moveUpElement(element:CMDComponentElement):Boolean {
+			var index:int = cmdElements.getItemIndex(element);
+			if (index > 0) {
+				cmdElements.removeItemAt(index);
+    			cmdElements.addItemAt(element, index - 1);
+    			return true;
+			}
+			return false;
+		}
+		
+		public function moveDownComponent(comp:CMDComponent):Boolean {
+			var index:int = cmdComponents.getItemIndex(comp);
+			if (index < cmdComponents.length - 1) {
+				cmdComponents.removeItemAt(index);
+    			cmdComponents.addItemAt(comp, index + 1);
+    			return true;
+			}
+			return false;
+		}
+		
+		public function moveUpComponent(comp:CMDComponent):Boolean {
+			var index:int = cmdComponents.getItemIndex(comp);
+			if (index > 0) {
+				cmdComponents.removeItemAt(index);
+    			cmdComponents.addItemAt(comp, index - 1);
+    			return true;
+			}
+			return false;
+		}
+
+		public function toXml():XML {
+			var result:XML = <CMD_Component></CMD_Component>;
+			if (name)
+				result.@name = name;
+			if (componentId)
+				result.@ComponentId = componentId;
+			if (conceptLink)
+				result.@ConceptLink = conceptLink;
+			if (filename)
+				result.@filename = filename;
+			if (cardinalityMin)
+				result.@CardinalityMin = cardinalityMin;
+			if (cardinalityMax)
+				result.@CardinalityMax = cardinalityMax;
+			if (attributeList.length > 0) {
+				var attributeListTag:XML = <AttributeList></AttributeList>;
+				for each (var attribute:CMDAttribute in attributeList) {
+					attributeListTag.appendChild(attribute.toXml());
+				}
+				result.appendChild(attributeListTag);
+			}
+			for each (var element:CMDComponentElement in cmdElements) {
+				result.appendChild(element.toXml());
+			}
+			for each (var component:CMDComponent in cmdComponents) {
+				result.appendChild(component.toXml());
+			}
+			return result;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElement.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElement.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElement.as	(revision 1843)
@@ -0,0 +1,101 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.common.XmlAble;
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+	import clarin.cmdi.componentregistry.editor.ValueSchemePopUp;
+	
+	import mx.collections.ArrayCollection;
+
+	[Bindable]
+	public class CMDComponentElement implements XmlAble, ValueSchemeInterface {
+
+		//Attributes
+		public var name:String;
+		public var conceptLink:String;
+		public var documentation:String;
+		public var displayPriority:String;
+		public var multilingual:String;
+		private var _valueSchemeSimple:String;
+		public var cardinalityMin:String = "1";
+		public var cardinalityMax:String = "1";
+
+		//elements
+		public var attributeList:ArrayCollection = new ArrayCollection();
+		private var _valueSchemeEnumeration:ArrayCollection;
+		private var _valueSchemePattern:String;
+
+		public function CMDComponentElement() {
+		}
+
+		public static function createEmptyElement():CMDComponentElement {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.valueSchemeSimple = ValueSchemePopUp.DEFAULT_VALUE;
+			return result;
+		}
+
+
+		public function get valueSchemeSimple():String {
+			return this._valueSchemeSimple
+		}
+
+		public function set valueSchemeSimple(valueSchemeSimple:String):void {
+			this._valueSchemeSimple = valueSchemeSimple;
+		}
+
+		public function get valueSchemeEnumeration():ArrayCollection {
+			return this._valueSchemeEnumeration
+		}
+
+		public function set valueSchemeEnumeration(valueSchemeEnumeration:ArrayCollection):void {
+			this._valueSchemeEnumeration = valueSchemeEnumeration;
+		}
+
+		public function get valueSchemePattern():String {
+			return this._valueSchemePattern;
+		}
+
+		public function set valueSchemePattern(valueSchemePattern:String):void {
+			this._valueSchemePattern = valueSchemePattern;
+		}
+
+		public function toXml():XML {
+			var result:XML = <CMD_Element></CMD_Element>;
+			if (name)
+				result.@name = name;
+			if (conceptLink)
+				result.@ConceptLink = conceptLink;
+			if (documentation)
+				result.@Documentation = documentation;
+			if (displayPriority && displayPriority != "0")
+				result.@DisplayPriority = displayPriority;
+			if (valueSchemeSimple)
+				result.@ValueScheme = valueSchemeSimple;
+			if (cardinalityMin)
+				result.@CardinalityMin = cardinalityMin;
+			if (cardinalityMax)
+				result.@CardinalityMax = cardinalityMax;
+			if (multilingual != null)
+				result.@Multilingual = multilingual;
+			if (attributeList.length > 0) {
+				var attributeListTag:XML = <AttributeList></AttributeList>;
+				for each (var attribute:CMDAttribute in attributeList) {
+					attributeListTag.appendChild(attribute.toXml());
+				}
+				result.appendChild(attributeListTag);
+			}
+			if (valueSchemePattern) {
+				result.appendChild(<ValueScheme><pattern>{valueSchemePattern}</pattern></ValueScheme>)
+			}
+			if (valueSchemeEnumeration != null) {
+				var enumerationScheme:XML = <enumeration></enumeration>;
+				for each (var item:ValueSchemeItem in valueSchemeEnumeration) {
+					enumerationScheme.appendChild(<item {ComponentMD.APP_INFO}={item.appInfo} {ComponentMD.CONCEPTLINK}={item.conceptLink}>{item.item}</item>);
+				}
+				result.appendChild(<ValueScheme>{enumerationScheme}</ValueScheme>);
+			}
+			return result;
+		}
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElementTest.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElementTest.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentElementTest.as	(revision 1843)
@@ -0,0 +1,98 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+
+	import flexunit.framework.TestCase;
+	import flexunit.framework.TestSuite;
+
+	import mx.collections.ArrayCollection;
+
+	public class CMDComponentElementTest extends TestCase {
+		public function CMDComponentElementTest() {
+			super();
+		}
+
+		public static function suite():TestSuite {
+			return new TestSuite(CMDComponentElementTest);
+		}
+
+		public function testToXml():void {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.name = "aap";
+			result.valueSchemeSimple = "string";
+			result.documentation = "Docu";
+			result.displayPriority = "1";
+			result.multilingual = "false";
+			var att:CMDAttribute = new CMDAttribute();
+			att.name = "test";
+			att.valueSchemeSimple = "string";
+			result.attributeList.addItem(att);
+			var expected:XML = <CMD_Element name="aap" Documentation="Docu" DisplayPriority="1" ValueScheme="string" CardinalityMin="1" CardinalityMax="1"  Multilingual="false">
+					<AttributeList>
+						<Attribute>
+							<Name>test</Name>
+							<Type>string</Type>
+						</Attribute>  
+					</AttributeList>
+				</CMD_Element>;
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+		public function testToXmlDisplayPriorityZeroMeansDoNotSetIt():void {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.name = "aap";
+			result.valueSchemeSimple = "string";
+			result.documentation = "Docu";
+			result.displayPriority = "0";
+			var att:CMDAttribute = new CMDAttribute();
+			att.name = "test";
+			att.valueSchemeSimple = "string";
+			result.attributeList.addItem(att);
+			var expected:XML = <CMD_Element name="aap" Documentation="Docu" ValueScheme="string" CardinalityMin="1" CardinalityMax="1">
+					<AttributeList>
+						<Attribute>
+							<Name>test</Name>
+							<Type>string</Type>
+						</Attribute>  
+					</AttributeList>
+				</CMD_Element>;
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+		public function testToXmlValueScheme():void {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.name = "Sex";
+			result.conceptLink = "http://www.isocat.org/datcat/DC-2560";
+			result.valueSchemeEnumeration = new ArrayCollection();
+			result.valueSchemeEnumeration.addItem(new ValueSchemeItem("Male", "", ""));
+			result.valueSchemeEnumeration.addItem(new ValueSchemeItem("Female", "", ""));
+			result.valueSchemeEnumeration.addItem(new ValueSchemeItem("Unknown", "test", "test2"));
+			var expected:XML = <CMD_Element name="Sex" ConceptLink="http://www.isocat.org/datcat/DC-2560" CardinalityMin="1" CardinalityMax="1">
+					<ValueScheme>
+						<enumeration>
+							<item AppInfo="" ConceptLink="">Male</item>
+							<item AppInfo="" ConceptLink="">Female</item>
+							<item AppInfo="test" ConceptLink="test2">Unknown</item>
+						</enumeration>
+					</ValueScheme>
+				</CMD_Element>;
+
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+		public function testToXmlValueSchemePattern():void {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.name = "Test";
+			result.cardinalityMax = "5"
+			result.valueSchemePattern = "[a-z]";
+
+			var expected:XML = <CMD_Element name="Test" CardinalityMin="1" CardinalityMax="5">
+					<ValueScheme>
+						<pattern>[a-z]</pattern>
+					</ValueScheme>
+				</CMD_Element>;
+
+			assertEquals(expected.toXMLString(), result.toXml().toXMLString());
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentTest.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentTest.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDComponentTest.as	(revision 1843)
@@ -0,0 +1,24 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import flexunit.framework.TestCase;
+	import flexunit.framework.TestSuite;
+
+	public class CMDComponentTest extends TestCase {
+		public function CMDComponentTest() {
+			super();
+		}
+
+		public static function suite():TestSuite {
+			return new TestSuite(CMDComponentTest);
+		}
+
+		public function testToXml():void {
+		    var comp:CMDComponent = new CMDComponent();
+		    comp.name = "aap";
+		    var expected:XML = <CMD_Component name="aap" CardinalityMin="1" CardinalityMax="1"/>
+			assertEquals(expected.toXMLString(), comp.toXml().toXMLString());
+			
+		}
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDModelFactory.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDModelFactory.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDModelFactory.as	(revision 1843)
@@ -0,0 +1,118 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.editor.ValueSchemeItem;
+
+	import mx.collections.ArrayCollection;
+	import mx.collections.XMLListCollection;
+
+	public final class CMDModelFactory {
+		public function CMDModelFactory() {
+		}
+
+		public static function createModel(xml:XML, description:ItemDescription):CMDSpec {
+			var result:CMDSpec = new CMDSpec(xml.@isProfile == "true");
+			result.headerName = xml.Header.Name;
+			result.headerId = xml.Header.ID;
+			result.headerDescription = xml.Header.Description;
+			result.groupName = description.groupName;
+			result.domainName = description.domainName;
+			var components:XMLList = xml.elements(ComponentMD.CMD_COMPONENT);
+			for each (var component:XML in components) {
+				var cmdComp:CMDComponent = createComponent(component);
+				result.cmdComponents.addItem(cmdComp);
+			}
+			return result;
+		}
+
+		private static function createComponent(xml:XML):CMDComponent {
+			var result:CMDComponent = new CMDComponent();
+			result.name = xml.@name;
+			result.componentId = xml.@ComponentId;
+			result.conceptLink = xml.@ConceptLink;
+			result.filename = xml.@filename;
+			if (xml.hasOwnProperty("@CardinalityMin"))
+				result.cardinalityMin = xml.@CardinalityMin;
+			if (xml.hasOwnProperty("@CardinalityMax"))
+				result.cardinalityMax = xml.@CardinalityMax;
+			result.attributeList = createAttributeList(xml);
+			var elements:XMLList = xml.elements(ComponentMD.CMD_ELEMENT);
+			for each (var element:XML in elements) {
+				var cmdElement:CMDComponentElement = createComponentElement(element);
+				result.cmdElements.addItem(cmdElement);
+			}
+			var components:XMLList = xml.elements(ComponentMD.CMD_COMPONENT);
+			for each (var component:XML in components) {
+				var cmdComponent:CMDComponent = createComponent(component);
+				result.cmdComponents.addItem(cmdComponent);
+			}
+			return result;
+		}
+
+		private static function createComponentElement(xml:XML):CMDComponentElement {
+			var result:CMDComponentElement = new CMDComponentElement();
+			result.name = xml.@name;
+			result.conceptLink = xml.@ConceptLink;
+			result.documentation = xml.@Documentation;
+			result.displayPriority = xml.@DisplayPriority;
+			if (xml.hasOwnProperty("@CardinalityMin"))
+				result.cardinalityMin = xml.@CardinalityMin;
+			if (xml.hasOwnProperty("@CardinalityMax"))
+				result.cardinalityMax = xml.@CardinalityMax;
+			if (xml.hasOwnProperty("@Multilingual"))
+				result.multilingual = xml.@Multilingual;
+			result.attributeList = createAttributeList(xml);
+			if (xml.hasOwnProperty(ComponentMD.VALUE_SCHEME)) {
+				if (xml.ValueScheme.hasOwnProperty(ComponentMD.PATTERN)) {
+					result.valueSchemePattern = xml.ValueScheme.pattern;
+				} else if (xml.ValueScheme.hasOwnProperty(ComponentMD.ENUMERATION)) {
+					var xmlList:XMLListCollection = new XMLListCollection(xml.ValueScheme.enumeration.*);
+					var valueSchemeItems:ArrayCollection = new ArrayCollection();
+					for each (var xml:XML in xmlList) {
+						valueSchemeItems.addItem(new ValueSchemeItem(String(xml.text()), String(xml.@AppInfo), String(xml.@ConceptLink)));
+					}
+					result.valueSchemeEnumeration = valueSchemeItems;
+				}
+			} else if (xml.hasOwnProperty("@ValueScheme")) {
+				result.valueSchemeSimple = xml.@ValueScheme;
+			} else {
+				result.valueSchemeSimple = "";
+			}
+			return result;
+		}
+
+		private static function createAttributeList(xml:XML):ArrayCollection {
+			var result:ArrayCollection = new ArrayCollection();
+			if (xml.hasOwnProperty(ComponentMD.ATTRIBUTE_LIST)) {
+				var attributes:XMLList = xml.AttributeList.descendants(ComponentMD.ATTRIBUTE);
+				for each (var attribute:XML in attributes) {
+					var cmdAttribute:CMDAttribute = createAttribute(attribute);
+					result.addItem(cmdAttribute);
+				}
+			}
+			return result;
+		}
+
+		private static function createAttribute(xml:XML):CMDAttribute {
+			var result:CMDAttribute = new CMDAttribute();
+			result.name = xml.Name;
+			result.conceptLink = xml.ConceptLink;
+			if (xml.hasOwnProperty(ComponentMD.TYPE)) {
+				result.valueSchemeSimple = xml.Type;
+			} else {
+				if (xml.ValueScheme.hasOwnProperty(ComponentMD.PATTERN)) {
+					result.valueSchemePattern = xml.ValueScheme.pattern;
+				} else if (xml.ValueScheme.hasOwnProperty(ComponentMD.ENUMERATION)) {
+					var xmlList:XMLListCollection = new XMLListCollection(xml.ValueScheme.enumeration.*);
+					var valueSchemeItems:ArrayCollection = new ArrayCollection();
+					for each (var xml:XML in xmlList) {
+						valueSchemeItems.addItem(new ValueSchemeItem(String(xml.text()), String(xml.@AppInfo), String(xml.@ConceptLink)));
+					}
+					result.valueSchemeEnumeration = valueSchemeItems;
+				}
+			}
+			return result;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpec.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpec.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpec.as	(revision 1843)
@@ -0,0 +1,74 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import clarin.cmdi.componentregistry.common.XmlAble;
+
+	import mx.collections.ArrayCollection;
+
+	[Bindable]
+	public class CMDSpec implements XmlAble {
+		//Attribute
+		public var isProfile:Boolean;
+
+		//Elements
+		public var headerName:String;
+		public var headerId:String;
+		public var headerDescription:String;
+		public var cmdComponents:ArrayCollection = new ArrayCollection();
+
+		public var groupName:String = ""; //Not in xml but stored in the description
+		private var _domainName:String = ""; //Not in xml but stored in the description
+
+		public function CMDSpec(isProfile:Boolean) {
+			this.isProfile = isProfile;
+		}
+
+		public function removeComponent(component:CMDComponent):void {
+			var index:int = cmdComponents.getItemIndex(component);
+			if (index != -1) {
+				cmdComponents.removeItemAt(index);
+			}
+		}
+
+		public function toXml():XML {
+			var result:XML = <CMD_ComponentSpec>
+					<Header>
+						<ID>{headerId}</ID>
+						<Name>{headerName}</Name>
+						<Description>{headerDescription}</Description>
+					</Header>
+				</CMD_ComponentSpec>;
+			result.@isProfile = isProfile;
+			for each (var component:CMDComponent in cmdComponents) {
+				result.appendChild(component.toXml());
+			}
+			return result;
+		}
+
+		public function get domainName():String {
+			return _domainName;
+		}
+
+		public function set domainName(domainName:String):void {
+			if (domainName) {
+				_domainName = domainName;
+			} else {
+				_domainName = "";
+			}
+		}
+
+		public static function createEmptyComponent():CMDSpec {
+			var result:CMDSpec = new CMDSpec(false);
+			var c:CMDComponent = CMDComponent.createEmptyComponent();
+			result.cmdComponents.addItem(c);
+			c.cmdElements.addItem(CMDComponentElement.createEmptyElement());
+			return result
+		}
+
+		public static function createEmptyProfile():CMDSpec {
+			var result:CMDSpec = new CMDSpec(true);
+			var c:CMDComponent = CMDComponent.createEmptyComponent();
+			result.cmdComponents.addItem(c);
+			c.cmdElements.addItem(CMDComponentElement.createEmptyElement());
+			return result
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpecTest.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpecTest.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/CMDSpecTest.as	(revision 1843)
@@ -0,0 +1,31 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import flexunit.framework.TestCase;
+	import flexunit.framework.TestSuite;
+
+	public class CMDSpecTest extends TestCase {
+		public function CMDSpecTest() {
+			super();
+		}
+
+		public static function suite():TestSuite {
+			return new TestSuite(CMDSpecTest);
+		}
+
+		public function testToXml():void {
+			var comp:CMDSpec = new CMDSpec(true);
+			comp.headerName = "aap";
+			comp.headerDescription = "noot";
+			comp.headerId = "";
+			var expected:XML = <CMD_ComponentSpec isProfile="true">
+					<Header>
+						<ID></ID>
+						<Name>aap</Name>
+						<Description>noot</Description>
+					</Header>
+				</CMD_ComponentSpec>
+
+			assertEquals(expected.toXMLString(), comp.toXml().toXMLString());
+
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/ValueSchemeInterface.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/ValueSchemeInterface.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/editor/model/ValueSchemeInterface.as	(revision 1843)
@@ -0,0 +1,17 @@
+package clarin.cmdi.componentregistry.editor.model {
+	import mx.collections.ArrayCollection;
+
+	public interface ValueSchemeInterface {
+		function get valueSchemeSimple():String;
+		function set valueSchemeSimple(valueSchemeSimple:String):void;
+
+		/**
+		 * ArrayCollection of ValueSchemeItem's
+		 * */
+		function get valueSchemeEnumeration():ArrayCollection;
+		function set valueSchemeEnumeration(valueSchemeEnumeration:ArrayCollection):void;
+
+		function get valueSchemePattern():String;
+		function set valueSchemePattern(valueSchemePattern:String):void;
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/FileLoadedEvent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/FileLoadedEvent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/FileLoadedEvent.as	(revision 1843)
@@ -0,0 +1,25 @@
+package clarin.cmdi.componentregistry.importer {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import flash.events.Event;
+	import flash.net.FileReference;
+
+	public class FileLoadedEvent extends Event {
+		public static const FILE_LOADED:String = "fileLoaded";
+		private var _fileReference:FileReference;
+
+		public function FileLoadedEvent(fileReference:FileReference, bubbles:Boolean = false, cancelable:Boolean = false) {
+			super(FILE_LOADED, bubbles, cancelable);
+			_fileReference = fileReference;
+		}
+
+		public function get fileReference():FileReference {
+			return _fileReference;
+		}
+
+		override public function clone():Event {
+			return new FileLoadedEvent(_fileReference, bubbles, cancelable);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/Importer.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/Importer.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/Importer.mxml	(revision 1843)
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"
+		   xmlns:local="clarin.cmdi.componentregistry.services.*"
+		   width="100%"
+		   height="100%"
+		   label="Import..."
+		   implements="clarin.cmdi.componentregistry.common.components.RegistryView">
+
+	<mx:Script>
+		<![CDATA[
+			import mx.core.UIComponent;
+			import clarin.cmdi.componentregistry.common.ComponentMD;
+			import clarin.cmdi.componentregistry.common.Profile;
+			import clarin.cmdi.componentregistry.services.Config;
+			import mx.events.ValidationResultEvent;
+			import mx.collections.ArrayCollection;
+			import mx.validators.Validator;
+			import clarin.cmdi.componentregistry.editor.InputValidators;
+			import clarin.cmdi.componentregistry.common.LabelConstants;
+			import clarin.cmdi.componentregistry.common.Credentials;
+			import mx.core.Application;
+			import clarin.cmdi.componentregistry.common.ItemDescription;
+			import mx.controls.Alert;
+
+			private var validators:ArrayCollection = new ArrayCollection();
+
+			[Bindable]
+			private var isProfile:Boolean = true;
+			[Bindable]
+			private var importTypeString:String = "";
+
+			private var loadedXML:XML;
+
+			private function submit(event:Event):void {
+				if (validate()) {
+					var item:ItemDescription = new ItemDescription();
+					item.description = description.text;
+					item.name = nameInput.text;
+					item.groupName = groupName.text;
+					if (domainName.selectedIndex != -1)
+						item.domainName = domainName.selectedItem.data;
+					item.isProfile = isProfile;
+					item.isInUserSpace = true; //We only allow import into workspace it can be published from there.
+					if (loadedXML) {
+						updateXMLFromFormFields(loadedXML);
+						uploadSrv.upload(UploadService.NEW, item, loadedXML.toXMLString());
+					} else {
+						// No loaded XML. Let the upload service try with file reference
+						uploadSrv.upload(UploadService.NEW, item);
+					}
+				}
+			}
+
+			private function validate():Boolean {
+				var result:Boolean = true;
+				for (var i:int; i < validators.length; i++) {
+					var val:Validator = validators.getItemAt(i) as Validator;
+					if (val.listener.visible) {
+						var event:ValidationResultEvent = val.validate();
+						if (event.type != ValidationResultEvent.VALID) {
+							result = false;
+						}
+					}
+				}
+				return result;
+			}
+
+			private function setIsProfile(isProfileValue:Boolean):void {
+				isProfile = isProfileValue;
+				if (isProfile) {
+					importTypeString = "Profile";
+				} else {
+					importTypeString = "Component";
+				}
+			}
+
+			private function registryChange(event:UploadCompleteEvent):void {
+				// Upload completed. Reset upload services and form
+				uploadSrv.reset();
+				clearForm();
+				// Browse to uploaded item
+				parentApplication.viewStack.switchToBrowse(event.itemDescription);
+			}
+
+			private function fileLoaded(event:FileLoadedEvent):void {
+				var data:ByteArray = event.fileReference.data;
+				if (data && data.bytesAvailable) {
+					try {
+						var utfBytes:String = data.readUTFBytes(data.length);
+						loadedXML = new XML(utfBytes);
+
+						// New file selected, clear all previous entries
+						clearForm();
+						// Set import type (profile or component) from attribute in XML
+						setImportTypeFromFile(loadedXML);
+						// Set name, description from values in XML
+						setFormFieldsFromFile(loadedXML);
+					} catch (error:Error) {
+						Alert.show("Could not read the selected file. Not a valid XML file?", "Error");
+						importTypeString = "Error";
+						trace("Error while reading loaded file " + event.fileReference.name);
+						return;
+					}
+				}
+			}
+
+			private function setImportTypeFromFile(resultXml:XML):void {
+				if (resultXml.hasOwnProperty("@isProfile")) {
+					setIsProfile(("true" == resultXml.@isProfile));
+				} else {
+					Alert.show("Unable to determine import type. Selected file may not be a valid component specification!", "Warning");
+					importTypeString = "Unknown";
+				}
+			}
+
+			private function setFormFieldsFromFile(resultXml:XML):void {
+				var header:XML = getHeaderXML(resultXml);
+				var component:XML = getComponentXML(resultXml);
+				if (header) {
+					description.text = header.Description;
+				}
+				if(component){
+					nameInput.text = component.@name;
+				}
+			}
+
+			private function updateXMLFromFormFields(xml:XML):void {
+				var header:XML = getHeaderXML(xml);
+				var component:XML = getComponentXML(xml);
+				if (header) {
+					header.Name = nameInput.text;
+					header.Description = description.text;
+				}
+				if(component){
+					component.@name = nameInput.text;
+				}
+			}
+
+			private function getHeaderXML(xml:XML):XML {
+				if (xml.hasOwnProperty("Header")) {
+					var nodes:XMLList = xml.Header;
+					if (nodes && nodes.length() > 0) {
+						return nodes[0];
+					}
+				}
+				return null;
+			}
+			
+			private function getComponentXML(xml:XML):XML {
+				if (xml.hasOwnProperty("CMD_Component")) {
+					var nodes:XMLList = xml.CMD_Component;
+					if (nodes && nodes.length() > 0) {
+						return nodes[0];
+					}
+				}
+				return null;
+			}
+
+			private function clearForm():void {
+				importTypeString = "";
+				nameInput.text = "";
+				description.text = "";
+				groupName.text = "";
+				domainName.selectedItem = null;
+
+				// Reset all error strings on components with validators, so previous validation error message don't show anymore
+				for (var i:int; i < validators.length; i++) {
+					var val:Validator = validators.getItemAt(i) as Validator;
+					if (val.listener.visible) {
+						(val.source as UIComponent).errorString = "";
+					}
+				}
+			}
+
+			private function registerNameValidator(event:Event):void {
+				var validator:Validator = InputValidators.getNameValidator();
+				validator.listener = event.currentTarget;
+				validator.source = event.currentTarget;
+				validator.property = "text";
+				validators.addItem(validator);
+			}
+
+			private function registerIsRequiredValidator(event:Event, source:Object = null):void {
+				var validator:Validator = InputValidators.getIsRequiredValidator();
+				validator.listener = event.currentTarget;
+				if (!source) {
+					validator.source = event.currentTarget;
+				} else {
+					validator.source = source;
+				}
+				validator.property = "text";
+				validators.addItem(validator);
+			}
+
+			public function getType():String {
+				return Config.VIEW_IMPORT;
+			}
+		]]>
+	</mx:Script>
+
+	<local:UploadService id="uploadSrv"
+						 loadBeforeUploading="true"
+						 fileLoaded="fileLoaded(event)"
+						 uploadComplete="registryChange(event)"/>
+	<mx:VBox>
+		<mx:Form>
+			<mx:HBox>
+				<mx:Button label="Select xml..."
+						   id="btnSelect"
+						   click="uploadSrv.selectXmlFile(event)"
+						   creationComplete="registerIsRequiredValidator(event, txtSelectedFile)"/>
+				<mx:Text id="txtSelectedFile"
+						 text="{uploadSrv.selectedFile}"/>
+			</mx:HBox>
+
+			<mx:FormItem label="Type">
+				<mx:Label id="importType"
+						  width="300"
+						  text="{importTypeString}"/>
+			</mx:FormItem>
+			<mx:FormItem label="Name">
+				<mx:TextInput id="nameInput"
+							  width="300"
+							  creationComplete="registerNameValidator(event)"/>
+			</mx:FormItem>
+			<mx:FormItem label="Description">
+				<mx:TextArea id="description"
+							 width="300"
+							 height="120"
+							 creationComplete="registerIsRequiredValidator(event)"/>
+			</mx:FormItem>
+			<mx:FormItem label="Creator Name">
+				<mx:Text id="creatorName"
+						 width="300"
+						 text="{Credentials.instance.userName}"/>
+			</mx:FormItem>
+			<mx:FormItem label="Domain Name">
+				<mx:ComboBox id="domainName"
+							 selectedIndex="-1"
+							 prompt="{LabelConstants.DOMAIN_NAME_PROMPT}"
+							 dataProvider="{LabelConstants.DOMAIN_NAME_DATA}"/>
+			</mx:FormItem>
+			<mx:FormItem label="Group Name">
+				<mx:TextInput id="groupName"
+							  width="300"/>
+			</mx:FormItem>
+			<mx:Button label="Submit"
+					   click="submit(event)"/>
+			<mx:ProgressBar id="uploadProgress"
+							label=""
+							mode="manual"
+							creationComplete="uploadSrv.init(uploadProgress)"
+							visible="false"/>
+		</mx:Form>
+
+		<mx:Text id="errorMessageField"
+				 text="{uploadSrv.message}"/>
+
+	</mx:VBox>
+
+</mx:Canvas>
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/UploadCompleteEvent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/UploadCompleteEvent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/importer/UploadCompleteEvent.as	(revision 1843)
@@ -0,0 +1,24 @@
+package clarin.cmdi.componentregistry.importer {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+
+	import flash.events.Event;
+
+	public class UploadCompleteEvent extends Event {
+		public static const UPLOAD_COMPLETE:String = "uploadComplete";
+		private var _itemDescription:ItemDescription;
+
+		public function UploadCompleteEvent(itemDescription:ItemDescription, bubbles:Boolean = false, cancelable:Boolean = false) {
+			super(UPLOAD_COMPLETE, bubbles, cancelable);
+			_itemDescription = itemDescription;
+		}
+
+		public function get itemDescription():ItemDescription {
+			return _itemDescription;
+		}
+
+		override public function clone():Event {
+			return new UploadCompleteEvent(_itemDescription, bubbles, cancelable);
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/BrowserService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/BrowserService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/BrowserService.as	(revision 1843)
@@ -0,0 +1,64 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import mx.collections.ArrayCollection;
+	
+	import mx.rpc.events.ResultEvent;
+	
+	[Event(name="itemsLoaded", type="flash.events.Event")]
+	public class BrowserService extends ComponentRegistryService {
+        public static const ITEMS_LOADED:String = "itemsLoaded";
+
+		/**
+		 * Typed ArrayCollection publicly available for outside code to bind to and watch.
+		 */
+		[Bindable]
+		[ArrayElementType("ItemDescription")]
+		public var itemDescriptions:ArrayCollection;
+
+		// Not bindable needed for lookups over the whole collections of itemDescriptions
+		protected var unFilteredItemDescriptions:ArrayCollection;
+		protected var userSpace:Boolean;
+
+		public function BrowserService(restUrl:String, userSpace:Boolean) {
+			super(restUrl);
+			this.userSpace = userSpace;
+		}
+		
+		override protected function initServiceUrl(url:URI):void{
+			if (userSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+		}
+		
+		/**
+		 * Override in concrete subclasses
+		 */
+		override protected function result(resultEvent:ResultEvent):void {
+			dispatchEvent(new Event(ITEMS_LOADED));
+		}
+
+		protected function setItemDescriptions(items:ArrayCollection):void {
+			itemDescriptions = items;
+			unFilteredItemDescriptions = new ArrayCollection(); //create a copy
+			for each (var item:Object in items) {
+				unFilteredItemDescriptions.addItem(item);
+			}
+		}
+
+		/**
+		 * Looks up itemDescription, returns null if not found.
+		 */
+		public function lookUpDescription(componentId:String):ItemDescription {
+			for each (var item:ItemDescription in unFilteredItemDescriptions) {
+				if (item.id == componentId) {
+					return item;
+				}
+			}
+			return null;
+		}
+	}
+}
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentListService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentListService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentListService.as	(revision 1843)
@@ -0,0 +1,55 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.Comment;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import mx.collections.ArrayCollection;
+	import mx.rpc.events.ResultEvent;
+	
+	[Event(name="CommentsLoaded", type="flash.events.Event")]
+	public class CommentListService extends ComponentRegistryService {
+		public static const COMMENTS_LOADED:String = "CommentsLoaded";
+		;
+		private var userSpace:Boolean;
+		
+		/**
+		 * Typed ArrayCollection publicly available for outside code to bind to and watch.
+		 */
+		[Bindable]
+		[ArrayElementType("Comment")]
+		public var comments:ArrayCollection;
+		
+		public function CommentListService(itemDescription:ItemDescription, userSpace:Boolean) {
+			var url:String;
+			if(itemDescription.isProfile){
+				url = Config.instance.getProfileCommentsPath(itemDescription.id);
+			} else{
+				url = Config.instance.getComponentCommentsPath(itemDescription.id);
+			}
+			super(url);
+			
+			this.userSpace = userSpace;
+		}
+		
+		override protected function initServiceUrl(url:URI):void{
+			if (userSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+		}
+		
+		override protected function result(resultEvent:ResultEvent):void {
+			var resultXml:XML = resultEvent.result as XML;
+			var nodes:XMLList = resultXml.comment;
+			
+			comments = new ArrayCollection();
+			for each (var node:XML in nodes) {
+				var comment:Comment = new Comment();
+				comment.create(node);
+				comments.addItem(comment);
+			}
+			comments.refresh();
+			dispatchEvent(new Event(COMMENTS_LOADED));
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentPostService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentPostService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/CommentPostService.as	(revision 1843)
@@ -0,0 +1,139 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.Comment;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.HTTPStatusEvent;
+	import flash.events.IOErrorEvent;
+	import flash.events.ProgressEvent;
+	import flash.events.SecurityErrorEvent;
+	import flash.utils.ByteArray;
+	
+	import mx.managers.CursorManager;
+	
+	import ru.inspirit.net.MultipartURLLoader;
+	
+	[Event(name="postComplete", type="flash.events.Event")]
+	public class CommentPostService extends EventDispatcher{
+		
+		public static const POST_COMPLETE:String = "postComplete";
+		
+		public function CommentPostService() {
+		}
+		
+		[Bindable]
+		public var message:String = "";
+		
+		private var ml:MultipartURLLoader;
+		
+		private function createAndInitRequest():void {
+			CursorManager.setBusyCursor();
+			ml = new MultipartURLLoader();
+			ml.addEventListener(Event.COMPLETE, completeHandler);
+			ml.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+			ml.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
+			ml.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+		}
+		
+		/**
+		 * submits a comment
+		 */
+		public function upload(comment:Comment, itemDescription:ItemDescription):void {
+			createAndInitRequest();
+			var uri:URI = createUri(comment,itemDescription.isInUserSpace);
+			submit(createByteArray(comment.toXml()), uri);
+		}
+		
+		private function createUri(comment:Comment, userSpace:Boolean):URI {
+			var uri:URI = null;
+			if (comment.profileDescriptionId) {
+				uri = new URI(Config.instance.getProfileCommentsPath(comment.profileDescriptionId));
+			} else if(comment.componentDescriptionId){
+				uri = new URI(Config.instance.getComponentCommentsPath(comment.componentDescriptionId));
+			} else{
+				return null;
+			}
+			if (userSpace){
+				uri.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+			return uri;
+		}
+		
+		private function createByteArray(data:String):ByteArray {
+			var result:ByteArray = null;
+			if (data != null) {
+				result = new ByteArray();
+				result.writeUTFBytes(data);
+				result.position = 0;
+			}
+			return result
+		}
+		
+		private function submit(data:ByteArray, uri:URI):void {
+			message = "";
+			try {
+				ml.addFile(data, "comment.xml", "data");
+				ml.load(uri.toString());
+			} catch (error:Error) {
+				trace("Unable to post comment. Error: " + error);
+				CursorManager.removeBusyCursor();
+				throw error;
+			}
+		}
+		
+		private function completeHandler(event:Event):void {
+			uploadComplete();
+			var response:XML = new XML(ml.loader.data);
+			handleResponse(response);
+		}
+		
+		private function httpStatusHandler(event:HTTPStatusEvent):void {
+			if (event.status != 200) {
+				addToMessage("Server Failed to handle registration. Unexpected error, try again later. (httpstatus code was: " + event.status + ")\n");
+			}
+			CursorManager.removeBusyCursor();
+		}
+		
+		private function securityErrorHandler(event:SecurityErrorEvent):void {
+			addToMessage("Server Failed to handle registration. Unexpected error, try again later. (error: " + event.text + ")\n");
+			CursorManager.removeBusyCursor();
+		}
+		
+		private function progressHandler(event:ProgressEvent):void {
+			trace("Uploading: " + event.bytesLoaded + "/" + event.bytesTotal);
+		}
+		
+		private function startUploadHandler():void {
+			trace("uploading start");
+		}
+		
+		private function handleResponse(response:XML):void {
+			if (response.@registered == true) {
+				// TODO
+				dispatchEvent(new Event(POST_COMPLETE));
+			} else {
+				createErrorMessage(response);
+			}
+		}
+		
+		private function uploadComplete():void {
+			CursorManager.removeBusyCursor();
+		}
+		
+		private function createErrorMessage(response:XML):void {
+			addToMessage("Failed to register:");
+			var errors:XMLList = response.errors.error;
+			for each (var error:XML in errors) {
+				message += " - " + error.toString() + "\n";
+			}
+		}
+		
+		private function addToMessage(text:String):void {
+			message += text;
+		}
+		
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentInfoService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentInfoService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentInfoService.as	(revision 1843)
@@ -0,0 +1,64 @@
+package clarin.cmdi.componentregistry.services {
+
+	import clarin.cmdi.componentregistry.common.Component;
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	
+	import mx.controls.Alert;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.AsyncToken;
+	import mx.rpc.Responder;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+
+	[Event(name="ComponentLoaded", type="flash.events.Event")]
+	public class ComponentInfoService extends EventDispatcher{
+		public static const COMPONENT_LOADED:String = "ComponentLoaded";
+
+		private var service:HTTPService;
+
+		[Bindable]
+		public var component:Component;
+
+
+		public function ComponentInfoService() {
+			this.service = new HTTPService();
+			this.service.method = HTTPRequestMessage.GET_METHOD;
+			this.service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+		}
+
+		public function load(item:ItemDescription):void {
+			this.component = new Component();
+			component.description = item;
+			var url:URI = new URI(item.dataUrl);
+			if (item.isInUserSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+			service.url = url.toString();
+			var token:AsyncToken = this.service.send();
+			token.addResponder(new Responder(result, fault));
+		}
+
+		private function result(resultEvent:ResultEvent):void {
+			var resultXml:XML = resultEvent.result as XML;
+			var metaData:ComponentMD = new ComponentMD();
+			metaData.name = resultXml.CMD_Component.@name;
+			metaData.xml = resultXml;
+			component.componentMD = metaData;
+			dispatchEvent(new Event(COMPONENT_LOADED));
+		}
+
+		public function fault(faultEvent:FaultEvent):void {
+			var errorMessage:String = StringUtil.substitute("Error in {0}: {1} - {2}", this, faultEvent.fault.faultString, faultEvent.fault.faultDetail);
+			Alert.show(errorMessage);
+		}
+	}
+}
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentListService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentListService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentListService.as	(revision 1843)
@@ -0,0 +1,51 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.browser.BrowserColumns;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import mx.collections.ArrayCollection;
+	import mx.rpc.events.ResultEvent;
+
+	public class ComponentListService extends BrowserService {
+
+		private static var _instance:ComponentListService = new ComponentListService();
+		private static var _userSpaceInstance:ComponentListService = new ComponentListService(true);
+
+		public function ComponentListService(userSpace:Boolean = false) {
+			super(Config.instance.componentListUrl, userSpace);
+		}
+
+		override protected function result(resultEvent:ResultEvent):void {
+			var resultXml:XML = resultEvent.result as XML;
+			var nodes:XMLList = resultXml.componentDescription;
+
+			var tempArray:ArrayCollection = new ArrayCollection();
+			for each (var node:XML in nodes) {
+				var item:ItemDescription = new ItemDescription();
+				item.createComponent(node, userSpace);
+				tempArray.addItem(item);
+			}
+			tempArray.sort = BrowserColumns.getInitialSortForComponents();
+			tempArray.refresh();
+            setItemDescriptions(new ArrayCollection(tempArray.toArray()));
+		    super.result(resultEvent);
+		}
+
+		public static function getInstance(userSpace:Boolean):ComponentListService {
+			if (userSpace) {
+				return _userSpaceInstance;
+			} else {
+				return _instance;
+			}
+		}
+
+		public static function findDescription(componentId:String):ItemDescription {
+			var result:ItemDescription = getInstance(true).lookUpDescription(componentId);
+			if (result == null) {
+				result = getInstance(false).lookUpDescription(componentId);
+			}
+			return result
+		}
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentRegistryService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentRegistryService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentRegistryService.as	(revision 1843)
@@ -0,0 +1,57 @@
+package clarin.cmdi.componentregistry.services
+{
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	
+	import mx.controls.Alert;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.AsyncToken;
+	import mx.rpc.Responder;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+	
+	public class ComponentRegistryService extends EventDispatcher {
+		private var service:HTTPService;
+		
+		private var serviceUrl:String;
+		
+		public function ComponentRegistryService(restUrl:String) {
+			this.serviceUrl = restUrl;
+			service = new HTTPService();
+			service.method = HTTPRequestMessage.GET_METHOD;
+			service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+		}
+		
+		private function initService():void {
+			var url:URI = new URI(serviceUrl);
+			url.setQueryValue("unique", new Date().getTime().toString());
+			initServiceUrl(url);
+			service.url = url.toString();
+		}
+		
+		public function load():void {
+			initService();
+			var token:AsyncToken = this.service.send();
+			token.addResponder(new Responder(result, fault));
+		}
+		
+		/**
+		 * Override in concrete subclasses
+		 */
+		protected function result(resultEvent:ResultEvent):void {
+		}
+		
+		public function fault(faultEvent:FaultEvent):void {
+			var errorMessage:String = StringUtil.substitute("Error in {0}: \n Fault: {1} - {2}", this, faultEvent.fault.faultString, faultEvent.fault.faultDetail);
+			trace(errorMessage);
+			Alert.show("Internal Server error cannot process the data, try reloading the application.");
+		}
+		
+		protected function initServiceUrl(url:URI):void{
+		};
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageCheckEvent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageCheckEvent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageCheckEvent.as	(revision 1843)
@@ -0,0 +1,31 @@
+package clarin.cmdi.componentregistry.services
+{
+	import flash.events.Event;
+	
+	import mx.collections.ArrayCollection;
+	
+	public class ComponentUsageCheckEvent extends Event
+	{	
+		public static const COMPONENT_IN_USE:String = "componentInUse";
+		private var _itemsUsingComponent:ArrayCollection;
+		
+		public function ComponentUsageCheckEvent(type:String, itemsUsingComponent:ArrayCollection, bubbles:Boolean = false, cancelable:Boolean = false)
+		{
+			super(type, bubbles, cancelable);
+			_itemsUsingComponent = itemsUsingComponent;
+		}
+		
+		private var _isComponentInUse:Boolean;
+		
+		public function get isComponentInUse():Boolean{
+			return _itemsUsingComponent != null && _itemsUsingComponent.length > 0;
+		}
+		
+		/**
+		 * Names of components that use the specified item
+		 */
+		public function get itemUsingComponent():ArrayCollection{
+			return _itemsUsingComponent;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ComponentUsageService.as	(revision 1843)
@@ -0,0 +1,68 @@
+package clarin.cmdi.componentregistry.services
+{
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	
+	import mx.collections.ArrayCollection;
+	import mx.controls.Alert;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.AsyncToken;
+	import mx.rpc.Responder;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+	
+	/**
+	 * Service that calls registry/components/usage/{id} for the specified component, which is used to check
+	 * whether the component is used by any other components or profiles in the same registry. 
+	 */
+	[Event(name="componentInUse", type="clarin.cmdi.componentregistry.services.ComponentUsageCheckEvent")]
+	public class ComponentUsageService extends EventDispatcher
+	{
+		private var service:HTTPService;
+		
+		public function ComponentUsageService(itemDescription:ItemDescription, userSpace:Boolean)
+		{
+			var url:URI = new URI(Config.instance.componentUsageUrl + itemDescription.id);
+			if (userSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+
+			service = new HTTPService();
+			service.url = url.toString();
+			service.method = HTTPRequestMessage.GET_METHOD;
+			service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+			service.showBusyCursor = true;
+		}
+				
+		public function checkUsage():void{
+			var token:AsyncToken = this.service.send();
+			token.addResponder(new Responder(result, fault));
+		}
+		
+		private function result(resultEvent:ResultEvent):void {
+			// Result contains list of items that use the specified component
+			var resultXml:XML = resultEvent.result as XML;
+			
+			// Collect item names so the view can show them to the user
+			var resultItems:ArrayCollection = new ArrayCollection();
+			for each (var description:XML in resultXml.children()) {
+				resultItems.addItem(description.name.toString());
+			}
+			
+			var event:ComponentUsageCheckEvent = new ComponentUsageCheckEvent(ComponentUsageCheckEvent.COMPONENT_IN_USE, resultItems);					
+			dispatchEvent(event);
+		}
+		
+		private function fault(faultEvent:FaultEvent):void {
+			var errorMessage:String = StringUtil.substitute("Error in {0}: \n Fault: {1} - {2}", this, faultEvent.fault.faultString, faultEvent.fault.faultDetail);
+			trace(errorMessage);
+			Alert.show("Internal Server error cannot process the data, try reloading the application.");
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/Config.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/Config.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/Config.as	(revision 1843)
@@ -0,0 +1,184 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+
+	[Event(name="userSpaceToggle", type="flash.events.Event")]
+	public final class Config extends EventDispatcher {
+		public static const USER_SPACE_TOGGLE_EVENT:String = "userSpaceToggle";
+
+		public static const CLARIN_REGISTER_URL:String = "http://www.clarin.eu/user/register";
+		public static const PARAM_USERSPACE:String = "userspace";
+		public static const REGISTRY_PARAM_VIEW:String = "view";
+		public static const REGISTRY_PARAM_ITEM:String = "item";
+		public static const REGISTRY_PARAM_SPACE:String = "space";
+		public static const REGISTRY_PARAM_DEBUG:String = "debug";
+
+		//Possible views to start with.
+		public static const VIEW_BROWSE:String = "browse";
+		public static const VIEW_EDIT:String = "edit";
+		public static const VIEW_IMPORT:String = "import";
+		//Possible space to start with.
+		public static const SPACE_USER:String = "user";
+		public static const SPACE_PUBLIC:String = "public";
+
+		private static const COMPONENT_LIST_URL:String = "/rest/registry/components";
+		private static const PROFILE_LIST_URL:String = "/rest/registry/profiles";
+		private static const COMPONENT_USAGE_URL:String = "/rest/registry/components/usage/";
+		private static const UPLOAD_PROFILE_SERVICE_URL:String = "/rest/registry/profiles";
+		private static const UPLOAD_COMPONENT_SERVICE_URL:String = "/rest/registry/components";
+		private static const PROFILE_INFO_URL:String = "/rest/registry/profiles/";
+		private static const COMPONENT_INFO_URL:String = "/rest/registry/components/";
+		private static const PING_SESSION_URL:String = "/rest/registry/pingSession";
+		private static const USER_SETTINGS_URL:String = "/admin/userSettings";
+		private static const COMMENTS_URL_PATH:String = "/comments/";
+		private static const ISOCAT_SERVLET:String = "/isocat";
+
+
+		private static var _instance:Config = new Config();
+
+		private var _startupItem:String; //item to be selected at startup, can be specified as a url parameter
+		private var _serviceRootUrl:String = "http://localhost:8080/ComponentRegistry";
+		//Default _serviceRootUrl value can be useful for testing. Set the proper value in your (index.)html that embeds the flash object.
+		//Like this: "FlashVars", "serviceRootUrl=http://localhost:8080/ComponentRegistry"
+
+		private var _view:String = VIEW_BROWSE;
+		private var _space:String = SPACE_PUBLIC;
+		private var _userSpace:Boolean = false;
+		private var _debug:Boolean = false;
+
+		public function Config() {
+			if (_instance != null) {
+				throw new Error("Config can only be accessed through Config.instance");
+			}
+		}
+
+		private function init(applicationParameters:Object):void {
+			var serviceRootUrl:String = applicationParameters.serviceRootUrl;
+			if (serviceRootUrl) {
+				_serviceRootUrl = serviceRootUrl;
+			}
+			var item:String = applicationParameters.item;
+			if (item) {
+				_startupItem = item;
+			}
+			var view:String = applicationParameters.view;
+			if (view) {
+				_view = view;
+			}
+			var space:String = applicationParameters.space;
+			if (space) {
+				_space = space;
+			}
+			var debug:int = applicationParameters.debug;
+			if(debug) {
+				_debug = Boolean(debug);
+			}
+		}
+
+		public static function create(applicationParameters:Object):void {
+			_instance.init(applicationParameters);
+		}
+
+		public function get profileListUrl():String {
+			return _serviceRootUrl + PROFILE_LIST_URL;
+		}
+
+		public function get componentListUrl():String {
+			return _serviceRootUrl + COMPONENT_LIST_URL;
+		}
+		
+		public function get componentUsageUrl():String {
+			return _serviceRootUrl + COMPONENT_USAGE_URL;
+		}
+
+		public function get profileInfoUrl():String {
+			return _serviceRootUrl + PROFILE_INFO_URL;
+		}
+		
+		public function getProfileCommentsPath(id:String):String{
+			return profileInfoUrl + id + COMMENTS_URL_PATH;
+		}
+
+		public function getComponentCommentsPath(id:String):String{
+			return componentInfoUrl + id + COMMENTS_URL_PATH;
+		}
+
+		public function get componentInfoUrl():String {
+			return _serviceRootUrl + COMPONENT_INFO_URL;
+		}
+
+		public function get uploadProfileUrl():String {
+			return _serviceRootUrl + UPLOAD_PROFILE_SERVICE_URL;
+		}
+
+		public function get uploadComponentUrl():String {
+			return _serviceRootUrl + UPLOAD_COMPONENT_SERVICE_URL;
+		}
+
+		public function get isocatSearchUrl():String {
+			return _serviceRootUrl + ISOCAT_SERVLET;
+		}
+
+		public function get serviceRootUrl():String {
+			return _serviceRootUrl;
+		}
+
+		public function get pingSessionUrl():String {
+			return _serviceRootUrl + PING_SESSION_URL;
+		}
+		
+		public function get userSettingsUrl():String{
+			return _serviceRootUrl + USER_SETTINGS_URL;
+		}
+
+		public function set userSpace(userSpace:Boolean):void {
+			if (_userSpace != userSpace) {
+				_userSpace = userSpace;
+				dispatchEvent(new Event(USER_SPACE_TOGGLE_EVENT));
+			}
+		}
+
+		public function get userSpace():Boolean {
+			return _userSpace;
+		}
+
+		public function get startupItem():String {
+			return _startupItem;
+		}
+
+		public function get view():String {
+			return _view;
+		}
+
+		public function get space():String {
+			return _space;
+		}
+		
+		public function get debug():Boolean {
+			return _debug;
+		}
+
+		public static function getBookmarkUrl(item:ItemDescription):String {
+			var uri:URI = new URI(Config.instance.serviceRootUrl);
+		    uri.setQueryValue(REGISTRY_PARAM_ITEM, item.id);
+			if (item.isInUserSpace) {
+				uri.setQueryValue(REGISTRY_PARAM_SPACE, SPACE_USER);
+			}
+			return uri.toString();
+		}
+		
+		public static function getXsdLink(item:ItemDescription):String {
+			var uri:URI = new URI(item.dataUrl+"/xsd");
+			return uri.toString();
+		}
+
+		public static function get instance():Config {
+			return _instance;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/DeleteService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/DeleteService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/DeleteService.as	(revision 1843)
@@ -0,0 +1,70 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+
+	import com.adobe.net.URI;
+
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+
+	import mx.controls.Alert;
+	import mx.managers.CursorManager;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+
+	[Event(name="itemDeleted", type="flash.events.Event")]
+
+	public class DeleteService extends EventDispatcher {
+		public static const ITEM_DELETED:String = "itemDeleted";
+		private var service:HTTPService;
+		private static const DELETE_METHOD:Object = {"method": "delete"};
+
+		private static var _instance:DeleteService = new DeleteService();
+
+		public function DeleteService() {
+			if (_instance != null) {
+				throw new Error("DeleteService should only be accessed through DeleteService.instance");
+			}
+			service = new HTTPService();
+			service.addEventListener(FaultEvent.FAULT, handleError);
+			service.addEventListener(ResultEvent.RESULT, handleResult);
+			service.method = HTTPRequestMessage.POST_METHOD;
+		}
+
+		public function deleteItem(item:ItemDescription):void {
+			CursorManager.setBusyCursor();
+			var url:URI = new URI(item.dataUrl);
+			if (item.isInUserSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+			service.url = url.toString();
+			service.send(DELETE_METHOD);
+		}
+
+		private function handleResult(resultEvent:ResultEvent):void {
+			CursorManager.removeBusyCursor();
+			if (resultEvent.statusCode >= 200 && resultEvent.statusCode < 300) {
+				dispatchEvent(new Event(ITEM_DELETED));
+			} else {
+				Alert.show("Unexpected error, server returned status: " + resultEvent.statusCode + "\n Message = ");
+			}
+		}
+
+		public function handleError(faultEvent:FaultEvent):void {
+			CursorManager.removeBusyCursor();
+			if (faultEvent.statusCode == 401) { //Apparrently depending on browser status codes and errormessages are sometimes not passed along to flash.
+				Alert.show("Item not deleted:" + faultEvent.message.body);
+			} else if (faultEvent.statusCode == 403) {
+				Alert.show("Item not deleted:" + faultEvent.message.body);
+			} else {
+				Alert.show("Item not deleted: Item is either public or in the case of a component still referenced by other components/profiles.");
+			}
+		}
+
+		public static function get instance():DeleteService {
+			return _instance;
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/IsocatService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/IsocatService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/IsocatService.as	(revision 1843)
@@ -0,0 +1,83 @@
+package clarin.cmdi.componentregistry.services {
+	import com.adobe.net.URI;
+	
+	import flash.events.EventDispatcher;
+	
+	import mx.controls.Alert;
+	import mx.managers.CursorManager;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+
+	public class IsocatService extends EventDispatcher {
+		public static const PROFILE_LOADED:String = "ProfileLoaded";
+		public static const TYPE_SIMPLE:String = "simple";
+		public static const TYPE_COMPLEX:String = "complex";
+		public static const TYPE_CONTAINER:String = "container";
+		
+		namespace dcif = "http://www.isocat.org/ns/dcif";
+
+
+		private var service:HTTPService;
+
+		[Bindable]
+		public var searchResults:XMLList;
+
+		public function IsocatService() {
+		}
+
+        /**
+         * keyword to search for
+         * type can be one of IsocatService.TYPE_SIMPLE or IsocatService.TYPE_COMPLEX or null for all types
+         **/ 
+		public function load(keyword:String, type:String):void {
+			if (keyword) {
+				createClient();
+				CursorManager.setBusyCursor();
+				var uri:URI = new URI(Config.instance.isocatSearchUrl);
+				uri.setQueryValue("keywords", keyword);
+				if (type)
+				    uri.setQueryValue("type", type);
+				service.url = uri.toString();
+				service.send();
+			}
+		}
+
+		public function close():void {
+			if (service) {
+				service.cancel();
+			}
+			CursorManager.removeBusyCursor();
+		}
+
+		private function createClient():void {
+			service = new HTTPService();
+			service.method = HTTPRequestMessage.GET_METHOD;
+			service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+			service.addEventListener(ResultEvent.RESULT, handleResult);
+			service.addEventListener(FaultEvent.FAULT, handleError);
+		}
+
+
+		private function handleResult(resultEvent:ResultEvent):void {
+			CursorManager.removeBusyCursor();
+			if (resultEvent.statusCode >= 200 && resultEvent.statusCode < 300) {
+				var data:XML = new XML(resultEvent.result);
+				searchResults = data.dcif::dataCategory;
+			} else {
+				Alert.show("Unexpected error, server returned status: " + resultEvent.statusCode + "\n Message = ");
+			}
+		}
+
+		private function handleError(faultEvent:FaultEvent):void {
+			CursorManager.removeBusyCursor();
+			var errorMessage:String = StringUtil.substitute("Error in {0} status {1}: {2}", this, faultEvent.statusCode, faultEvent.fault.faultString);
+			Alert.show(errorMessage);
+		}
+
+
+	}
+}
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/PingSessionService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/PingSessionService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/PingSessionService.as	(revision 1843)
@@ -0,0 +1,73 @@
+package clarin.cmdi.componentregistry.services {
+
+	import clarin.cmdi.componentregistry.common.Credentials;
+	
+	import flash.events.TimerEvent;
+	import flash.utils.Timer;
+	
+	import mx.controls.Alert;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.AsyncToken;
+	import mx.rpc.Responder;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+
+
+	public class PingSessionService {
+
+		[Bindable]
+		public var stillActive:Boolean
+
+		public static const INSTANCE:PingSessionService = new PingSessionService();
+        private static const PING_INTERVAL:int = 1000 * 60 * 5; //5 minutes
+		private var timer:Timer = new Timer(PING_INTERVAL, 0);
+		private var service:HTTPService;
+
+		/**
+		 * Use INSTANCE field
+		 */
+		function PingSessionService() {
+			this.service = new HTTPService();
+			this.service.method = HTTPRequestMessage.GET_METHOD;
+			this.service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+		}
+
+		public function startPinging():void {
+			timer.addEventListener(TimerEvent.TIMER, timerHandler);
+			timer.start();
+		}
+
+		public function timerHandler(event:TimerEvent):void {
+			pingSession();
+		}
+
+		private function pingSession():void {
+		    if (Credentials.instance.isLoggedIn()) {
+    			service.url = Config.instance.pingSessionUrl;
+    			var token:AsyncToken = service.send();
+    			token.addResponder(new Responder(result, fault));
+		    }
+		}
+
+		private function result(resultEvent:ResultEvent):void {
+			stillActive = resultEvent.result.@stillActive == "true";
+			if (!stillActive) {
+			    Alert.show("Your session has expired, please reload the application to refresh the session.");
+			    timer.stop(); 
+			}
+		}
+
+		public function fault(faultEvent:FaultEvent):void {
+			timer.stop(); // We stop to bother the user with more errors. Somethings is wrong user needs probably to reload which will start the timer again.
+			var errorMessage:String = StringUtil.substitute("Error in {0}: {1} - {2}", this, faultEvent.fault.faultString, faultEvent.fault.faultDetail);
+			Alert.show(errorMessage);
+		}
+
+
+
+
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileInfoService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileInfoService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileInfoService.as	(revision 1843)
@@ -0,0 +1,72 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ComponentMD;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.common.Profile;
+
+	import com.adobe.net.URI;
+
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+
+	import mx.collections.ArrayCollection;
+	import mx.controls.Alert;
+	import mx.messaging.messages.HTTPRequestMessage;
+	import mx.rpc.AsyncToken;
+	import mx.rpc.Responder;
+	import mx.rpc.events.FaultEvent;
+	import mx.rpc.events.ResultEvent;
+	import mx.rpc.http.HTTPService;
+	import mx.utils.StringUtil;
+
+	[Event(name="ProfileLoaded", type="flash.events.Event")]
+	public class ProfileInfoService extends EventDispatcher {
+		public static const PROFILE_LOADED:String = "ProfileLoaded";
+
+		private var service:HTTPService;
+
+		[Bindable]
+		public var profile:Profile;
+
+
+		public function ProfileInfoService() {
+			this.service = new HTTPService();
+			this.service.method = HTTPRequestMessage.GET_METHOD;
+			this.service.resultFormat = HTTPService.RESULT_FORMAT_E4X;
+		}
+
+		public function load(item:ItemDescription):void {
+			profile = new Profile();
+			profile.description = item;
+			var url:URI = new URI(item.dataUrl);
+			if (item.isInUserSpace) {
+				url.setQueryValue(Config.PARAM_USERSPACE, "true");
+			}
+			service.url = url.toString();
+			var token:AsyncToken = this.service.send();
+			token.addResponder(new Responder(result, fault));
+		}
+
+		private function result(resultEvent:ResultEvent):void {
+			var resultXml:XML = resultEvent.result as XML;
+			var nodes:XMLList = resultXml.CMD_Component;
+
+			profile.nrOfComponents = nodes.length();
+			profile.profileSource = resultXml;
+			var tempArray:Array = new Array();
+			for each (var node:XML in nodes) {
+				var component:ComponentMD = new ComponentMD();
+				component.name = node.@name;
+				component.xml = node;
+				tempArray[tempArray.length] = component;
+			}
+			this.profile.components = new ArrayCollection(tempArray);
+			dispatchEvent(new Event(PROFILE_LOADED));
+		}
+
+		public function fault(faultEvent:FaultEvent):void {
+			var errorMessage:String = StringUtil.substitute("Error in {0}: {1} - {2}", this, faultEvent.fault.faultString, faultEvent.fault.faultDetail);
+			Alert.show(errorMessage);
+		}
+	}
+}
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileListService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileListService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/ProfileListService.as	(revision 1843)
@@ -0,0 +1,49 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.browser.BrowserColumns;
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	
+	import mx.collections.ArrayCollection;
+	import mx.rpc.events.ResultEvent;
+
+	public class ProfileListService extends BrowserService {
+		
+		private static var _instance:ProfileListService = new ProfileListService();
+		private static var _userSpaceInstance:ProfileListService = new ProfileListService(true);
+
+		public function ProfileListService(userSpace:Boolean=false) {
+			super(Config.instance.profileListUrl, userSpace);
+		}
+
+		override protected function result(resultEvent:ResultEvent):void {
+			var resultXml:XML = resultEvent.result as XML;
+			var nodes:XMLList = resultXml.profileDescription;
+			var tempArray:ArrayCollection = new ArrayCollection();
+			for each (var node:XML in nodes) {
+				var item:ItemDescription = new ItemDescription();
+				item.createProfile(node, userSpace);
+				tempArray.addItem(item);
+			}
+			tempArray.sort = BrowserColumns.getInitialSortForProfiles();
+			tempArray.refresh();
+			setItemDescriptions(new ArrayCollection(tempArray.toArray()));
+		    super.result(resultEvent);
+		}
+
+		public static function getInstance(userSpace:Boolean):ProfileListService {
+			if (userSpace) {
+				return _userSpaceInstance;
+			} else {
+				return _instance;
+			}
+		}
+		
+		public static function findDescription(profileId:String):ItemDescription {
+			var result:ItemDescription = getInstance(true).lookUpDescription(profileId);
+			if (result == null) {
+				result = getInstance(false).lookUpDescription(profileId);
+			}
+			return result
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/SaveItemDialog.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/SaveItemDialog.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/SaveItemDialog.as	(revision 1843)
@@ -0,0 +1,31 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+
+	import com.adobe.net.URI;
+
+	import flash.net.URLRequest;
+	import flash.net.navigateToURL;
+
+	public class SaveItemDialog {
+
+
+		public function SaveItemDialog() {
+		}
+
+		public function saveAsXML(item:ItemDescription):void {
+			save(item, "xml");
+		}
+
+		public function saveAsXSD(item:ItemDescription):void {
+			save(item, "xsd");
+		}
+
+		private function save(item:ItemDescription, extension:String, urlVariable:String = null):void {
+			var req:URLRequest = new URLRequest();
+			var url:URI = new URI(item.dataUrl + "/" + extension);
+			req.url = url.toString();
+			navigateToURL(req, "_top");
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/UploadService.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/UploadService.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/clarin/cmdi/componentregistry/services/UploadService.as	(revision 1843)
@@ -0,0 +1,268 @@
+package clarin.cmdi.componentregistry.services {
+	import clarin.cmdi.componentregistry.common.ItemDescription;
+	import clarin.cmdi.componentregistry.importer.FileLoadedEvent;
+	import clarin.cmdi.componentregistry.importer.UploadCompleteEvent;
+	
+	import com.adobe.net.URI;
+	
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.HTTPStatusEvent;
+	import flash.events.IOErrorEvent;
+	import flash.events.ProgressEvent;
+	import flash.events.SecurityErrorEvent;
+	import flash.net.FileFilter;
+	import flash.net.FileReference;
+	import flash.net.URLVariables;
+	import flash.utils.ByteArray;
+	
+	import mx.controls.ProgressBar;
+	import mx.managers.CursorManager;
+	
+	import ru.inspirit.net.MultipartURLLoader;
+
+	[Event(name="uploadComplete", type="clarin.cmdi.componentregistry.importer.UploadCompleteEvent")]
+	[Event(name="fileLoaded", type="clarin.cmdi.componentregistry.importer.FileLoadedEvent")]
+	public class UploadService extends EventDispatcher{
+
+		/**
+		 * Tries to Update the existing data (only valid for updating in private workspace)
+		 **/
+		public static const UPDATE:int = 0;
+		/**
+		 * Tries to create new data
+		 **/
+		public static const NEW:int = 1;
+		/**
+		 * Tries to publish existing private data to public workspace
+		 **/
+		public static const PUBLISH:int = 2;
+
+		public function UploadService() {
+		}
+
+		[Bindable]
+		public var selectedFile:String = "";
+		[Bindable]
+		public var message:String = "";
+
+		private var fileRef:FileReference;
+		private var pb:ProgressBar;
+		private var ml:MultipartURLLoader;
+		private var _loadBeforeUploading:Boolean = false;
+
+		public function set loadBeforeUploading(lbu:Boolean):void {
+			_loadBeforeUploading = lbu;
+		}
+
+		public function init(progressBar:ProgressBar):void {
+			pb = progressBar;
+		}
+
+		private function createAndInitRequest():void {
+			CursorManager.setBusyCursor();
+			ml = new MultipartURLLoader();
+			ml.addEventListener(Event.COMPLETE, completeHandler);
+			ml.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+			ml.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
+			ml.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
+			ml.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+		}
+
+		private function createAndInitFileReference():void {
+			fileRef = new FileReference();
+			fileRef.addEventListener(Event.SELECT, selectHandler);
+
+			fileRef.addEventListener(ProgressEvent.PROGRESS, progressHandler);
+			fileRef.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+			fileRef.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
+
+			// If loading is enabled, register handler that will dispatch loadFile event
+			if (_loadBeforeUploading) {
+				fileRef.addEventListener(Event.COMPLETE, fileLoadedHandler);
+			}
+		}
+
+		/**
+		 * submits a profile/component, data parameter can be null which implies a file was selected using selectXmlFile();
+		 * An valid uploadAction must be one of UploadEvent.UPDATE, UploadEvent.NEW or UploadEvent.PUBLISH
+		 */
+		public function upload(uploadAction:int, description:ItemDescription, data:String = null):void {
+			createAndInitRequest();
+			var uri:URI = createUri(uploadAction, description);
+			submit(description, createByteArray(data), uri);
+		}
+
+		private function createUri(uploadAction:int, desc:ItemDescription):URI {
+			var uri:URI = null;
+			var uriBase:String = Config.instance.uploadComponentUrl;
+			if (desc.isProfile) {
+				uriBase = Config.instance.uploadProfileUrl;
+			}
+			var action:int = uploadAction;
+			if (!desc.id) {
+				action = NEW;
+			}
+			switch (action) {
+				case UPDATE:
+					uri = new URI(uriBase + "/" + desc.id + "/update");
+					if (desc.isInUserSpace) {
+						uri.setQueryValue(Config.PARAM_USERSPACE, "true");
+					}
+					break;
+				case NEW:
+					uri = new URI(uriBase);
+					if (desc.isInUserSpace) {
+						uri.setQueryValue(Config.PARAM_USERSPACE, "true");
+					}
+					break;
+				case PUBLISH:
+					uri = new URI(uriBase + "/" + desc.id + "/publish");
+					//never a user param for publish 
+					break;
+				default:
+					throw new Error("Invalid upload action " + uploadAction + ", upload cancelled.");
+			}
+			return uri;
+		}
+
+		private function createByteArray(data:String):ByteArray {
+			var result:ByteArray = null;
+			if (data != null) {
+				result = new ByteArray();
+				result.writeUTFBytes(data);
+				result.position = 0;
+			}
+			return result
+		}
+
+		private function submit(description:ItemDescription, data:ByteArray, uri:URI):void {
+			message = "";
+			try {
+				if (data != null) {
+					var params:URLVariables = new URLVariables();
+					ml.addVariable("description", description.description);
+					ml.addVariable("name", description.name);
+					ml.addVariable("domainName", description.domainName);
+					ml.addVariable("group", description.groupName);
+					ml.addFile(data, description.name + ".xml", "data");
+					ml.load(uri.toString());
+				} else {
+					// Cannot sent data that is not a file with FileReference.upload so just load the data and then submit through HttpClient.
+					// FileReference also does not handle authentication tokens.
+					startUploadHandler();
+					if (fileRef.data == null) {
+						//only load if not loaded before otherwise sent the already loaded file. You can only force a reload of the file by selecting it again (it is a flash thingy).
+						fileRef.addEventListener(Event.COMPLETE, function(event:Event):void {
+								submit(description, fileRef.data, uri);
+							});
+						fileRef.load();
+					} else {
+						submit(description, fileRef.data, uri);
+					}
+				}
+			} catch (error:Error) {
+				trace("Unable to upload file. Error: " + error);
+				CursorManager.removeBusyCursor();
+				throw error;
+			}
+		}
+		
+		/**
+		 * Resets upload service, removes any remaining file reference, unsets selected file, and makes progress invisible  
+		 **/
+		public function reset():void{
+			createAndInitFileReference();
+			selectedFile = "";
+			pb.visible = false;
+		}
+
+		public function selectXmlFile(event:Event):void {
+			createAndInitFileReference();
+			var filter:FileFilter = new FileFilter("Xml Files (*.xml)", "*.xml");
+			fileRef.browse(new Array(filter));
+		}
+
+		private function selectHandler(event:Event):void {
+			selectedFile = fileRef.name;
+			message = "";
+			pb.visible = false;
+			if (_loadBeforeUploading) {
+				fileRef.load();
+			}
+		}
+
+		private function fileLoadedHandler(event:Event):void {
+			dispatchEvent(new FileLoadedEvent(fileRef));
+		}
+
+		private function completeHandler(event:Event):void {
+			uploadComplete();
+			var response:XML = new XML(ml.loader.data);
+			handleResponse(response);
+		}
+
+		private function httpStatusHandler(event:HTTPStatusEvent):void {
+			if (event.status != 200) {
+				addToMessage("Server Failed to handle registration. Unexpected error, try again later. (httpstatus code was: " + event.status + ")\n");
+			}
+			CursorManager.removeBusyCursor();
+		}
+
+		private function securityErrorHandler(event:SecurityErrorEvent):void {
+			addToMessage("Server Failed to handle registration. Unexpected error, try again later. (error: " + event.text + ")\n");
+			CursorManager.removeBusyCursor();
+		}
+
+		private function ioErrorHandler(event:IOErrorEvent):void {
+			addToMessage("Unable to load file. (error: " + event.text + ")\n");
+			CursorManager.removeBusyCursor();
+		}
+
+		private function progressHandler(event:ProgressEvent):void {
+			trace("Uploading: " + event.bytesLoaded + "/" + event.bytesTotal);
+			pb.setProgress(event.bytesLoaded, event.bytesTotal);
+		}
+
+		private function startUploadHandler():void {
+			trace("uploading start");
+			pb.label = "uploading %3%%";
+			pb.visible = true;
+			pb.includeInLayout = true;
+		}
+
+		private function handleResponse(response:XML):void {
+			if (response.@registered == true) {
+				var item:ItemDescription = new ItemDescription();
+				var isInUserSpace:Boolean = response.@isInUserSpace == true;
+				if (response.@isProfile == true) {
+					item.createProfile(response.description[0], isInUserSpace);
+				} else {
+					item.createComponent(response.description[0], isInUserSpace);
+				}
+				dispatchEvent(new UploadCompleteEvent(item));
+			} else {
+				createErrorMessage(response);
+			}
+		}
+
+		private function uploadComplete():void {
+			pb.label = "Upload complete";
+			pb.setProgress(100, 100);
+			CursorManager.removeBusyCursor();
+		}
+
+		private function createErrorMessage(response:XML):void {
+			addToMessage("Failed to register:");
+			var errors:XMLList = response.errors.error;
+			for each (var error:XML in errors) {
+				message += " - " + error.toString() + "\n";
+			}
+		}
+
+		private function addToMessage(text:String):void {
+			message += text;
+		}
+
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SearchBox.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SearchBox.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SearchBox.as	(revision 1843)
@@ -0,0 +1,92 @@
+/*
+	Copyright (c) 2006 Narciso Jaramillo <nj_flex@rictus.com>
+	
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files (the "Software"),
+	to deal in the Software without restriction, including without limitation 
+	the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+	and/or sell copies of the Software, and to permit persons to whom the 
+	Software is furnished to do so, subject to the following conditions:
+	
+	The above copyright notice and this permission notice shall be included 
+	in all copies or substantial portions of the Software.
+	
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
+	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
+	IN THE SOFTWARE.
+*/
+
+package com.rictus.controls
+{
+	import mx.containers.HBox;
+	import mx.controls.Image;
+	import mx.controls.TextInput;
+	import flash.events.Event;
+	import flash.events.FocusEvent;
+
+	[Event(name="change", type="flash.events.Event")]
+	public class SearchBox extends HBox
+	{
+		[@Embed("assets/searchIcon.png")]
+		private const searchIcon: Class;
+		
+		private var _textInput: SelfLabelingTextInput;
+		private var _label: String;
+		
+		public function SearchBox() {}
+		
+		[Bindable]
+		public function get text(): String {
+			return _textInput.text;
+		}
+		public function set text(value: String): void {
+			_textInput.text = value;
+		}
+		
+		[Bindable]
+		override public function get label(): String {
+			return _label;
+		}
+		override public function set label(value: String): void {
+			_label = value;
+			if (_textInput != null) {
+				_textInput.label = value;
+			}
+		}
+
+		override protected function createChildren(): void {
+			super.createChildren();
+			
+			setStyle("borderStyle", "solid");
+			setStyle("backgroundColor", 0xffffff);
+			setStyle("horizontalGap", 0);
+			setStyle("paddingLeft", 3);
+			setStyle("paddingRight", 3);
+			setStyle("cornerRadius", 5);
+			setStyle("verticalAlign", "middle");
+			
+			var image: Image = new Image();
+			image.source = searchIcon;
+			addChild(image);
+			
+			_textInput = new SelfLabelingTextInput();
+			_textInput.setStyle("borderStyle", "none");
+			_textInput.setStyle("focusAlpha", 0);
+			_textInput.percentWidth = 100;
+			// This is a hack around the fact that we don't have baseline alignment.
+			// Without this, the text field doesn't center properly.
+			_textInput.height = 18;
+			_textInput.addEventListener(Event.CHANGE, handleTextChange);
+			_textInput.label = _label;
+			addChild(_textInput);
+		}
+		
+		private function handleTextChange(event: Event): void {
+			callLater(dispatchEvent, [new Event(Event.CHANGE)]);
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SelfLabelingTextInput.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SelfLabelingTextInput.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/com/rictus/controls/SelfLabelingTextInput.as	(revision 1843)
@@ -0,0 +1,117 @@
+/*
+	Copyright (c) 2006 Narciso Jaramillo <nj_flex@rictus.com>
+	
+	Permission is hereby granted, free of charge, to any person obtaining
+	a copy of this software and associated documentation files (the "Software"),
+	to deal in the Software without restriction, including without limitation 
+	the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+	and/or sell copies of the Software, and to permit persons to whom the 
+	Software is furnished to do so, subject to the following conditions:
+	
+	The above copyright notice and this permission notice shall be included 
+	in all copies or substantial portions of the Software.
+	
+	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
+	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
+	IN THE SOFTWARE.
+*/
+
+package com.rictus.controls
+{
+	import mx.controls.TextInput;
+	import flash.events.FocusEvent;
+
+	/**
+	 * A text input that displays a gray label inside itself when it's empty.  When the user clicks in,
+	 * the label disappears.  If the user exits the field and leaves it empty, the label reappears.
+	 * 
+	 * TODO: get the label color from a style instead of hard-coding it.
+	 *
+	 * @author Narciso Jaramillo <nj_flex@rictus.com>
+	 */
+	 
+	public class SelfLabelingTextInput extends TextInput
+	{
+		private var _textIsEmpty: Boolean = true;
+		private var _label: String;
+		
+		public function SelfLabelingTextInput() {}
+		
+		/**
+		 * The label to display when the text field is empty.
+		 */
+		public function get label(): String {
+			return _label;
+		}
+		
+		public function set label(value: String): void {
+			_label = value;
+			toolTip = value;
+			updateContents();
+		}
+		
+		[Bindable]
+		override public function get text(): String {
+			if (_textIsEmpty) {
+				return "";
+			}
+			else {
+				return super.text;
+			}
+		}
+		
+		override public function set text(value: String): void {
+			if (value == "") {
+				_textIsEmpty = true;
+			}
+			else {
+				_textIsEmpty = false;
+				super.text = value;
+			}
+			updateContents();
+		}
+		
+		private function updateContents(): void {
+			if (_textIsEmpty) {
+				setStyle("color", 0xaaaaaa);
+				super.text = _label;
+			}
+			else {
+				setStyle("color", 0x000000);
+			}
+		}
+
+		
+		private function handleTextChange(event: Event): void {
+			if (super.text == "") {
+				_textIsEmpty = true;
+			}
+			else {
+				_textIsEmpty = false;
+			}
+		}
+		
+		private function handleFocusIn(event: FocusEvent): void {
+			if (_textIsEmpty) {
+				super.text = "";
+				setStyle("color", 0x000000);
+			}
+		}
+		
+		private function handleFocusOut(event: FocusEvent): void {
+			updateContents();
+		}
+		
+		override public function initialize(): void {
+			super.initialize();
+			addEventListener(Event.CHANGE, handleTextChange);
+			addEventListener(FocusEvent.FOCUS_IN, handleFocusIn);
+			addEventListener(FocusEvent.FOCUS_OUT, handleFocusOut);
+			updateContents();
+		}
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/main.mxml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/main.mxml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/main.mxml	(revision 1843)
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
+				xmlns:common="clarin.cmdi.componentregistry.common.components.*"
+				layout="absolute"
+				preinitialize="init();"
+				applicationComplete="appComplete();"
+				backgroundColor="#DDE3EF">
+	<mx:Style source="/assets/css/main.css"/>
+	<mx:Script>
+		<![CDATA[
+			import clarin.cmdi.componentregistry.common.AboutPopup;
+			import clarin.cmdi.componentregistry.common.Credentials;
+			import clarin.cmdi.componentregistry.services.Config;
+			import clarin.cmdi.componentregistry.services.PingSessionService;
+			
+			import com.flexspy.FlexSpy;
+			
+			import flash.utils.getTimer;
+			
+			import mx.containers.Box;
+			import mx.controls.Alert;
+			import mx.controls.Button;
+			import mx.core.UIComponent;
+			import mx.core.mx_internal;
+			import mx.events.FlexEvent;
+			import mx.managers.PopUpManager;
+			
+			import org.hasseg.externalMouseWheel.ExternalMouseWheelSupport;
+
+			private var sessionPinger:PingSessionService;
+			[Bindable]
+			private var aboutMenu:ContextMenu;
+			
+			
+			private function init():void{
+				this.contextMenu = createMenu();
+				initializeInstances();
+			}
+			
+			private function initializeInstances():void {
+				Credentials.create(Application.application.parameters);
+				Config.create(Application.application.parameters);				
+			}
+			
+			private function createMenu():ContextMenu{
+				var menu:ContextMenu = new ContextMenu();
+				var item:ContextMenuItem = new ContextMenuItem("About Clarin Component Registry");
+				item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, showAbout);
+				menu.customItems = [item];
+				menu.hideBuiltInItems();
+				return menu;
+			}
+			
+			private function showAbout(event:ContextMenuEvent):void{
+				var aboutBox:AboutPopup = new AboutPopup();
+				aboutBox.x = appPanel.width/2 - aboutBox.width/2;
+				aboutBox.y = appPanel.height/2 - aboutBox.height/2;
+				PopUpManager.addPopUp(aboutBox, event.mouseTarget);
+			}
+
+			private function appComplete():void {
+				ExternalMouseWheelSupport.getInstance(stage);
+				sessionPinger = PingSessionService.INSTANCE
+				sessionPinger.startPinging();
+				if (Credentials.instance.isLoggedIn() && (Config.instance.space == Config.SPACE_USER)) {
+					Config.instance.userSpace = true;
+				}
+				viewStack.loadStartup();
+				
+				if(Config.instance.debug){
+					var flexSpyButton:Button = new Button();
+					flexSpyButton.label="FlexSpy";
+					flexSpyButton.addEventListener(MouseEvent.CLICK,showFlexSpy);
+					topBar.addChild(flexSpyButton);
+				}
+			}
+			
+			private function showFlexSpy(event:Event):void{
+				FlexSpy.show();
+			}
+
+		]]>
+	</mx:Script>
+
+	<mx:Panel id="appPanel" width="100%"
+			  height="100%"
+			  layout="absolute"
+			  title="Clarin Component Browser"
+			  x="0"
+			  y="0">			  
+
+		<mx:VBox height="100%"
+				 width="100%">
+			<mx:HBox borderStyle="none" id="topBar"
+					 width="100%">
+				<mx:ToggleButtonBar id="toggleBar"
+									dataProvider="{viewStack}"/>
+				<mx:Spacer width="90%"/>
+				<mx:Label text="User: {Credentials.instance.userName}"/>
+				<common:LoginLabelButton id="login" includeInLayout="{!Credentials.instance.isLoggedIn()}" visible="{!Credentials.instance.isLoggedIn()}" />
+				<common:UserSettingsLabelButton id="userSettings" includeInLayout="{Credentials.instance.isLoggedIn()}" visible="{Credentials.instance.isLoggedIn()}"/>
+			</mx:HBox>
+			<common:RegistryViewStack id="viewStack"
+									  borderStyle="none"
+									  height="100%"
+									  width="100%"/>
+		</mx:VBox>
+	</mx:Panel>
+		
+</mx:Application>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/org/hasseg/externalMouseWheel/ExternalMouseWheelSupport.as	(revision 1843)
@@ -0,0 +1,478 @@
+﻿/*
+This code is licensed under the MIT License:
+
+Copyright (c) 2007 Ali Rantakari
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+package org.hasseg.externalMouseWheel
+{
+	
+	import flash.display.DisplayObject;
+	import flash.display.DisplayObjectContainer;
+	import flash.display.InteractiveObject;
+	import flash.display.Stage;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.MouseEvent;
+	import flash.external.ExternalInterface;
+	import flash.geom.Point;
+	
+	
+	/**
+	* Implements mouse wheel support for OS X.
+	* This is done by catching mouse wheel events in JavaScript through the
+	* ExternalInterface, finding the topmost InteractiveObject under the mouse
+	* and making it dispatch the as MouseEvents. 
+	* 
+	* @author Ali Rantakari ( http://hasseg.org/blog ) - Feel free to use, given that this notice stays intact
+	* @author Pavel fljot ( http://inreflected.com ) - a couple of changes + pure AS3-projects support (v1.5)
+	*/
+	public final class ExternalMouseWheelSupport extends EventDispatcher
+	{
+		/*
+		* Purposefully non-AsDoc'd Changelog:
+		* 
+		* ---------------------------------------------------------------------------------
+		* VERSION 1.0 (Ali Rantakari)
+		* July 2007
+		* 
+		* - Initial implementation
+		* 
+		* 
+		* ---------------------------------------------------------------------------------
+		* VERSION 1.5 (Changes by Pavel fljot, http://inreflected.com)
+		* Jan 2008
+		* 
+		* 1. initialization by getInstance(stage:Stage) method, that gets reference to the Stage;
+		* 2. getAllInteractiveObjectsOnStage() is renamed to getMouseEnabledInteractiveObjectsOnStage()
+		*    and returns only objects that are really listening to the mouse at the moment;
+		* 3. added filtration into getRegisteredObjects() method for _manuallyRegisteredObjects
+		*    (for same purposes as getMouseEnabledInteractiveObjectsOnStage() ).
+		* 
+		* 
+		* ---------------------------------------------------------------------------------
+		* VERSION 2.0 (Changes by Ali Rantakari)
+		* Apr 2008
+		* 
+		* - Some minor code cleanup (both syntax & implementation -- tried to make
+		*   the code a bit more readable and clear)
+		* - Some minor fixes & additions in comments (for the same purpose as above)
+		* - Renamed some methods to better depict what they do
+		* - Removed try/catch block from initJSConnection() (formerly initialize()) in order to
+		*   let the errors be propagated onwards instead of hiding them in the log
+		* - Made getInstance() throw an error if the aStage parameter is null
+		* - Used flash.events.MouseEvent instead of our own mouse event class
+		*   (can't remember why I did that in the first place..?)
+		* - Added support for modifier keys (ctrl (i.e. command on a Mac,) alt, shift)
+		* - Added an another method for determining the InteractiveObject under mouse
+		*   to dispatch the wheel event, courtesy of pixelbreaker.com's solution. Also
+		*   added a property for selecting which one of these methods to use
+		* - Removed option for manual registration of objects (if one wants to exclude
+		*   an object from mouse events, they should use the mouseEnabled property)
+		* - Added property "initialized"
+		* 
+		*/
+		
+		
+		/**
+		* A possible value for <code>dispatchingObjectDeterminationMethod</code>.
+		* 
+		* @see #dispatchingObjectDeterminationMethod
+		*/
+		public static const COPY_MOUSEMOVE_EVENTS:uint = 0;
+		/**
+		* A possible value for <code>dispatchingObjectDeterminationMethod</code>.
+		* 
+		* @see #dispatchingObjectDeterminationMethod
+		*/
+		public static const TRAVERSE_DISPLAY_LIST:uint = 1;
+		
+		
+		private static var _stage:Stage;		
+		
+		private var _initialized:Boolean = false;
+		
+		private var _dispatchingObjectDeterminationMethod:uint = COPY_MOUSEMOVE_EVENTS; // default
+		private var _lastMoveEventTarget:InteractiveObject = null;
+		private var _lastMoveEventLocalCoords:Point = null;
+		
+		
+		
+		
+		
+		// BEGIN: singleton pattern implementation			----------------------------------------------------------- 
+		
+		private static var _INSTANCE:ExternalMouseWheelSupport = null;
+		
+		/**
+		* @private
+		*/
+		public function ExternalMouseWheelSupport(aSingletonEnforcer:SingletonEnforcer):void
+		{
+			if (_INSTANCE != null)
+			{
+				throw new Error("You can't create more than one instance of this class because it is a singleton. Use ExternalMouseWheelSupport.instance to get a handle to it.");
+			}
+			else
+			{
+				_lastMoveEventLocalCoords = new Point(0,0);
+				dispatchingObjectDeterminationMethod = _dispatchingObjectDeterminationMethod; // call setter to attach listener if applicable
+				initJSConnection();
+			}
+		}
+		
+		/**
+		* Returns the reference to the singleton instance of this class
+		* 
+		* @param aStage		Reference to the Stage object (required!)
+		* 
+		* @return			Reference to the singleton instance of this class
+		*/
+		public static function getInstance(aStage:Stage):ExternalMouseWheelSupport
+		{
+			if (aStage == null)
+				throw new Error("aStage property can not be null");
+			else
+			{
+				_stage = aStage;
+				if (_INSTANCE == null) _INSTANCE = new ExternalMouseWheelSupport(new SingletonEnforcer());
+				return _INSTANCE;
+			}
+		}
+		
+		// --end--: singleton pattern implementation		- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		// BEGIN: private methods			----------------------------------------------------------- 
+		
+		
+		// initialize the JavaScript connection:
+		// - add ExternalInterface callback so JavaScript can send us the wheel events
+		// - call the mw_initialize() JavaScript function
+		private function initJSConnection():void
+		{
+			if (ExternalInterface.available)
+			{
+				ExternalInterface.addCallback("dispatchExternalMouseWheelEvent", externalMouseWheelEventHandler);
+				_initialized = ExternalInterface.call("extMouseWheel.initCaptureFor", ExternalInterface.objectID);
+				dispatchEvent(new Event("initializedChanged"));
+			}
+		}
+		
+		
+		// handler for the calls coming from JavaScript
+		private function externalMouseWheelEventHandler(aDelta:int, aX:Number, aY:Number, aCtrlKey:Boolean, aAltKey:Boolean, aShiftKey:Boolean, aButtonDown:Boolean):void
+		{
+			var mouseEvent:MouseEvent;
+			
+			if (_dispatchingObjectDeterminationMethod == COPY_MOUSEMOVE_EVENTS)
+			{
+				if (_lastMoveEventTarget != null)
+				{
+					mouseEvent = 
+						new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false,
+										_lastMoveEventLocalCoords.x, _lastMoveEventLocalCoords.y,
+										null, //relatedObject -- doesn't apply here
+										aCtrlKey, aAltKey, aShiftKey, aButtonDown, aDelta);
+					_lastMoveEventTarget.dispatchEvent(mouseEvent);
+				}
+			}
+			else if (_dispatchingObjectDeterminationMethod == TRAVERSE_DISPLAY_LIST)
+			{
+				var iaObjs:Array = getMouseEnabledInteractiveObjectsOnStage();
+				
+				if (iaObjs.length > 0)
+				{
+					// see which ones pass a hittest with the mouse cursor
+					var hitTestObjs:Array = iaObjs.filter(function(aItem:*, aIndex:int, aArray:Array):Boolean {
+						return (aItem.hitTestPoint(aX,aY,true));
+					});
+					
+					// create array of hittest-passing objects and their levels in the displaylist
+					var rObjs:Array = getDisplayListLevelsFor(hitTestObjs);
+					
+					// see which ones of the remaining are highest in the displaylist
+					var highestLevel:uint = 0;
+					for (var m:uint = 0; m < rObjs.length; m++)
+					{
+						if (rObjs[m].level > highestLevel) highestLevel = rObjs[m].level;
+					}
+					var onTheHighestLevel:Array = rObjs.filter(function(aItem:*, aIndex:int, aArray:Array):Boolean {
+						return (aItem.level == highestLevel);
+					});
+					
+					// pick the last one from the ones that have the highest level
+					var highestInDisplayList:Object = {object:null, level:(-10000)};
+					for (var n:uint = 0; n < onTheHighestLevel.length; n++)
+					{
+						if (onTheHighestLevel[n].level > highestInDisplayList.level) highestInDisplayList = onTheHighestLevel[n];
+					}
+					
+					// make it dispatch a MouseEvent.MOUSE_WHEEL event
+					if (highestInDisplayList.object != null)
+					{
+						if (highestInDisplayList.object.dispatchEvent)
+						{
+							//var mouseEvent:ExternalMouseWheelEvent = new ExternalMouseWheelEvent(ExternalMouseWheelEvent.MOUSE_WHEEL, aDelta, aX, aY);
+							var localCoords:Point = highestInDisplayList.object.globalToLocal(new Point(aX, aY));
+							mouseEvent = 
+								new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false,
+												localCoords.x, localCoords.y,
+												null, //relatedObject -- doesn't apply here
+												aCtrlKey, aAltKey, aShiftKey, aButtonDown, aDelta);
+							highestInDisplayList.object.dispatchEvent(mouseEvent);
+						}
+					}
+				}
+			}
+		}
+		
+		
+		
+		// save topmost InteractiveObject on stage under mouse
+		private function stageMouseMoveHandler(event:MouseEvent):void
+		{
+			_lastMoveEventTarget = InteractiveObject(event.target);
+			_lastMoveEventLocalCoords.x = event.localX;
+			_lastMoveEventLocalCoords.y = event.localY;
+		}
+		
+		
+		
+		
+		
+		
+		
+		
+		/**
+		* Returns an array of Objects, specifying the display list levels
+		* for a specified array of DisplayObjects. The return Object will
+		* be in the following format:
+		* 
+		* <code>{object:<DisplayObject>, level:<uint>}</code>
+		* 
+		* @param aObjs		An array of DisplayObjects
+		* 
+		* @return			An array of Objects, containing the
+		*					objects and their levels in the DisplayList
+		*/
+		private function getDisplayListLevelsFor(aObjs:Array):Array
+		{
+			var objs:Array = new Array();
+			
+			if (aObjs.length > 0)
+			{
+				if (aObjs[0].stage != null)
+				{
+					objs = travelDisplayList(aObjs[0].stage);
+					var currLevel:uint = 0;
+					
+					function travelDisplayList(container:DisplayObjectContainer):Array
+					{
+						var retArr:Array = new Array();
+						var child:DisplayObject;
+						for (var i:uint=0; i < container.numChildren; i++)
+						{
+							currLevel++;
+							child = container.getChildAt(i);
+							if (aObjs.indexOf(child) != (-1)) retArr.push({object:child, level:currLevel});
+							if (container.getChildAt(i) is DisplayObjectContainer)
+							{
+								var grandChildren:Array = travelDisplayList(DisplayObjectContainer(child));
+								for (var j:uint = 0; j < grandChildren.length; j++)
+									retArr.push(grandChildren[j]);
+							}
+						}
+						return retArr;
+					}
+				}
+			}
+			
+			return objs;
+		}
+		
+		
+		
+		
+		// returns all the InteractiveObjects on stage that are able to
+		// dispatch mouse events
+		private function getMouseEnabledInteractiveObjectsOnStage():Array
+		{
+			var objs:Array = new Array();
+			
+			objs = travelDisplayList(_stage);
+			
+			function travelDisplayList(container:DisplayObjectContainer):Array
+			{
+				var retArr:Array = new Array();
+				var child:DisplayObject;
+				for (var i:uint=0; i < container.numChildren; i++)
+				{
+					child = container.getChildAt(i);
+					if (child is InteractiveObject)
+					{
+						if (!child.visible)
+							continue;
+						
+						if ((child as InteractiveObject).mouseEnabled)
+							retArr.push(child);
+						
+						// fljot: get children only if they are mouse-enabled. otherwise no need to scan them
+						if (child is DisplayObjectContainer && (child as DisplayObjectContainer).mouseChildren)
+						{
+							var grandChildren:Array = travelDisplayList(DisplayObjectContainer(child));
+							for (var j:uint = 0; j < grandChildren.length; j++)
+								retArr.push(grandChildren[j]);
+						}
+					}
+				}
+				return retArr;
+			}
+			
+			return objs;
+		}
+		
+		
+		
+		// checks whether a given object is "mouse-enabled" -- i.e. if it's supposed
+		// to be able to dispatch mouse events.
+		private function objectIsMouseEnabled(aObj:InteractiveObject, aCheckMouseEnabledProperty:Boolean = true):Boolean
+		{
+			var isEnabled:Boolean = true;
+			
+			if (!aObj.visible || (aCheckMouseEnabledProperty && !aObj.mouseEnabled))
+				isEnabled = false;
+			
+			if (isEnabled && aObj.parent)
+			{
+				// fljot: need to check parents if they are visible
+				if (!(aObj.parent as DisplayObjectContainer).mouseChildren)
+					isEnabled = false;
+				else
+					isEnabled = objectIsMouseEnabled(aObj.parent, false);
+			}
+			
+			return isEnabled;
+		}
+		
+		// --end--: private methods		- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		
+		// BEGIN: public methods			----------------------------------------------------------- 
+		
+		
+		/**
+		* Specifies the method of determining the InteractiveObject that will
+		* be called to dispatch the external mouse wheel events received from
+		* JavaScript.
+		* 
+		* <p>The possible values are:</p>
+		* <table class="innertable">
+		* <tr>	<th>Constant to use</th><th>Description</th></tr>
+		* <tr>	<td>ExternalMouseWheelSupport.COPY_MOUSEMOVE_EVENTS</td>
+		* 		<td>
+		* 		With this method, a <code>mouseMove</code> event listener will be
+		* 		added to the Stage and the object to dispatch a mouse wheel
+		* 		event when one arrives via JavaScript will be the same one
+		* 		that was the target for the last such <code>mouseMove</code>
+		* 		event.
+		* 		</td></tr>
+		* <tr>	<td>ExternalMouseWheelSupport.TRAVERSE_DISPLAY_LIST</td>
+		* 		<td>
+		* 		With this method, each time a mouse wheel event arrives via
+		* 		JavaScript the object to dispatch the event will be determined
+		* 		by traversing the display list hierarchy and finding the
+		* 		topmost matching object under the mouse cursor.
+		* 		</td></tr>
+		* </table>
+		* 
+		* @see #COPY_MOUSEMOVE_EVENTS
+		* @see #TRAVERSE_DISPLAY_LIST
+		*/
+		public function get dispatchingObjectDeterminationMethod():uint
+		{
+			return _dispatchingObjectDeterminationMethod;
+		}
+		/**
+		* @private
+		*/
+		public function set dispatchingObjectDeterminationMethod(aVal:uint):void
+		{
+			if (aVal != COPY_MOUSEMOVE_EVENTS && aVal != TRAVERSE_DISPLAY_LIST)
+				return;
+			
+			if (aVal == COPY_MOUSEMOVE_EVENTS && _stage != null)
+				_stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false, 0, true);
+			else if (aVal == COPY_MOUSEMOVE_EVENTS && _stage != null)
+				_stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false);
+			
+			_dispatchingObjectDeterminationMethod = aVal;
+		}
+		
+		
+		
+		/**
+		* Whether or not the external mouse wheel support has been
+		* successfully initialized. Note that an unsuccessful initialization
+		* might mean that the support is simply not needed (i.e. if running
+		* in Windows Flash Player in a browser other than Safari.)
+		*/
+		[Bindable(event="initializedChanged")]
+		public function get initialized():Boolean
+		{
+			return _initialized;
+		}
+		
+		
+		
+		// --end--: public methods		- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+		
+		
+	}
+	
+	
+}
+
+class SingletonEnforcer {}
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/MultipartURLLoader.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/MultipartURLLoader.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/MultipartURLLoader.as	(revision 1843)
@@ -0,0 +1,592 @@
+﻿package ru.inspirit.net
+{
+	import flash.errors.IllegalOperationError;
+	import flash.events.Event;
+	import flash.events.EventDispatcher;
+	import flash.events.HTTPStatusEvent;
+	import flash.events.IOErrorEvent;
+	import flash.events.ProgressEvent;
+	import flash.events.SecurityErrorEvent;
+	import flash.net.URLLoader;
+	import flash.net.URLLoaderDataFormat;
+	import flash.net.URLRequest;
+	import flash.net.URLRequestHeader;
+	import flash.net.URLRequestMethod;
+	import flash.utils.ByteArray;
+	import flash.utils.Dictionary;
+	import flash.utils.Endian;
+	import flash.utils.clearInterval;
+	import flash.utils.setTimeout;
+	
+	import ru.inspirit.net.events.MultipartURLLoaderEvent;
+
+	/**
+	 * Multipart URL Loader
+	 *
+	 * Original idea by Marston Development Studio - http://marstonstudio.com/?p=36
+	 *
+	 * History
+	 * 2009.01.15 version 1.0
+	 * Initial release
+	 *
+	 * 2009.01.19 version 1.1
+	 * Added options for MIME-types (default is application/octet-stream)
+	 *
+	 * 2009.01.20 version 1.2
+	 * Added clearVariables and clearFiles methods
+	 * Small code refactoring
+	 * Public methods documentaion
+	 *
+	 * 2009.02.09 version 1.2.1
+	 * Changed 'useWeakReference' to false (thanx to zlatko)
+	 * It appears that on some servers setting 'useWeakReference' to true
+	 * completely disables this event
+	 * 
+	 * 2009.03.05 version 1.3
+	 * Added Async property. Now you can prepare data asynchronous before sending it. 
+	 * It will prevent flash player from freezing while constructing request data.
+	 * You can specify the amount of bytes to write per iteration through BLOCK_SIZE static property.
+	 * Added events for asynchronous method.
+	 * Added dataFormat property for returned server data.
+	 * Removed 'Cache-Control' from headers and added custom requestHeaders array property.
+	 * Added getter for the URLLoader class used to send data.
+	 *
+	 * @author Eugene Zatepyakin
+	 * @version 1.3
+	 * @link http://blog.inspirit.ru/
+	 */
+	public class  MultipartURLLoader extends EventDispatcher
+	{
+		public static var BLOCK_SIZE:uint = 64 * 1024;
+		
+		private var _loader:URLLoader;
+		private var _boundary:String;
+		private var _variableNames:Array;
+		private var _fileNames:Array;
+		private var _variables:Dictionary;
+		private var _files:Dictionary;
+		
+		private var _async:Boolean = false;
+		private var _path:String;
+		private var _data:ByteArray;
+		
+		private var _prepared:Boolean = false;
+		private var asyncWriteTimeoutId:Number;
+		private var asyncFilePointer:uint = 0;
+		private var totalFilesSize:uint = 0;
+		private var writtenBytes:uint = 0;
+		
+		public var requestHeaders:Array;
+
+		public function MultipartURLLoader()
+		{
+			_fileNames = new Array();
+			_files = new Dictionary();
+			_variableNames = new Array();
+			_variables = new Dictionary();
+			_loader = new URLLoader();
+			requestHeaders = new Array();
+		}
+
+		/**
+		 * Start uploading data to specified path
+		 *
+		 * @param	path	The server script path
+		 * @param	async	Set to true if you are uploading huge amount of data
+		 */
+		public function load(path:String, async:Boolean = false):void
+		{
+			if (path == null || path == '') throw new IllegalOperationError('You cant load without specifing PATH');
+			
+			_path = path;
+			_async = async;
+			
+			if (_async) {
+				if(!_prepared){
+					constructPostDataAsync();
+				} else {
+					doSend();
+				}
+			} else {
+				_data = constructPostData();
+				doSend();
+			}
+		}
+		
+		/**
+		 * Start uploading data after async prepare
+		 */
+		public function startLoad():void
+		{
+			if ( _path == null || _path == '' || _async == false ) throw new IllegalOperationError('You can use this method only if loading asynchronous.');
+			if ( !_prepared && _async ) throw new IllegalOperationError('You should prepare data before sending when using asynchronous.');
+			
+			doSend();
+		}
+		
+		/**
+		 * Prepare data before sending (only if you use asynchronous)
+		 */
+		public function prepareData():void
+		{
+			constructPostDataAsync();
+		}
+
+		/**
+		 * Stop loader action
+		 */
+		public function close():void
+		{
+			try {
+				_loader.close();
+			} catch( e:Error ) { }
+		}
+
+		/**
+		 * Add string variable to loader
+		 * If you have already added variable with the same name it will be overwritten
+		 *
+		 * @param	name	Variable name
+		 * @param	value	Variable value
+		 */
+		public function addVariable(name:String, value:Object = ''):void
+		{
+			if (_variableNames.indexOf(name) == -1) {
+				_variableNames.push(name);
+			}
+			_variables[name] = value;
+			_prepared = false;
+		}
+
+		/**
+		 * Add file part to loader
+		 * If you have already added file with the same fileName it will be overwritten
+		 *
+		 * @param	fileContent	File content encoded to ByteArray
+		 * @param	fileName	Name of the file
+		 * @param	dataField	Name of the field containg file data
+		 * @param	contentType	MIME type of the uploading file
+		 */
+		public function addFile(fileContent:ByteArray, fileName:String, dataField:String = 'Filedata', contentType:String = 'application/octet-stream'):void
+		{
+			if (_fileNames.indexOf(fileName) == -1) {
+				_fileNames.push(fileName);
+				_files[fileName] = new FilePart(fileContent, fileName, dataField, contentType);
+				totalFilesSize += fileContent.length;
+			} else {
+				var f:FilePart = _files[fileName] as FilePart;
+				totalFilesSize -= f.fileContent.length;
+				f.fileContent = fileContent;
+				f.fileName = fileName;
+				f.dataField = dataField;
+				f.contentType = contentType;
+				totalFilesSize += fileContent.length;
+			}
+			
+			_prepared = false;
+		}
+
+		/**
+		 * Remove all variable parts
+		 */
+		public function clearVariables():void
+		{
+			_variableNames = new Array();
+			_variables = new Dictionary();
+			_prepared = false;
+		}
+
+		/**
+		 * Remove all file parts
+		 */
+		public function clearFiles():void
+		{
+			for each(var name:String in _fileNames)
+			{
+				(_files[name] as FilePart).dispose();
+			}
+			_fileNames = new Array();
+			_files = new Dictionary();
+			totalFilesSize = 0;
+			_prepared = false;
+		}
+
+		/**
+		 * Dispose all class instance objects
+		 */
+		public function dispose(): void
+		{
+			clearInterval(asyncWriteTimeoutId);
+			removeListener();
+			close();
+
+			_loader = null;
+			_boundary = null;
+			_variableNames = null;
+			_variables = null;
+			_fileNames = null;
+			_files = null;
+			requestHeaders = null;
+			_data = null;
+		}
+
+		/**
+		 * Generate random boundary
+		 * @return	Random boundary
+		 */
+		public function getBoundary():String
+		{
+			if (_boundary == null) {
+				_boundary = '';
+				for (var i:int = 0; i < 0x20; i++ ) {
+					_boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
+				}
+			}
+			return _boundary;
+		}
+		
+		public function get ASYNC():Boolean
+		{
+			return _async;
+		}
+		
+		public function get PREPARED():Boolean
+		{
+			return _prepared;
+		}
+		
+		public function get dataFormat():String
+		{
+			return _loader.dataFormat;
+		}
+		
+		public function set dataFormat(format:String):void
+		{
+			if (format != URLLoaderDataFormat.BINARY && format != URLLoaderDataFormat.TEXT && format != URLLoaderDataFormat.VARIABLES) {
+				throw new IllegalOperationError('Illegal URLLoader Data Format');
+			}
+			_loader.dataFormat = format;
+		}
+		
+		public function get loader():URLLoader
+		{
+			return _loader;
+		}
+		
+		private function doSend():void
+		{
+			var urlRequest:URLRequest = new URLRequest();
+			urlRequest.url = _path;
+			
+			/*
+			* Change patdui (MPI).
+			* Set the contenttype in the request header otherwie we get an error like:
+            *   'SecurityError: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.'
+            * See for instance: http://stackoverflow.com/questions/1270347/unexpected-flash-security-exception-when-using-urlloader for the explanation and solution.
+			*/			
+			//urlRequest.contentType = 'multipart/form-data; boundary=' + getBoundary();
+            urlRequest.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + getBoundary())); 
+
+			urlRequest.method = URLRequestMethod.POST;
+			urlRequest.data = _data;
+			
+			if (requestHeaders.length && requestHeaders != null){
+				urlRequest.requestHeaders = requestHeaders.concat();
+			}
+			
+			addListener();
+			
+			_loader.load(urlRequest);
+		}
+		
+		private function constructPostDataAsync():void
+		{
+			clearInterval(asyncWriteTimeoutId);
+
+			_data = new ByteArray();
+			_data.endian = Endian.BIG_ENDIAN;
+			
+			_data = constructVariablesPart(_data);
+			
+			asyncFilePointer = 0;
+			writtenBytes = 0;
+			_prepared = false;
+			if (_fileNames.length) {
+				nextAsyncLoop();
+			} else {
+				_data = closeDataObject(_data);
+				_prepared = true;
+				dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_COMPLETE) );
+			}
+		}
+
+		private function constructPostData():ByteArray
+		{
+			var postData:ByteArray = new ByteArray();
+			postData.endian = Endian.BIG_ENDIAN;
+
+			postData = constructVariablesPart(postData);
+			postData = constructFilesPart(postData);
+			
+			postData = closeDataObject(postData);
+			
+			return postData;
+		}
+		
+		private function closeDataObject(postData:ByteArray):ByteArray
+		{
+			postData = BOUNDARY(postData);
+			postData = DOUBLEDASH(postData);
+			return postData;
+		}
+
+		private function constructVariablesPart(postData:ByteArray):ByteArray
+		{
+			var i:uint;
+			var bytes:String;
+
+			for each(var name:String in _variableNames)
+			{
+				postData = BOUNDARY(postData);
+				postData = LINEBREAK(postData);
+				bytes = 'Content-Disposition: form-data; name="' + name + '"';
+				for ( i = 0; i < bytes.length; i++ ) {
+					postData.writeByte( bytes.charCodeAt(i) );
+				}
+				postData = LINEBREAK(postData);
+				postData = LINEBREAK(postData);
+				postData.writeUTFBytes(_variables[name]);
+				postData = LINEBREAK(postData);
+			}
+
+			return postData;
+		}
+
+		private function constructFilesPart(postData:ByteArray):ByteArray
+		{
+			var i:uint;
+			var bytes:String;
+			
+			if(_fileNames.length){
+				for each(var name:String in _fileNames)
+				{
+					postData = getFilePartHeader(postData, _files[name] as FilePart);
+					postData = getFilePartData(postData, _files[name] as FilePart);
+					postData = LINEBREAK(postData);
+				}
+				postData = closeFilePartsData(postData);
+			}
+			
+			return postData;
+		}
+		
+		private function closeFilePartsData(postData:ByteArray):ByteArray
+		{
+			var i:uint;
+			var bytes:String;
+			
+			postData = LINEBREAK(postData);
+			postData = BOUNDARY(postData);
+			postData = LINEBREAK(postData);
+			bytes = 'Content-Disposition: form-data; name="Upload"';
+			for ( i = 0; i < bytes.length; i++ ) {
+				postData.writeByte( bytes.charCodeAt(i) );
+			}
+			postData = LINEBREAK(postData);
+			postData = LINEBREAK(postData);
+			bytes = 'Submit Query';
+			for ( i = 0; i < bytes.length; i++ ) {
+				postData.writeByte( bytes.charCodeAt(i) );
+			}
+			postData = LINEBREAK(postData);
+			
+			return postData;
+		}
+		
+		private function getFilePartHeader(postData:ByteArray, part:FilePart):ByteArray
+		{
+			var i:uint;
+			var bytes:String;
+
+			postData = BOUNDARY(postData);
+			postData = LINEBREAK(postData);
+			bytes = 'Content-Disposition: form-data; name="Filename"';
+			for ( i = 0; i < bytes.length; i++ ) {
+				postData.writeByte( bytes.charCodeAt(i) );
+			}
+			postData = LINEBREAK(postData);
+			postData = LINEBREAK(postData);
+			postData.writeUTFBytes(part.fileName);
+			postData = LINEBREAK(postData);
+
+			postData = BOUNDARY(postData);
+			postData = LINEBREAK(postData);
+			bytes = 'Content-Disposition: form-data; name="' + part.dataField + '"; filename="';
+			for ( i = 0; i < bytes.length; i++ ) {
+				postData.writeByte( bytes.charCodeAt(i) );
+			}
+			postData.writeUTFBytes(part.fileName);
+			postData = QUOTATIONMARK(postData);
+			postData = LINEBREAK(postData);
+			bytes = 'Content-Type: ' + part.contentType;
+			for ( i = 0; i < bytes.length; i++ ) {
+				postData.writeByte( bytes.charCodeAt(i) );
+			}
+			postData = LINEBREAK(postData);
+			postData = LINEBREAK(postData);
+			
+			return postData;
+		}
+
+		private function getFilePartData(postData:ByteArray, part:FilePart):ByteArray
+		{
+			postData.writeBytes(part.fileContent, 0, part.fileContent.length);
+			
+			return postData;
+		}
+
+		private function onProgress( event: ProgressEvent ): void
+		{
+			dispatchEvent( event );
+		}
+
+		private function onComplete( event: Event ): void
+		{
+			removeListener();
+			dispatchEvent( event );
+		}
+
+		private function onIOError( event: IOErrorEvent ): void
+		{
+			removeListener();
+			dispatchEvent( event );
+		}
+
+		private function onSecurityError( event: SecurityErrorEvent ): void
+		{
+			removeListener();
+			dispatchEvent( event );
+		}
+
+		private function onHTTPStatus( event: HTTPStatusEvent ): void
+		{
+			dispatchEvent( event );
+		}
+
+		private function addListener(): void
+		{
+			_loader.addEventListener( Event.COMPLETE, onComplete, false, 0, false );
+			_loader.addEventListener( ProgressEvent.PROGRESS, onProgress, false, 0, false );
+			_loader.addEventListener( IOErrorEvent.IO_ERROR, onIOError, false, 0, false );
+			_loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, onHTTPStatus, false, 0, false );
+			_loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError, false, 0, false );
+		}
+
+		private function removeListener(): void
+		{
+			_loader.removeEventListener( Event.COMPLETE, onComplete );
+			_loader.removeEventListener( ProgressEvent.PROGRESS, onProgress );
+			_loader.removeEventListener( IOErrorEvent.IO_ERROR, onIOError );
+			_loader.removeEventListener( HTTPStatusEvent.HTTP_STATUS, onHTTPStatus );
+			_loader.removeEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
+		}
+
+		private function BOUNDARY(p:ByteArray):ByteArray
+		{
+			var l:int = getBoundary().length;
+			p = DOUBLEDASH(p);
+			for (var i:int = 0; i < l; i++ ) {
+				p.writeByte( _boundary.charCodeAt( i ) );
+			}
+			return p;
+		}
+
+		private function LINEBREAK(p:ByteArray):ByteArray
+		{
+			p.writeShort(0x0d0a);
+			return p;
+		}
+
+		private function QUOTATIONMARK(p:ByteArray):ByteArray
+		{
+			p.writeByte(0x22);
+			return p;
+		}
+
+		private function DOUBLEDASH(p:ByteArray):ByteArray
+		{
+			p.writeShort(0x2d2d);
+			return p;
+		}
+		
+		private function nextAsyncLoop():void
+		{
+			var fp:FilePart;
+			
+			if (asyncFilePointer < _fileNames.length) {
+				
+				fp = _files[_fileNames[asyncFilePointer]] as FilePart;
+				_data = getFilePartHeader(_data, fp);
+				
+				asyncWriteTimeoutId = setTimeout(writeChunkLoop, 10, _data, fp.fileContent, 0);
+				
+				asyncFilePointer ++;
+			} else {
+				_data = closeFilePartsData(_data);
+				_data = closeDataObject(_data);
+				
+				_prepared = true;
+				
+				dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_PROGRESS, totalFilesSize, totalFilesSize) );
+				dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_COMPLETE) );
+			}
+		}
+		
+		private function writeChunkLoop(dest:ByteArray, data:ByteArray, p:uint = 0):void
+		{
+			var len:uint = Math.min(BLOCK_SIZE, data.length - p);
+			dest.writeBytes(data, p, len);
+			
+			if (len < BLOCK_SIZE || p + len >= data.length) {
+				// Finished writing file bytearray
+				dest = LINEBREAK(dest);
+				nextAsyncLoop();
+				return;
+			}
+			
+			p += len;
+			writtenBytes += len;
+			if ( writtenBytes % BLOCK_SIZE * 2 == 0 ) {
+				dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_PROGRESS, writtenBytes, totalFilesSize) );
+			}
+			
+			asyncWriteTimeoutId = setTimeout(writeChunkLoop, 10, dest, data, p);
+		}
+
+	}
+}
+
+internal class FilePart
+{
+
+	public var fileContent:flash.utils.ByteArray;
+	public var fileName:String;
+	public var dataField:String;
+	public var contentType:String;
+
+	public function FilePart(fileContent:flash.utils.ByteArray, fileName:String, dataField:String = 'Filedata', contentType:String = 'application/octet-stream')
+	{
+		this.fileContent = fileContent;
+		this.fileName = fileName;
+		this.dataField = dataField;
+		this.contentType = contentType;
+	}
+
+	public function dispose():void
+	{
+		fileContent = null;
+		fileName = null;
+		dataField = null;
+		contentType = null;
+	}
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/events/MultipartURLLoaderEvent.as
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/events/MultipartURLLoaderEvent.as	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/flex/ru/inspirit/net/events/MultipartURLLoaderEvent.as	(revision 1843)
@@ -0,0 +1,27 @@
+﻿package ru.inspirit.net.events 
+{
+	import flash.events.Event;
+	
+	/**
+	 * MultipartURLLoader Event for async data prepare tracking
+	 * @author Eugene Zatepyakin
+	 */
+	public class MultipartURLLoaderEvent extends Event
+	{
+		public static const DATA_PREPARE_PROGRESS:String = 'dataPrepareProgress';
+		public static const DATA_PREPARE_COMPLETE:String = 'dataPrepareComplete';
+		
+		public var bytesWritten:uint = 0;
+		public var bytesTotal:uint = 0;
+		
+		public function MultipartURLLoaderEvent(type:String, w:uint = 0, t:uint = 0) 
+		{
+			super(type);
+			
+			bytesTotal = t;
+			bytesWritten = w;
+		}
+		
+	}
+	
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/resources/assets/css/main.css
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/resources/assets/css/main.css	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentBrowserGui/src/main/resources/assets/css/main.css	(revision 1843)
@@ -0,0 +1,67 @@
+/* CSS file */
+Application {
+    font-family: Verdana, Arial, Helv, Helvetica, sans-serif, "_sans";
+}
+
+ToggleButtonBar {
+   buttonWidth: 120;
+   horizontalGap: -1;
+}
+
+.borderStyles {
+   borderStyle: solid;
+   borderThickness: 2;
+   borderColor: #009dff;
+   cornerRadius: 8;
+}
+
+.xmlBrowser {
+   borderStyle: none;
+   borderThickness: 0;
+   backgroundColor: #DDE3EF;
+   cornerRadius: 8;
+   dropShadowEnabled: true;
+   verticalGap: 1;
+   indicatorGap: 8;
+}
+
+.xmlBrowserHeader {
+    fontWeight: bold;
+}
+
+.xmlBrowserField {
+    fontWeight: normal;
+}
+
+.xmlBrowserValueLabel {
+    fontWeight: normal;
+}
+
+.xmlEditorFieldEditField {
+    borderStyle: solid;
+    borderColor: #ffffff;
+    borderThickness: 1;
+    cornerRadius: 3;
+    fontWeight: normal;
+}
+
+.xmlTextArea {
+   borderStyle: solid;
+   backgroundColor: #DDE3EF;
+   borderThickness: 1;
+   borderColor: #DDE3EF;
+   cornerRadius: 8;
+   dropShadowEnabled: true;
+}
+
+TitleWindow {
+   borderAlpha: 1;
+}
+
+.showInfoPageLabel {
+    fontWeight: bold;
+}
+
+
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/CHANGES
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/CHANGES	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/CHANGES	(revision 1843)
@@ -0,0 +1,100 @@
+Bug Fixes and Features
+
+Release ComponentRegistry-1.11.0 (???????????????):
+- Upgraded to Saxon-HE 9.4
+- Validation of component specifications now also supports schematron rules in the general component schema.
+- Flex component editor does client side checks for duplicate component names.
+- Comments can be posted on profiles and components through a set of new REST calls, with support in the Flex UI. http://trac.clarin.eu/ticket/144
+- Data type 'dateTime' has been added as ValueScheme for elements. http://trac.clarin.eu/ticket/163
+- Recursion detection takes place at every component/profile registration or update. http://trac.clarin.eu/ticket/168
+- Users can set their display name through a web form linked from the Flex UI. http://trac.clarin.eu/ticket/156
+- 'Save' button in editor is only enabled when editing existing components/profiles from workspace. http://trac.clarin.eu/ticket/165
+
+Release ComponentRegistry-1.10.0 (4 november 2011):
+- Attributes can be added and edited on components. http://trac.clarin.eu/ticket/125
+- ConceptLinks can be assigned to attributes of components and elements. http://trac.clarin.eu/ticket/125#comment:3
+- ConceptLinks are enabled for Components. The search is filtered to show 'container' type concepts only. http://trac.clarin.eu/ticket/141
+- XML browser ('component preview') shows the group name if available. http://trac.clarin.eu/ticket/159
+- Added the mdEditor parameter to registry/profiles REST call to filter on profiles that should appear in e.g. Arbil. http://trac.clarin.eu/ticket/160
+- An 'about' screen can be triggered from the context menu that shows some info including the application version. http://trac.clarin.eu/ticket/106
+
+Release ComponentRegistry-1.9.1 (29 september 2011):
+- When recursion is detected while expanding (for XML or XSD), an exception is thrown, which will lead to an error response to the user rather than an infinite loop and no response. http://trac.clarin.eu/ticket/148
+
+Release ComponentRegistry-1.9 (22 september 2011):
+- Save private components works even when component is used, warning message is shown in Flex UI http://trac.clarin.eu/ticket/134
+
+Release ComponentRegistry-1.8.1 (29 june 2011):
+- Fixed some issues with UTF-8 handling http://trac.clarin.eu/ticket/133
+
+Release ComponentRegistry-1.8 (8 June 2011):
+- Backend reimplemented to use relational database instead of filesystem storage
+- Specify group for profiles http://trac.clarin.eu/ticket/49
+- Header name from specification copied to description when importing http://trac.clarin.eu/ticket/51
+- Fixed fold-out bug http://trac.clarin.eu/ticket/99
+
+Release ComponentRegistry-1.7 (26 January 2011):
+- Publishing means moving the private component/profile to public space. http://trac.clarin.eu/ticket/57
+- Edit pane is reloaded with saved component/profile. http://trac.clarin.eu/ticket/91
+- Created "show info" menu item that gives the xsd link and a bookmarkable link to open registry on selected item. http://trac.clarin.eu/ticket/59
+- Profiles in private workspace can have a public xsd. http://trac.clarin.eu/ticket/52
+
+Release ComponentRegistry-1.6.1 (19 November 2010):
+- fixed bug where registry jumps to the editor screen upon a delete
+- added tooltip to MultiLingual
+- added some whitespace to up/down icons
+- fixed issue where profiles with no "defining" component could not be edited. A "defining" component is now always added. For example see imdi-profile-instance
+
+Release ComponentRegistry-1.6 (12 November 2010):
+- No more dependency on jaxb, use default implementation in java6.
+- xml:lang in profiles/components, http://trac.clarin.eu/ticket/10
+- Add a save and a save as new button, http://trac.clarin.eu/ticket/11
+- Move clear changes button and make behaviour more clear, http://trac.clarin.eu/ticket/12 
+- Make browsing open for anyone (lazy login), http://trac.clarin.eu/ticket/14
+- "Adding ""null"" to ValueScheme (controlled vocabulary) doesn't show the item in the editor", http://trac.clarin.eu/ticket/15
+- "Make download xml, expanded", http://trac.clarin.eu/ticket/16
+- Allow reorder of elements/components in editor, http://trac.clarin.eu/ticket/17
+
+
+Release ComponentRegistry-1.5 (6 September 2010):
+- cleanup olds libs dir mpg jars can be taken from clarin maven site.
+- update jersey version
+- Admin page: cannot delete stuff, which is still used. Need to be able to update it at least at admin's risk. 
+
+
+Release ComponentRegistry-1.4 (20 August 2010):
+- Alternatively make the registry open in the browser showing the component/profile (make them bookmarkable). This involves moving the login process to a later stage and having a completely anonymous browsing registry.
+- Fix handling of eduPrincipalName/DisplayName make mapping in registry to keep track of which user has which displayName.
+  MIGRATE: add principalName to userMapping.xml, Migrate all descriptions to add userId element.
+- Import Descriptions is different from profile description, differs from edit.
+- put save button also at the bottom.
+- Make console showing tomcat log in admin page.
+- Make right click 'insert row' in valuescheme edit. So you can add an entry in the middle of an enumeration
+- Ping's don't work and are done through anonymous, it should give a better error handling and the ping should fail on anonymous. People need to be triggered to login again. Probable cause is computer sleeps and ping is not done for more then a while.
+- Make admin statistics page.
+- The description of some components/profiles is very short. The description in the actual cmdi header is longer and should be copied to the description of the description.xml's. Make a migrate plan for that.
+- link to isocat should be searchable on metadata only
+- Make isocat link clickable in isocat search field.
+- Changed tooltip in search isocat.
+
+
+Release ComponentRegistry-1.3 (28 June 2010):
+- Only admin can delete public items after a month in registry.
+- sort ignore case
+- Add some user logging.
+- Indenting XSD with one space.
+- Timeout thing. Flex client no keeps session alive by pinging the server.
+- Import screen should have bigger description field (like the editor).
+- Switched valueScheme item and appInfo columns and presentation. (Ordering will be better then).
+- Create Admin Page, where you can browse repo and edit all items. 
+- Create public link to private workspace so arbil can query it? as opposed to let people download xsd at the moment? Fix: Use XSD for now.
+- Isocat use complex conceptlinks to elements and simple types to valuescheme enumeration.
+- isocat simple/complex search in isocat metadata 'profile'
+- Stream xsd instead of creating and sending.
+- isocat popup place it in middle of screen.
+- Make swf file have version, so we have no more caching problems.
+- Add message in admin page that you are logged in as admin user. 
+- Conceptlink is selectable from the wrong column in valuescheme edit.
+- Fixed definition of multiple vocabularies in XSD. (XSLT fix).
+- Do not make popups transparant.
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/INSTALL
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/INSTALL	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/INSTALL	(revision 1843)
@@ -0,0 +1,53 @@
+INSTALLING THE COMPONENT REGISTRY REST SERVICE AND FLEX UI
+
+Important to know
+-----------------
+The Component Registry REST service depends on a PostgreSQL database to
+store its data. It is packaged as a servlet and has been tested to work with
+Tomcat. 
+
+The package includes a Flex based client that runs client-side in the
+user's browser. It is wrapped by an index.jsp page that embeds it and passes
+some parameters; it is located in the root of the application directory. 
+
+The web application uses the Spring framework and in the current version it
+is partly configured through Spring (see below).
+
+Setting up the database
+-----------------------
+- Create a new PostgreSQL database and configure users and roles
+- Run the create script 'create.sql' under the appropriate permissions
+
+Configuring Tomcat
+------------------
+By default, the application assumes a named (JNDI) datasource 
+jdbc/ComponentRegistry that provides access to the ComponentRegistry
+database. Set it up for the database described above in the Tomcat 
+configuration.
+    
+For more information, or configuring a custom datasource Spring bean,
+see WEB-INF/spring-config/datasource-jdbc.xml
+
+Deploying the application
+-------------------------
+Deploy the ComponentRegistry.war file to the Tomcat instance.
+
+Configuring the application
+---------------------------
+Some aspects could require additional configuration depending on the
+context:
+
+- Admin users. The application expects a context parameter
+  'componentRegistryAdminUsers' to be set as a white-space separated list of
+  users that should be granted access to the administration interface. So,
+  make sure the following is set in the relevant context fragment:
+
+    <Parameter 
+        name="componentRegistryAdminUsers" 
+	value="joe.admin@mpi.nl someone.else@clarin.eu"/>
+
+- Shibboleth authentication. ComponentRegistry uses the SHHAA filter, which
+  is configured in WEB-INF/shhaa.xml. Make sure SSO and SLO URL's are correct.
+
+- Misc configuration including admin users (has sensible defaults for
+  catalog server): WEB-INF/spring-config/component-registry.xml
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/README
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/README	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/README	(revision 1843)
@@ -0,0 +1,71 @@
+CLARIN COMPONENT REGISTRY
+=========================
+
+What is it?
+-----------
+
+The Component Registry stores CMDI metadata components and profiles and
+offers a service to list and retrieve them. The BrowserGui is a web
+application displaying available components in the component registry in the
+correct context: application domain, creator, creation date, version, etc.
+The registry offers a hierarchical structure for browsing the components. 
+
+The componentRegistry is set up as a Flex Gui frontend communicating with a
+Java based backend (REST service).
+
+The ComponentRegistry is a central software component to the Clarin MetaData
+Infrastructure (CMDI). For more information on CMDI, see
+<http://www.clarin.eu/cmdi>.
+
+Documentation
+-------------
+
+- A set of TRAC pages for developers has been setup on the Clarin.eu TRAC at
+<http://trac.clarin.eu/wiki/ComponentRegistryAndEditor>. You will need a
+login to access these pages. To request one, contact <clarin@clarin.eu>.
+
+- The REST interface is documented at <http://www.clarin.eu/node/3248>.
+
+- Documentation for users is available at <http://www.clarin.eu/node/3223>.
+
+How to set up for development/building from source
+--------------------------------------------------
+
+Creating war artifact for deployment:
+
+ - in ComponentBrowserGui: mvn install
+ - in ComponentRegistry: mvn package
+ 
+ The ComponentRegistry war will include the flex swf file needed to start the application. 
+ So deploying the resulting war will be enough to start the application.
+ By default the application is set to work when deployed on localhost. If you want to change that 
+ change the serverRootUrl property in the pom.xml of ComponentRegistry. There are already build
+ profiles for lux16.mpi.nl and catalog.clarin.eu that set these correctly.
+
+ The rest service relies on a Component Registry database, for which a create script can be found in 
+ the src/sql directory. For configuration instructions, see the comments in context.xml.
+
+
+NOTE on generating java classes from general-component-schema.xsd.
+The ComponentRegistry needs the general-component-schema.xsd, which should be found at:
+1) ComponentRegistry/src/main/binding/ -> that directory has a svn:externals property pointing to the schema.
+Do a 'svn propget svn:externals' to see the property. Results in: 'http://svn.clarin.eu/metadata/trunk/toolkit/general-component-schema.xsd general-component-schema.xsd'
+
+Missing some artifacts for Maven?:
+The ComponentBrowserGui project needs some swf files which are not in any maven repository I could find. 
+So install them manually: go to ComponentBrowserGui/libs/ and run the commands in maveninstalllib.txt
+ 
+Creating initial setup files (eclipse config):
+
+ - in ComponentBrowserGui: mvn flexmojos:flexbuilder
+ - in ComponentRegistry: mvn eclipse:eclipse
+ 
+Installation
+------------
+
+Please see the file called INSTALL
+
+Upgrading
+---------
+
+Please see the file called UPGRADE
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/UPDATE
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/UPDATE	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/UPDATE	(revision 1843)
@@ -0,0 +1,28 @@
+UPDATING THE COMPONENT REGISTRY REST SERVICE AND FLEX UI
+
+Procedure for updating
+----------------------
+
+- When upgrading to a new version of the ComponentRegistry, check if there are
+  updates of the database schema. These will be named upgrade-x.yy.sql, e.g.
+  upgrade-1.10.sql
+
+- If the database needs upgrading, first make a backup (dump) of the existing
+  database. Stop the application before doing so
+
+- Execute the upgrade script. When upgrading over multiple minor versions, 
+  execute the upgrade scripts incrementally
+
+- Then redeploy the WAR and start the application
+
+Version specific issues
+-----------------------
+
+=== 1.x -> 1.11 ==
+
+- The following should be added to the context fragment for the Component
+  Registry:
+    <Parameter
+	name="componentRegistryAdminUsers"
+	value="space-separated-list-of-admin-eppns"/>
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/commands.txt
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/commands.txt	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/commands.txt	(revision 1843)
@@ -0,0 +1,9 @@
+LOCAL:
+mvn clean package -Dmaven.test.skip=true
+
+LUX16:
+mvn clean package -Dmaven.test.skip=true -Plux16 
+
+CATALOG.CLARIN:
+mvn clean package -Dmaven.test.skip=true -Pclarin
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/pom.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/pom.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/pom.xml	(revision 1843)
@@ -0,0 +1,420 @@
+
+<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">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+	<groupId>clarin.cmdi</groupId>
+	<artifactId>componentRegistry.parent</artifactId>
+	<version>1.0</version>
+    </parent>
+    <groupId>clarin.cmdi</groupId>
+    <artifactId>ComponentRegistry</artifactId>
+    <packaging>${packaging}</packaging>
+    <version>${ComponentRegistry.version}</version>
+    <name>ComponentRegistry</name>
+    <description>
+        ComponentRegistry is part of the clarin metadata infrastructure (cmdi). 
+        The goal of the ComponentRegistry will be to register and make searchable Metadata Components and Profiles. 
+    </description>
+    <scm>
+	<connection>scm:svn:http://svn.clarin.eu/ComponentRegistry/trunk/ComponentRegistry</connection>
+	<developerConnection>scm:svn:http://svn.clarin.eu/ComponentRegistry/trunk/ComponentRegistry</developerConnection>
+	<url>http://trac.clarin.eu/browser/ComponentRegistry</url>
+    </scm>
+
+    <dependencies>
+	<dependency>
+	    <groupId>junit</groupId>
+	    <artifactId>junit</artifactId>
+	    <version>4.4</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>net.sf.saxon</groupId>
+	    <artifactId>saxon-he</artifactId>
+	    <version>9.4</version>
+	</dependency>
+	<dependency>
+	    <groupId>javax.servlet</groupId>
+	    <artifactId>servlet-api</artifactId>
+	    <version>2.5</version>
+	    <scope>provided</scope>
+	</dependency>
+	<dependency>
+	    <groupId>commons-codec</groupId>
+	    <artifactId>commons-codec</artifactId>
+	    <version>1.3</version>
+	</dependency>
+	<dependency>
+	    <groupId>commons-io</groupId>
+	    <artifactId>commons-io</artifactId>
+	    <version>1.4</version>
+	</dependency>
+	<dependency>
+	    <groupId>commons-lang</groupId>
+	    <artifactId>commons-lang</artifactId>
+	    <version>2.5</version>
+	</dependency>
+	<dependency>
+	    <groupId>commons-fileupload</groupId>
+	    <artifactId>commons-fileupload</artifactId>
+	    <version>1.2.1</version>
+	</dependency>
+	<dependency>
+	    <groupId>commons-collections</groupId>
+	    <artifactId>commons-collections</artifactId>
+	    <version>3.2.1</version>
+	</dependency>
+	<dependency>
+	    <groupId>xml-resolver</groupId>
+	    <artifactId>xml-resolver</artifactId>
+	    <version>1.2</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.slf4j</groupId>
+	    <artifactId>slf4j-log4j12</artifactId>
+	    <version>1.5.5</version>
+	</dependency>
+	<dependency>
+	    <groupId>log4j</groupId>
+	    <artifactId>log4j</artifactId>
+	    <version>1.2.14</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.springframework</groupId>
+	    <artifactId>spring</artifactId>
+	    <version>2.5.6</version>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.jersey.contribs</groupId>
+	    <artifactId>jersey-multipart</artifactId>
+	    <version>1.3</version>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.jersey</groupId>
+	    <artifactId>jersey-bundle</artifactId>
+	    <version>1.3</version>
+	    <exclusions>
+				<!--
+          Jersey has dependencies with different group ids therefore maven cannot resolve the conflict and gives me both
+          jars (two of stax and two of jaxb-impl). Excluding them manually to overcome the problem
+        -->
+		<exclusion>
+		    <groupId>stax</groupId>
+		    <artifactId>stax-api</artifactId>
+		</exclusion>
+	    </exclusions>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.jersey.jersey-test-framework</groupId>
+	    <artifactId>jersey-test-framework-grizzly</artifactId>
+	    <version>1.3</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.grizzly</groupId>
+	    <artifactId>grizzly-servlet-webserver</artifactId>
+	    <version>1.9.19</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.xml.stream</groupId>
+	    <artifactId>sjsxp</artifactId>
+	    <version>1.0.1</version>
+	</dependency>
+	<dependency>
+	    <groupId>de.mpg.mpgaai</groupId>
+	    <artifactId>mpgaai-jaas</artifactId>
+	    <version>1.3.2</version>
+	</dependency>
+	<dependency>
+	    <groupId>de.mpg.mpgaai</groupId>
+	    <artifactId>mpgaai-shhaa</artifactId>
+	    <version>1.0.2</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.apache.wicket</groupId>
+	    <artifactId>wicket</artifactId>
+	    <version>1.4.8</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.apache.wicket</groupId>
+	    <artifactId>wicket-extensions</artifactId>
+	    <version>1.4.8</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.apache.wicket</groupId>
+	    <artifactId>wicket-spring</artifactId>
+	    <version>1.4.8</version>
+	    <exclusions>
+		<exclusion>
+		    <groupId>org.springframework</groupId>
+		    <artifactId>spring</artifactId>
+		</exclusion>
+	    </exclusions>
+	</dependency>
+	<dependency>
+	    <groupId>com.sun.jersey.contribs</groupId>
+	    <artifactId>jersey-spring</artifactId>
+	    <version>1.3</version>
+	</dependency>
+	<dependency>
+	    <groupId>org.springframework</groupId>
+	    <artifactId>spring-test</artifactId>
+	    <version>2.5.6</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>commons-dbcp</groupId>
+	    <artifactId>commons-dbcp</artifactId>
+	    <version>1.4</version>
+	</dependency>
+	<dependency>
+	    <groupId>postgresql</groupId>
+	    <artifactId>postgresql</artifactId>
+	    <version>8.4-701.jdbc4</version>
+	</dependency>
+	<dependency>
+	    <groupId>hsqldb</groupId>
+	    <artifactId>hsqldb</artifactId>
+	    <version>1.8.0.10</version>
+	    <scope>test</scope>
+	</dependency>
+	<dependency>
+	    <groupId>clarin.cmdi</groupId>
+	    <artifactId>cmd-validate</artifactId>
+	    <version>1.0</version>
+	</dependency>
+    </dependencies>
+
+    <properties>
+	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	<packaging>war</packaging>
+		<!-- Properties to configure ComponentRegistry override on commandline with -D or change here -->
+	<serviceRootUrl>http://localhost:8080/${pom.artifactId}</serviceRootUrl>
+		<!-- Will be inserted in context.xml -->
+	<webXmlPath>src/main/webapp/WEB-INF/web.xml</webXmlPath>
+		<!-- non-shib web.xml -->
+	<isocatSearchUrl>http://www.isocat.org/rest/user/guest/search</isocatSearchUrl>
+	<ComponentRegistrySwfName>${pom.artifactId}-${ComponentBrowserGui.version}</ComponentRegistrySwfName>
+	<flexDebug>0</flexDebug>
+    </properties>
+
+    <profiles>
+	<profile>
+	    <id>lux16</id>
+	    <properties>
+		<serviceRootUrl>http://lux16.mpi.nl/ds/ComponentRegistry</serviceRootUrl>
+				<!-- Will be inserted in context.xml -->
+		<shibLI>http://lux16.mpi.nl/Shibboleth.sso/DS</shibLI>
+				<!-- Shibboleth login URI for SHHAA -->
+		<shibLO>http://lux16.mpi.nl/Shibboleth.sso/Logout</shibLO>
+				<!-- Shibboleth logout URI for SHHAA -->
+		<webXmlPath>src/main/webapp/WEB-INF/web-shib.xml</webXmlPath>
+				<!-- web.xml for shibboleth authentication -->
+	    </properties>
+	</profile>
+	<profile>
+	    <id>clarin</id>
+	    <properties>
+		<serviceRootUrl>http://catalog.clarin.eu/ds/ComponentRegistry</serviceRootUrl>
+				<!-- Will be inserted in context.xml -->
+		<shibLI>https://catalog.clarin.eu/Shibboleth.sso/DiscoJuice</shibLI>
+				<!-- Shibboleth login URI for SHHAA -->
+		<shibLO>https://catalog.clarin.eu/Shibboleth.sso/Logout</shibLO>
+				<!-- Shibboleth logout URI for SHHAA -->
+		<webXmlPath>src/main/webapp/WEB-INF/web-shib.xml</webXmlPath>
+				<!-- web.xml for shibboleth authentication -->
+	    </properties>
+	</profile>
+    </profiles>
+
+    <build>
+	<filters>
+	    <filter>properties/flexindex.properties</filter>
+	</filters>
+	<resources>
+	    <resource>
+		<filtering>false</filtering>
+		<directory>src/generated/jaxb</directory>
+	    </resource>
+	    <resource>
+		<filtering>true</filtering>
+		<directory>src/main/resources</directory>
+	    </resource>
+	    <resource>
+		<filtering>false</filtering>
+		<directory>src/main/java</directory>
+		<includes>
+		    <include>**/*.html</include>
+		</includes>
+	    </resource>
+	</resources>
+	<testResources>
+	    <testResource>
+		<directory>src/test/resources</directory>
+	    </testResource>
+	</testResources>
+	<plugins>
+	    <plugin>
+		<groupId>org.apache.maven.plugins</groupId>
+		<artifactId>maven-compiler-plugin</artifactId>
+		<configuration>
+		    <source>1.6</source>
+		    <target>1.6</target>
+		</configuration>
+	    </plugin>
+	    <plugin>
+		<groupId>org.apache.maven.plugins</groupId>
+		<artifactId>maven-war-plugin</artifactId>
+		<configuration>
+		    <warName>${pom.artifactId}</warName>
+		    <webXml>${webXmlPath}</webXml>
+		    <webResources>
+			<resource>
+			    <directory>src/main/webresources</directory>
+			    <filtering>true</filtering>
+			    <includes>
+				<include>index.jsp</include>
+				<include>WEB-INF/shhaa.xml</include>
+				<include>WEB-INF/applicationContext.xml</include>
+				<include>WEB-INF/spring-config/**</include>
+				<include>META-INF/context.xml</include>
+			    </includes>
+			</resource>
+		    </webResources>
+		    <archive>
+			<manifest>
+			    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+			</manifest>
+		    </archive>
+		</configuration>
+	    </plugin>
+	    <plugin>
+		<groupId>org.jvnet.jaxb2.maven2</groupId>
+		<artifactId>maven-jaxb2-plugin</artifactId>
+		<executions>
+		    <execution>
+			<goals>
+			    <goal>generate</goal>
+			</goals>
+		    </execution>
+		</executions>
+		<configuration>
+					<!-- assuming claring metadata project is checked out in same folder as this project -->
+		    <schemaDirectory>src/main/binding</schemaDirectory>
+		    <schemaIncludes>
+			<include>general-component-schema.xsd</include>
+		    </schemaIncludes>
+		    <bindingDirectory>src/main/binding</bindingDirectory>
+		    <extension>true</extension>
+		    <generateDirectory>${basedir}/src/generated/jaxb</generateDirectory>
+		    <generatePackage>clarin.cmdi.componentregistry.components</generatePackage>
+		    <catalog>src/main/resources/catalog.cat</catalog>
+		    <catalogResolver>org.jvnet.jaxb2.maven2.resolver.tools.ClasspathCatalogResolver</catalogResolver>
+		</configuration>
+	    </plugin>
+	    <plugin>
+		<groupId>org.apache.maven.plugins</groupId>
+		<artifactId>maven-dependency-plugin</artifactId>
+		<executions>
+		    <execution>
+			<id>copy</id>
+			<phase>process-resources</phase>
+			<goals>
+			    <goal>copy</goal>
+			</goals>
+			<configuration>
+			    <artifactItems>
+				<artifactItem>
+				    <groupId>clarin.cmdi</groupId>
+				    <artifactId>ComponentBrowserGui</artifactId>
+				    <version>${ComponentBrowserGui.version}</version>
+				    <type>swf</type>
+				    <overWrite>true</overWrite>
+				    <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}</outputDirectory>
+				    <destFileName>${ComponentRegistrySwfName}.swf</destFileName>
+				</artifactItem>
+			    </artifactItems>
+			</configuration>
+		    </execution>
+		</executions>
+	    </plugin>
+	    <plugin>
+		<artifactId>maven-assembly-plugin</artifactId>
+		<version>2.2.2</version>
+		<executions>
+		    <execution>
+			<id>make-assembly</id>
+			<phase>package</phase>
+			<goals>
+			    <goal>single</goal>
+			</goals>
+			<configuration>
+			    <descriptors>
+				<descriptor>src/main/assembly/release.xml</descriptor>
+			    </descriptors>
+			</configuration>
+		    </execution>
+		</executions>
+	    </plugin>
+	</plugins>
+    </build>
+    
+    <reporting>
+	<plugins>
+	    <plugin>
+		<groupId>org.codehaus.mojo</groupId>
+		<artifactId>findbugs-maven-plugin</artifactId>
+		<configuration>
+		    <excludeFilterFile>${basedir}/src/main/resources/findbugs-exclude.xml</excludeFilterFile>
+		    <threshold>Normal</threshold>
+		    <effort>Min</effort>
+		</configuration>
+	    </plugin>
+	</plugins>
+    </reporting>  
+    
+    <repositories>
+	<repository>
+	    <id>maven2-repository.dev.java.net</id>
+	    <name>Java.net Maven 2 Repository</name>
+	    <url>http://download.java.net/maven/2</url>
+	</repository>
+	<repository>
+	    <id>maven-glassfish-repository.dev.java.net</id>
+	    <name>Java.net Maven Glassfish Repository</name>
+	    <url>http://download.java.net/maven/glassfish</url>
+	</repository>
+	<repository>
+	    <id>maven-repository.dev.java.net</id>
+	    <name>Java.net Maven 1 Repository (legacy)</name>
+	    <url>http://download.java.net/maven/1</url>
+	    <layout>legacy</layout>
+	</repository>
+	<repository>
+	    <id>cmdi.clarin.repository</id>
+	    <name>Clarin Repository</name>
+	    <url>http://catalog.clarin.eu/ds/nexus/content/groups/public/</url>
+	</repository>
+	<repository>
+	    <id>sonatype</id>
+	    <url>https://oss.sonatype.org/content/groups/public</url>
+	</repository>
+    </repositories>
+    <pluginRepositories>
+	<pluginRepository>
+	    <id>maven2-repository.dev.java.net</id>
+	    <name>Java.net Maven 2 Repository</name>
+	    <url>http://download.java.net/maven/2</url>
+	</pluginRepository>
+	<pluginRepository>
+	    <id>maven-repository.dev.java.net</id>
+	    <name>Java.net Maven 1 Repository (legacy)</name>
+	    <url>http://download.java.net/maven/1</url>
+	    <layout>legacy</layout>
+	</pluginRepository>
+    </pluginRepositories>
+
+</project>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/properties/flexindex.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/properties/flexindex.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/properties/flexindex.properties	(revision 1843)
@@ -0,0 +1,8 @@
+title=Clarin Component Registry
+version_major=10
+version_minor=0
+version_revision=0
+width=100%
+height=100%
+application=ComponentRegistry
+bgcolor=#869ca7
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/assembly/release.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/assembly/release.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/assembly/release.xml	(revision 1843)
@@ -0,0 +1,51 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    
+    <id>mpi-deploy</id>
+    <formats>
+        <format>tar.gz</format>
+    </formats>
+    
+    <fileSets>
+        <fileSet>
+            <outputDirectory>war</outputDirectory>
+            <directory>target</directory>
+            <includes>
+                <include>*.war</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <outputDirectory>jar</outputDirectory>
+            <directory>target</directory>
+            <includes>
+                <include>*.jar</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <outputDirectory>scripts</outputDirectory>
+            <directory>src/main/sql</directory>
+            <includes>
+                <include>*.sql</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <outputDirectory>scripts</outputDirectory>
+            <directory>src/main/script</directory>
+        </fileSet>
+
+        <fileSet>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>UPDATE</include>
+                <include>LICENSES</include>
+                <include>README</include>
+                <include>CHANGES</include>
+                <include>INSTALL</include>
+            </includes>
+        </fileSet>
+    </fileSets>              
+</assembly>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/binding/bindings.xjb
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/binding/bindings.xjb	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/binding/bindings.xjb	(revision 1843)
@@ -0,0 +1,13 @@
+<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
+          xmlns:xs="http://www.w3.org/2001/XMLSchema"
+          version="2.0"> 
+          <!-- TODO Patrick component schema location here needs to be better handled. Not hardcoded for instance. -->
+   <bindings schemaLocation="general-component-schema.xsd"
+     node="/xs:schema/xs:complexType[@name='CMD_Element_type']/xs:sequence/xs:element[@name='ValueScheme']">
+      <property name="ValueScheme" />
+   </bindings>
+   <bindings schemaLocation="general-component-schema.xsd"
+     node="/xs:schema/xs:attributeGroup[@name='clarin_element_attributes']/xs:attribute[@name='ValueScheme']">
+      <property name="ValueSchemeAttribute" />
+   </bindings>
+</bindings>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/CMDComponentSpecExpander.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/CMDComponentSpecExpander.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/CMDComponentSpecExpander.java	(revision 1843)
@@ -0,0 +1,125 @@
+package clarin.cmdi.componentregistry;
+
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.components.CMDComponentType;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public abstract class CMDComponentSpecExpander {
+
+    private final static Logger LOG = LoggerFactory.getLogger(CMDComponentSpecExpander.class);
+    protected final ComponentRegistry registry;
+
+    public CMDComponentSpecExpander(ComponentRegistry registry) {
+	this.registry = registry;
+    }
+
+    public void expandNestedComponent(List<CMDComponentType> cmdComponents, String id) throws ComponentRegistryException {
+	expandNestedComponent(cmdComponents, new HashSet<String>(Collections.singleton(id)));
+    }
+
+    public void expandNestedComponent(List<CMDComponentType> cmdComponents) throws ComponentRegistryException {
+	expandNestedComponent(cmdComponents, new HashSet<String>());
+    }
+
+    private void expandNestedComponent(List<CMDComponentType> cmdComponents, Collection<String> path) throws ComponentRegistryException {
+	List<CMDComponentType> expanded = new ArrayList<CMDComponentType>();
+	for (CMDComponentType cmdComponentType : cmdComponents) {
+	    String componentId = cmdComponentType.getComponentId();
+	    if (componentId != null) {
+		if (path.contains(componentId)) {
+		    throw new ComponentRegistryException("Detected recursion in component specification: " + path.toString() + " already contains " + componentId);
+		} else {
+		    Collection<String> newPath = new HashSet<String>(path);
+		    newPath.add(componentId);
+		    // Use uncached components and profiles, because we expand and thus change them this change should not be in the cache.
+		    CMDComponentSpec spec = getUncachedComponent(componentId);
+		    if (spec != null) {
+			CMDComponentType nested = getComponentTypeOfAComponent(spec);
+			expandNestedComponent(nested.getCMDComponent(), newPath);
+			overwriteAttributes(cmdComponentType, nested);
+			expanded.add(nested);
+		    } else {
+			// Spec could not be resolved
+			LOG.warn("Could not resolve referenced component with id " + componentId);
+			// Add spec itself, without futher expanding
+			expanded.add(cmdComponentType);
+		    }
+		}
+	    } else {
+		// No id = embedded component
+		expandNestedComponent(cmdComponentType.getCMDComponent(), path);
+		expanded.add(cmdComponentType);//no attributes overwritten
+	    }
+	}
+	cmdComponents.clear();
+	cmdComponents.addAll(expanded);
+    }
+
+    private CMDComponentType getComponentTypeOfAComponent(CMDComponentSpec result) {
+	List<CMDComponentType> cmdComponents = result.getCMDComponent();
+	if (cmdComponents.size() != 1) {
+	    LOG.error("Internal error: CMDComponentSpec which is not a profile can only have one "
+		    + "CMDComponentType (which is the description of the component itself).");
+	}
+	CMDComponentType cmdComponentType = cmdComponents.get(0);
+	return cmdComponentType;
+    }
+
+    /**
+     * Copying the cardinality specified in the referenceDeclaration over the values in the actual component.
+     */
+    private void overwriteAttributes(CMDComponentType referenceDeclaration, CMDComponentType nested) {
+	if (!referenceDeclaration.getCardinalityMax().isEmpty()) {
+	    List<String> cardinalityMax = nested.getCardinalityMax();
+	    cardinalityMax.clear();
+	    cardinalityMax.addAll(referenceDeclaration.getCardinalityMax());
+	}
+	if (!referenceDeclaration.getCardinalityMin().isEmpty()) {
+	    List<String> cardinalityMin = nested.getCardinalityMin();
+	    cardinalityMin.clear();
+	    cardinalityMin.addAll(referenceDeclaration.getCardinalityMin());
+	}
+	nested.setComponentId(referenceDeclaration.getComponentId()); // Setting componentId for better xsd generation.
+    }
+
+    protected CMDComponentSpec expandComponent(String componentId) throws ComponentRegistryException {
+	// Use uncached components and profiles, because we expand and thus change them this change should not be in the cache.
+	CMDComponentSpec result = getUncachedComponent(componentId);//registry.getUncachedComponent(componentId);
+	CMDComponentType cmdComponentType = getComponentTypeOfAComponent(result);
+	expandNestedComponent(cmdComponentType.getCMDComponent(), componentId);
+	return result;
+    }
+
+    protected CMDComponentSpec expandProfile(String profileId) throws ComponentRegistryException {
+	// Use uncached components and profiles, because we expand and thus change them this change should not be in the cache.
+	CMDComponentSpec result = getUncachedProfile(profileId);//registry.getUncachedProfile(profileId);
+	List<CMDComponentType> cmdComponents = result.getCMDComponent();
+	expandNestedComponent(cmdComponents, profileId);
+	return result;
+    }
+
+//    protected CMDComponentSpec expandComment(String commentId) throws ComponentRegistryException {
+//        CMDComponentSpec result = getUncachedComment(commentId);
+//        List<CMDComponentType> cmdComponents = result.getCMDComponent();
+//        expandNestedComponent(cmdComponents);
+//        return result;
+//    }
+    /**
+     * Get uncached component from "this" registry and possibly from public registry. Note: "this" registry can be a user registry.
+     * @param componentId
+     */
+    protected abstract CMDComponentSpec getUncachedComponent(String componentId) throws ComponentRegistryException;
+
+    protected abstract CMDComponentSpec getUncachedProfile(String profileId) throws ComponentRegistryException;
+//    protected abstract CMDComponentSpec getUncachedComment(String commentId) throws ComponentRegistryException;
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistry.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistry.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistry.java	(revision 1843)
@@ -0,0 +1,198 @@
+package clarin.cmdi.componentregistry;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.Principal;
+import java.util.List;
+
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+public interface ComponentRegistry {
+
+    public static final String REGISTRY_ID = "clarin.eu:cr1:";
+    public static final String PUBLIC_NAME = "Public Registry";
+
+    /**
+     * 
+     * @return List of component descriptions ordered by name ascending
+     * @throws ComponentRegistryException
+     */
+    List<ComponentDescription> getComponentDescriptions() throws ComponentRegistryException;
+
+    ComponentDescription getComponentDescription(String id) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @return List of profile descriptions ordered by name ascending
+     * @throws ComponentRegistryException
+     */
+    List<ProfileDescription> getProfileDescriptions() throws ComponentRegistryException;
+
+    /**
+     * 
+     * @return List of profile descriptions ordered by name ascending, only the ones marked for showing in metadata editor
+     * @throws ComponentRegistryException
+     */
+    List<ProfileDescription> getProfileDescriptionsForMetadaEditor() throws ComponentRegistryException;
+
+    ProfileDescription getProfileDescription(String id) throws ComponentRegistryException;
+
+    CMDComponentSpec getMDProfile(String id) throws ComponentRegistryException;
+
+    CMDComponentSpec getMDComponent(String id) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @return -1 if profile could not be registered
+     */
+    int register(AbstractDescription desc, CMDComponentSpec spec);
+
+    /**
+     * 
+     * @param comment
+     * @return -1 if comment could not be registered
+     */
+    int registerComment(Comment comment, String userId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @return -1 if component could not be updated
+     */
+    int update(AbstractDescription description, CMDComponentSpec spec, Principal principal, boolean forceUpdate);
+
+    /**
+     * 
+     * @return -1 if component could not be published. Published means move from
+     *         current (private) workspace to public workspace.
+     */
+    int publish(AbstractDescription desc, CMDComponentSpec spec, Principal principal);
+
+    void getMDProfileAsXml(String profileId, OutputStream output) throws ComponentRegistryException;
+
+    void getMDProfileAsXsd(String profileId, OutputStream outputStream) throws ComponentRegistryException;
+
+    void getMDComponentAsXml(String componentId, OutputStream output) throws ComponentRegistryException;
+
+    void getMDComponentAsXsd(String componentId, OutputStream outputStream) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param profileId
+     * @param principal
+     * @throws IOException
+     * @throws UserUnauthorizedException
+     *             thrown when principal does not match creator of profile
+     * @throws DeleteFailedException
+     */
+    void deleteMDProfile(String profileId, Principal principal) throws IOException, UserUnauthorizedException, ComponentRegistryException, DeleteFailedException;
+
+    /**
+     * 
+     * @param componentId
+     * @param principal
+     * @param forceDelete
+     *            ignores the fact that the component is still in use by other
+     *            components and just deletes.
+     * @throws IOException
+     * @throws UserUnauthorizedException
+     *             thrown when principal does not match creator of component
+     * @throws DeleteFailedException
+     */
+    void deleteMDComponent(String componentId, Principal principal, boolean forceDelete) throws IOException, ComponentRegistryException, UserUnauthorizedException,
+	    DeleteFailedException;
+
+    /**
+     * 
+     * @param componentId
+     * @return List of ComponentDescriptions of Components that use the given
+     *         Component.
+     */
+    List<ComponentDescription> getUsageInComponents(String componentId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param componentId
+     * @return List of ProfileDescriptions of Profiles that use the given
+     *         Component.
+     */
+    List<ProfileDescription> getUsageInProfiles(String componentId) throws ComponentRegistryException;
+
+    /**
+     * Return true if this registry is the public registry as opposed to a
+     * registry used for the user privately.
+     **/
+    boolean isPublic();
+
+    /**
+     * @return {@link ComponentRegistry.PUBLIC_NAME} or name of the user's workspace
+     */
+    String getName();
+
+    /**
+     * 
+     * @return List of profile descriptions ordered by name ascending
+     */
+    List<ProfileDescription> getDeletedProfileDescriptions();
+
+    /**
+     * 
+     * @return List of component descriptions ordered by name ascending
+     */
+    List<ComponentDescription> getDeletedComponentDescriptions();
+
+    /**
+     * 
+     * @param profileId
+     * @return List of comments fro a specific profile
+     * @throws ComponentRegistryException 
+     */
+    List<Comment> getCommentsInProfile(String profileId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param profileId Id of profile to retrieve comment from
+     * @param commentId Id of comment to retrieve
+     * @return a specific comment from a profile
+     * @throws ComponentRegistryException 
+     */
+    Comment getSpecifiedCommentInProfile(String profileId, String commentId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param componentId
+     * @return List of comments from a specific component
+     * @throws ComponentRegistryException 
+     */
+    List<Comment> getCommentsInComponent(String componentId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param componentId Id of component to retrieve comment from
+     * @param commentId Id of comment to retrieve
+     * @return a specific comment from a component
+     * @throws ComponentRegistryException 
+     */
+    Comment getSpecifiedCommentInComponent(String componentId, String commentId) throws ComponentRegistryException;
+
+    /**
+     * 
+     * @param commentId Id of comment to delete
+     * @param principal User principal
+     * @throws IOException
+     * @throws ComponentRegistryException When comment cannot be successfully retrieved from registry
+     * @throws UserUnauthorizedException
+     * @throws DeleteFailedException 
+     */
+    public void deleteComment(String commentId, Principal principal) throws IOException, ComponentRegistryException, UserUnauthorizedException,
+	    DeleteFailedException;
+
+    /**
+     * 
+     * @return a component specification expander for this registry
+     */
+    public CMDComponentSpecExpander getExpander();
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryException.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryException.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryException.java	(revision 1843)
@@ -0,0 +1,16 @@
+package clarin.cmdi.componentregistry;
+
+public class ComponentRegistryException extends Exception {
+
+    public ComponentRegistryException(String message) {
+	super(message);
+    }
+
+    public ComponentRegistryException(String message, Throwable t) {
+	super(message, t);
+    }
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryFactory.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryFactory.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/ComponentRegistryFactory.java	(revision 1843)
@@ -0,0 +1,24 @@
+package clarin.cmdi.componentregistry;
+
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public interface ComponentRegistryFactory {
+
+    public static final String ANONYMOUS_USER = "anonymous"; //Default shibboleth fallback.
+
+    List<ComponentRegistry> getAllUserRegistries();
+
+    ComponentRegistry getComponentRegistry(boolean userspace, UserCredentials credentials);
+
+    ComponentRegistry getOtherUserComponentRegistry(Principal adminPrincipal, String userId);
+
+    ComponentRegistry getPublicRegistry();
+
+    RegistryUser getOrCreateUser(UserCredentials credentials);
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/Configuration.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/Configuration.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/Configuration.java	(revision 1843)
@@ -0,0 +1,119 @@
+package clarin.cmdi.componentregistry;
+
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class Configuration {
+
+    private static Logger LOG = LoggerFactory.getLogger(Configuration.class);
+    //NOTE: Default values, can be overwritten in applicationContext.xml
+    private String generalComponentSchema = "http://www.clarin.eu/cmd/general-component-schema.xsd";
+    private String component2SchemaXsl = "http://www.clarin.eu/cmd/xslt/comp2schema-v2/comp2schema.xsl";//"http://www.clarin.eu/cmd/comp2schema.xsl";
+    private String isocatRestUrl = "http://www.isocat.org/rest/";
+    private Collection<String> adminUsers = new HashSet<String>();
+    private List<String> displayNameShibbolethKeys = new ArrayList<String>();
+
+    {//Default values
+	displayNameShibbolethKeys.add("displayName");
+	displayNameShibbolethKeys.add("commonName");
+    }
+    private Map<String, String> schemaLocations = new HashMap<String, String>();
+
+    {//Default values
+	schemaLocations.put(CMDComponentSpec.class.getName(),
+		"http://www.clarin.eu/cmd/ http://www.clarin.eu/cmd/general-component-schema.xsd");
+    }
+    private final static Configuration INSTANCE = new Configuration();
+
+    private Configuration() {
+    }
+
+    public static Configuration getInstance() {
+	return INSTANCE;
+    }
+
+    public String getComponent2SchemaXsl() {
+	return component2SchemaXsl;
+    }
+
+    public List<String> getDisplayNameShibbolethKeys() {
+	return displayNameShibbolethKeys;
+    }
+
+    public String getGeneralComponentSchema() {
+	return generalComponentSchema;
+    }
+
+    public String getIsocatRestUrl() {
+	return isocatRestUrl;
+    }
+
+    public String getSchemaLocation(String key) {
+	return schemaLocations.get(key);
+    }
+
+    public boolean isAdminUser(Principal principal) {
+	if (principal != null) {
+	    return principal.getName().trim().length() > 0 // user name must be set (in case an empty entry is in admin users list)
+		    && adminUsers.contains(principal.getName());
+	}
+	return false;
+    }
+
+    public void setAdminUsers(Collection<String> adminUsers) {
+	LOG.debug("Setting adminUsers to {}", Arrays.toString(adminUsers.toArray()));
+	this.adminUsers = adminUsers;
+    }
+
+    /**
+     * 
+     * @param adminUsers Whitespace-separated list of admin users
+     */
+    public void setAdminUsersList(String adminUsersList) {
+	LOG.debug("Setting adminUsersList to {}", adminUsersList);
+	String[] adminUsersArray = adminUsersList.trim().split("\\s+");
+	setAdminUsers(Arrays.asList(adminUsersArray));
+    }
+
+    public void setComponent2SchemaXsl(String component2SchemaXsl) {
+	LOG.debug("Setting component2SchemaXsl to {}", component2SchemaXsl);
+	this.component2SchemaXsl = component2SchemaXsl;
+    }
+
+    public void setComponentSpecSchemaLocation(String componentSpecSchemaLocation) {
+	LOG.debug("Setting componentSpecSchemaLocation to {}", componentSpecSchemaLocation);
+	schemaLocations.put(CMDComponentSpec.class.getName(), componentSpecSchemaLocation);
+    }
+
+    public void setDisplayNameShibbolethKeys(List<String> displayNameShibbolethKeys) {
+	LOG.debug("Setting displayNameShibbolethKeys to {}", displayNameShibbolethKeys);
+	this.displayNameShibbolethKeys = displayNameShibbolethKeys;
+    }
+
+    public void setGeneralComponentSchema(String generalComponentSchema) {
+	LOG.debug("Setting generalComponentSchema to {}", generalComponentSchema);
+	this.generalComponentSchema = generalComponentSchema;
+    }
+
+    public void setIsocatRestUrl(String isocatRestUrl) {
+	LOG.debug("Setting isocatRestUrl to {}", isocatRestUrl);
+	this.isocatRestUrl = isocatRestUrl;
+    }
+
+    public String[] getAdminUsersArray() {
+	return adminUsers.toArray(new String[0]);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/DeleteFailedException.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/DeleteFailedException.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/DeleteFailedException.java	(revision 1843)
@@ -0,0 +1,18 @@
+package clarin.cmdi.componentregistry;
+
+public class DeleteFailedException extends ComponentRegistryException {
+
+    public DeleteFailedException(String message) {
+        super(message);
+    }
+
+    public DeleteFailedException(String message, Throwable t) {
+        super(message, t);
+    }
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/IdSequence.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/IdSequence.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/IdSequence.java	(revision 1843)
@@ -0,0 +1,9 @@
+package clarin.cmdi.componentregistry;
+
+public final class IdSequence {
+    static long current = System.currentTimeMillis();
+
+    static public synchronized long get() {
+        return current++;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/MDMarshaller.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/MDMarshaller.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/MDMarshaller.java	(revision 1843)
@@ -0,0 +1,197 @@
+package clarin.cmdi.componentregistry;
+
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.xml.resolver.tools.CatalogResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class MDMarshaller {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MDMarshaller.class);
+    /**
+     * I define W3C_XML_SCHEMA_NS_URI here cannot get it from @see XMLConstants there is a conflict between stax-api and java5.
+     */
+    private static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
+    private static Schema generalComponentSchema;
+
+    private MDMarshaller() {
+    }
+
+    /**
+     * Helper method that logs errors and returns null if unmarshal failed
+     */
+    public static <T> T unmarshal(Class<T> docClass, File file, Schema schema) {
+	T result = null;
+	try {
+	    result = unmarshal(docClass, new FileInputStream(file), schema);
+	} catch (JAXBException e) {
+	    LOG.error("Cannot unmarshal xml file: " + file, e);
+	} catch (IOException e) {
+	    LOG.error("Cannot retrieve content from file: " + file, e);
+	}
+	return result;
+    }
+
+    /**
+     * 
+     * @param docClass
+     * @param inputStream
+     * @param schema to validate against, can be null for no validation.
+     * @return
+     * @throws JAXBException
+     */
+    public static <T> T unmarshal(Class<T> docClass, InputStream inputStream, Schema schema) throws JAXBException {
+	String packageName = docClass.getPackage().getName();
+	JAXBContext jc = JAXBContext.newInstance(packageName);
+	Unmarshaller u = jc.createUnmarshaller();
+
+	if (schema != null) {
+	    u.setSchema(schema);
+	}
+	Object unmarshal = u.unmarshal(inputStream);
+	T doc = (T) unmarshal;
+	return doc;
+    }
+
+    /**
+     * Will wrap the Outputstream in a OutputStreamWriter with encoding set to UTF-8. This to make sure profiles are stored correctly.
+     */
+    public static <T> void marshal(T marshallableObject, OutputStream out) throws JAXBException, UnsupportedEncodingException {
+	String packageName = marshallableObject.getClass().getPackage().getName();
+	JAXBContext jc = JAXBContext.newInstance(packageName);
+
+	Marshaller m = jc.createMarshaller();
+	m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+	String schemaLocation = Configuration.getInstance().getSchemaLocation(marshallableObject.getClass().getName());
+	if (schemaLocation != null) {
+	    m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
+	}
+	Writer writer = new OutputStreamWriter(out, "UTF-8");
+	m.marshal(marshallableObject, writer);
+    }
+
+    public static Schema getCMDComponentSchema() {
+	if (generalComponentSchema == null) {
+	    try {
+		SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
+		schemaFactory.setResourceResolver(new LSResourceResolver() {
+		    private CatalogResolver catRes = new CatalogResolver();
+
+		    @Override
+		    public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
+			InputSource resolveEntity = catRes.resolveEntity(publicId, systemId);
+			resolveEntity.setEncoding("UTF-8");
+			DOMImplementationLS domImplementation;
+			try {
+			    domImplementation = (DOMImplementationLS) DOMImplementationRegistry.newInstance().getDOMImplementation("LS");
+			} catch (ClassCastException e) {
+			    throw new RuntimeException(e);
+			} catch (ClassNotFoundException e) {
+			    throw new RuntimeException(e);
+			} catch (InstantiationException e) {
+			    throw new RuntimeException(e);
+			} catch (IllegalAccessException e) {
+			    throw new RuntimeException(e);
+			}
+			LSInput lsInput = domImplementation.createLSInput();
+			lsInput.setEncoding("UTF-8");
+			lsInput.setByteStream(resolveEntity.getByteStream());
+			lsInput.setCharacterStream(resolveEntity.getCharacterStream());
+			return lsInput;
+		    }
+		});
+		generalComponentSchema = schemaFactory.newSchema(new URL(Configuration.getInstance().getGeneralComponentSchema()));
+	    } catch (MalformedURLException e) {
+		LOG.error("Cannot instantiate schema", e);
+	    } catch (SAXException e) {
+		LOG.error("Cannot instantiate schema", e);
+	    }
+	}
+	return generalComponentSchema;
+    }
+
+    public static void generateXsd(CMDComponentSpec spec, OutputStream outputStream) {
+	Templates componentToSchemaTemplates;
+	try {
+	    System.setProperty("javax.xml.transform.TransformerFactory", net.sf.saxon.TransformerFactoryImpl.class.getName());
+	    componentToSchemaTemplates = TransformerFactory.newInstance().newTemplates(
+		    new StreamSource(Configuration.getInstance().getComponent2SchemaXsl()));
+	} catch (TransformerConfigurationException e) {
+	    LOG.error("Cannot create Template", e);
+	    return;
+	}
+	try {
+	    Transformer transformer = componentToSchemaTemplates.newTransformer();
+	    ByteArrayOutputStream out = new ByteArrayOutputStream();
+	    MDMarshaller.marshal(spec, out);
+	    ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());
+	    transformer.transform(new StreamSource(input), new StreamResult(outputStream));
+	} catch (TransformerConfigurationException e) {
+	    LOG.error("Cannot create Transformer", e);
+	} catch (TransformerException e) {
+	    LOG.error("Cannot transform xml file: " + getSpecId(spec), e);
+	} catch (UnsupportedEncodingException e) {
+	    LOG.error("Error in encoding: ", e);
+	} catch (JAXBException e) {
+	    LOG.error("Cannot marshall spec: " + getSpecId(spec), e);
+	}
+    }
+
+    
+    
+    private static String getSpecId(CMDComponentSpec spec) {
+	String result = "";
+	if (spec != null && spec.getHeader() != null) {
+	    result = spec.getHeader().getID();
+	}
+	return result;
+    }
+
+    /**
+     * @param marshallableObject
+     * @return the xml representation of the marshallableObject
+     * @throws jaxb exceptions are wrapped in RuntimeExceptions
+     */
+    public static <T> String marshalToString(T marshallableObject) {
+	ByteArrayOutputStream out = new ByteArrayOutputStream();
+	try {
+	    marshal(marshallableObject, out);
+	    return out.toString("UTF-8");
+	} catch (UnsupportedEncodingException e) {
+	    throw new RuntimeException(e);
+	} catch (JAXBException e) {
+	    throw new RuntimeException(e);
+	}
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserCredentials.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserCredentials.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserCredentials.java	(revision 1843)
@@ -0,0 +1,70 @@
+package clarin.cmdi.componentregistry;
+
+import java.security.Principal;
+import java.util.List;
+
+import org.apache.commons.codec.digest.DigestUtils;
+
+import de.mpg.aai.shhaa.model.AuthAttribute;
+import de.mpg.aai.shhaa.model.AuthAttributes;
+import de.mpg.aai.shhaa.model.AuthPrincipal;
+
+/**
+ * Wrapper class to hold the userPrincipal and a displayName
+ * 
+ */
+public class UserCredentials {
+
+    private final Principal userPrincipal;
+
+    public UserCredentials(Principal userPrincipal) {
+        this.userPrincipal = userPrincipal;
+    }
+
+    public Principal getPrincipal() {
+        return userPrincipal;
+    }
+
+    public String getPrincipalName() {
+        return userPrincipal.getName();
+    }
+
+    public String getPrincipalNameMD5Hex() {
+        return getPrincipalNameMD5Hex(userPrincipal.getName());
+    }
+
+    public static String getPrincipalNameMD5Hex(String name){
+	return DigestUtils.md5Hex(name);
+    }
+
+    public String getDisplayName() {
+        String result = null;
+        if (userPrincipal instanceof AuthPrincipal) {
+            List<String> displayNamesAttributes = Configuration.getInstance().getDisplayNameShibbolethKeys();
+            AuthPrincipal authPrincipal = (AuthPrincipal) userPrincipal;
+            for (String key : displayNamesAttributes) {
+                result = getValue(authPrincipal, key);
+                if (result != null) {
+                    break;
+                }
+            }
+        }
+        if (result == null) {
+            result = getPrincipalName();
+        }
+        return result;
+    }
+
+    private String getValue(AuthPrincipal authPrincipal, String key) {
+        String result = null;
+        AuthAttributes attributes = authPrincipal.getAttribues();
+        if (attributes != null) {
+            AuthAttribute<String> authAttribute = (AuthAttribute<String>) attributes.get(key);
+            if (authAttribute != null) {
+                result = authAttribute.getValue();
+            }
+        }
+        return result;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserUnauthorizedException.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserUnauthorizedException.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/UserUnauthorizedException.java	(revision 1843)
@@ -0,0 +1,18 @@
+package clarin.cmdi.componentregistry;
+
+public class UserUnauthorizedException extends Exception {
+
+    public UserUnauthorizedException(String message) {
+        super(message);
+    }
+
+    public UserUnauthorizedException(String message, Throwable t) {
+        super(message, t);
+    }
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.html	(revision 1843)
@@ -0,0 +1,13 @@
+<html
+	xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+<head>
+<title>CMDI ComponentRegistry access denied</title>
+<link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+</head>
+<body>
+Access denied you (<b wicket:id="userName">userName</b>) are not a registered admin user. 
+<br />
+<br />
+If you want to become an administrator please sent a request to cmdi@clarin.eu.
+</body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AccessDeniedPage.java	(revision 1843)
@@ -0,0 +1,38 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+
+public class AccessDeniedPage extends WebPage {
+
+    private static final long serialVersionUID = 1L;
+
+    public AccessDeniedPage() {
+        Principal userPrincipal = getWebRequestCycle().getWebRequest().getHttpServletRequest().getUserPrincipal();
+        String userName = "not logged in";
+        if (userPrincipal != null && userPrincipal.getName() != null) {
+            userName = userPrincipal.getName();
+        }
+        add(new Label("userName", userName));
+    }
+
+    @Override
+    protected void configureResponse() {
+        super.configureResponse();
+        getWebRequestCycle().getWebResponse().getHttpServletResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
+    }
+
+    @Override
+    public boolean isVersioned() {
+        return false;
+    }
+
+    @Override
+    public boolean isErrorPage() {
+        return true;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminApp.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminApp.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminApp.java	(revision 1843)
@@ -0,0 +1,23 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
+
+public class AdminApp extends WebApplication {
+
+    @Override
+    protected void init() {
+        super.init();
+        getDebugSettings().setAjaxDebugModeEnabled(false);
+        addComponentInstantiationListener(new SpringComponentInjector(this));
+	
+	mountBookmarkablePage("userSettings", UserSettingsPage.class);
+    }
+
+    @Override
+    public Class<? extends Page> getHomePage() {
+        return AdminHomePage.class;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.html	(revision 1843)
@@ -0,0 +1,37 @@
+<html
+    xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+    <head>
+        <title>CMDI ComponentRegistry Admin Page</title>
+        <link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+    </head>
+    <body>
+        <span wicket:id="message"></span>
+
+        <div class="links">
+            <span wicket:id="linksMessage"></span>
+            <a wicket:id="massMigrate">MassMigrate</a>
+            <a wicket:id="log">View Log</a>
+            <a wicket:id="statistics">View Statistics</a>
+        </div>
+        <div class="container">
+            <div class="treeView">
+                <a wicket:id="expandAll">[expand all]</a>
+                <a wicket:id="collapseAll">[collapse all]</a>
+                <span wicket:id="tree">tree</span>
+            </div>
+            <div class="infoView">
+                <div id="feedbackPanel">
+                    <span wicket:id="feedback"></span>
+                </div>
+                <form wicket:id="form">
+                    <button wicket:id="delete" title="Press delete button to delete this item">delete</button>
+                    <button wicket:id="undelete" title="Press undelete button to put this item back in the registry">undelete</button>
+                    <input type="checkbox" wicket:id="forceUpdate" />forceUpdate
+                    <button wicket:id="submit">submit edit changes</button>
+                    <textarea  class="descriptionTextArea" wicket:id="description" >text</textarea>
+                    <textarea  class="contentTextArea" wicket:id="content" >text</textarea>
+                </form>
+            </div>
+        </div>
+    </body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/AdminHomePage.java	(revision 1843)
@@ -0,0 +1,301 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.security.Principal;
+import java.util.List;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.form.AjaxFallbackButton;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.TextArea;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.markup.html.tree.BaseTree;
+import org.apache.wicket.markup.html.tree.ITreeState;
+import org.apache.wicket.markup.html.tree.LinkTree;
+import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.impl.database.AdminRegistry;
+import clarin.cmdi.componentregistry.impl.database.ComponentDescriptionDao;
+import clarin.cmdi.componentregistry.impl.database.ProfileDescriptionDao;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+@SuppressWarnings("serial")
+public class AdminHomePage extends SecureAdminWebPage {
+
+    private static final long serialVersionUID = 1L;
+    private final static Logger LOG = LoggerFactory.getLogger(AdminHomePage.class);
+    private final CMDItemInfo info = new CMDItemInfo();
+    private final LinkTree tree;
+    private transient AdminRegistry adminRegistry = new AdminRegistry();
+    @SpringBean(name = "componentRegistryFactory")
+    private ComponentRegistryFactory componentRegistryFactory;
+    @SpringBean
+    private ProfileDescriptionDao profileDescriptionDao;
+    @SpringBean
+    private ComponentDescriptionDao componentDescriptionDao;
+
+    public AdminHomePage(final PageParameters parameters) throws ComponentRegistryException {
+	super(parameters);
+	adminRegistry.setComponentRegistryFactory(componentRegistryFactory);
+	adminRegistry.setProfileDescriptionDao(profileDescriptionDao);
+	adminRegistry.setComponentDescriptionDao(componentDescriptionDao);
+	addLinks();
+	final FeedbackPanel feedback = new FeedbackPanel("feedback");
+	feedback.setOutputMarkupId(true);
+	add(feedback);
+	Form form = new ItemEditForm("form");
+	add(form);
+
+	Button deleteButton = new AjaxFallbackButton("delete", form) {
+
+	    @Override
+	    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
+		CMDItemInfo info = (CMDItemInfo) form.getModelObject();
+		info("deleting:" + info.getName());
+		Principal userPrincipal = getWebRequest().getHttpServletRequest().getUserPrincipal();
+		try {
+		    adminRegistry.delete(info, userPrincipal);
+		    info("Item deleted.");
+		    reloadTreeModel(info);
+		} catch (SubmitFailedException e) {
+		    LOG.error("Admin: ", e);
+		    error("Cannot delete: " + info.getName() + "\n error=" + e);
+		}
+		if (target != null) {
+		    target.addComponent(form);
+		    target.addComponent(tree);
+		    target.addComponent(feedback);
+		}
+	    }
+
+	    @Override
+	    public boolean isEnabled() {
+		return info.isDeletable();
+
+	    }
+	;
+	};
+	form.add(deleteButton);
+
+	Button undeleteButton = new AjaxFallbackButton("undelete", form) {
+
+	    @Override
+	    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
+		CMDItemInfo info = (CMDItemInfo) form.getModelObject();
+		info("undeleting:" + info.getName());
+		try {
+		    adminRegistry.undelete(info);
+		    info("Item put back.");
+		    reloadTreeModel(info);
+		} catch (SubmitFailedException e) {
+		    LOG.error("Admin: ", e);
+		    error("Cannot undelete: " + info.getName() + "\n error=" + e);
+		}
+		if (target != null) {
+		    target.addComponent(form);
+		    target.addComponent(tree);
+		    target.addComponent(feedback);
+		}
+	    }
+
+	    @Override
+	    public boolean isEnabled() {
+		return info.isUndeletable();
+	    }
+	};
+	form.add(undeleteButton);
+
+	CheckBox forceUpdateCheck = new CheckBox("forceUpdate");
+	form.add(forceUpdateCheck);
+
+	Button submitButton = new AjaxFallbackButton("submit", form) {
+
+	    @Override
+	    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
+		CMDItemInfo info = (CMDItemInfo) form.getModelObject();
+		Principal userPrincipal = getWebRequest().getHttpServletRequest().getUserPrincipal();
+		info("submitting:" + info.getName() + " id=(" + info.getDataNode().getDescription().getId() + ")");
+		try {
+		    adminRegistry.submitFile(info, userPrincipal);
+		    info("submitting done.");
+		    reloadTreeModel(info);
+		} catch (SubmitFailedException e) {
+		    LOG.error("Admin: ", e);
+		    error("Cannot submit: " + info.getName() + "\n error=" + e);
+		}
+		if (target != null) {
+		    target.addComponent(form);
+		    target.addComponent(tree);
+		    target.addComponent(feedback);
+		}
+	    }
+
+	    @Override
+	    public boolean isEnabled() {
+		return info.isEditable();
+	    }
+	};
+	form.add(submitButton);
+
+	tree = createTree("tree", form, createDBTreeModel());
+	add(tree);
+	add(new Link("expandAll") {
+
+	    @Override
+	    public void onClick() {
+		tree.getTreeState().expandAll();
+	    }
+	});
+
+	add(new Link("collapseAll") {
+
+	    @Override
+	    public void onClick() {
+		tree.getTreeState().collapseAll();
+	    }
+	});
+
+    }
+
+    private void reloadTreeModel(CMDItemInfo info) {
+	try {
+	    tree.setModelObject(createDBTreeModel());
+	} catch (ComponentRegistryException e) {
+	    LOG.error("Admin: ", e);
+	    error("Cannot reload tree: " + info.getName() + "\n error=" + e);
+	}
+    }
+
+    private void addLinks() {
+	add(new Label("linksMessage", "Browse the data below or choose on of the following options:"));
+	add(new Link("massMigrate") {
+
+	    @Override
+	    public void onClick() {
+		setResponsePage(MassMigratePage.class);
+	    }
+	});
+	add(new Link("log") {
+
+	    @Override
+	    public void onClick() {
+		setResponsePage(ViewLogPage.class);
+	    }
+	});
+	add(new Link("statistics") {
+
+	    @Override
+	    public void onClick() {
+		setResponsePage(StatisticsPage.class);
+	    }
+	});
+    }
+
+    private LinkTree createTree(String id, final Form form, TreeModel treeModel) {
+	final LinkTree adminTree = new LinkTree(id, treeModel) {
+
+	    @Override
+	    protected void onNodeLinkClicked(Object node, BaseTree tree, AjaxRequestTarget target) {
+		super.onNodeLinkClicked(node, tree, target);
+		ITreeState treeState = tree.getTreeState();
+		if (treeState.isNodeExpanded(node)) {
+		    treeState.collapseNode(node);
+		} else {
+		    treeState.expandNode(node);
+		}
+		DisplayDataNode dn = (DisplayDataNode) ((DefaultMutableTreeNode) node).getUserObject();
+		info.setDataNode(dn);
+		AbstractDescription desc = dn.getDescription();
+		if (desc != null) {
+		    String content;
+		    if (desc.isProfile()) {
+			content = profileDescriptionDao.getContent(dn.isDeleted(), desc.getId());
+		    } else {
+			content = componentDescriptionDao.getContent(dn.isDeleted(), desc.getId());
+		    }
+		    info.setContent(content);
+		}
+		if (target != null) {
+		    target.addComponent(form);
+		}
+	    }
+	};
+	return adminTree;
+    }
+
+    private class ItemEditForm extends Form<CMDItemInfo> {
+
+	public ItemEditForm(String name) {
+	    super(name);
+	    CompoundPropertyModel model = new CompoundPropertyModel(info);
+	    setModel(model);
+
+	    TextArea descriptionArea = new TextArea("description");
+	    descriptionArea.setOutputMarkupId(true);
+	    add(descriptionArea);
+	    TextArea contentArea = new TextArea("content");
+	    contentArea.setOutputMarkupId(true);
+	    add(contentArea);
+	}
+    }
+
+    private TreeModel createDBTreeModel() throws ComponentRegistryException {
+	DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(new DisplayDataNode("ComponentRegistry", false));
+	DefaultMutableTreeNode publicNode = new DefaultMutableTreeNode(new DisplayDataNode("Public", false));
+	rootNode.add(publicNode);
+	ComponentRegistry publicRegistry = componentRegistryFactory.getPublicRegistry();
+	add(publicNode, publicRegistry);
+	List<ComponentRegistry> userRegistries = componentRegistryFactory.getAllUserRegistries();
+	for (ComponentRegistry registry : userRegistries) {
+	    DefaultMutableTreeNode userNode = new DefaultMutableTreeNode(new DisplayDataNode(registry.getName(), false));
+	    rootNode.add(userNode);
+	    add(userNode, registry);
+	}
+	TreeModel model = new DefaultTreeModel(rootNode);
+	return model;
+    }
+
+    private void add(DefaultMutableTreeNode parent, ComponentRegistry registry) throws ComponentRegistryException {
+	DefaultMutableTreeNode componentsNode = new DefaultMutableTreeNode(new DisplayDataNode("Components", false));
+	parent.add(componentsNode);
+	add(componentsNode, registry.getComponentDescriptions(), false, registry.isPublic());
+
+	DefaultMutableTreeNode profilesNode = new DefaultMutableTreeNode(new DisplayDataNode("Profiles", false));
+	parent.add(profilesNode);
+	add(profilesNode, registry.getProfileDescriptions(), false, registry.isPublic());
+
+	DefaultMutableTreeNode deletedCompNode = new DefaultMutableTreeNode(new DisplayDataNode("Deleted Components", true));
+	parent.add(deletedCompNode);
+
+	List<ComponentDescription> deletedComponentDescriptions = registry.getDeletedComponentDescriptions();
+	add(deletedCompNode, deletedComponentDescriptions, true, registry.isPublic());
+
+	DefaultMutableTreeNode deletedProfNode = new DefaultMutableTreeNode(new DisplayDataNode("Deleted Profiles", true));
+	parent.add(deletedProfNode);
+	List<ProfileDescription> deletedProfileDescriptions = registry.getDeletedProfileDescriptions();
+	add(deletedProfNode, deletedProfileDescriptions, true, registry.isPublic());
+    }
+
+    private void add(DefaultMutableTreeNode parent, List<? extends AbstractDescription> descs, boolean isDeleted, boolean isPublic) {
+	for (AbstractDescription desc : descs) {
+	    DefaultMutableTreeNode child = new DefaultMutableTreeNode(new DisplayDataNode(desc.getName(), isDeleted, desc, isPublic));
+	    parent.add(child);
+	}
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/CMDItemInfo.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/CMDItemInfo.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/CMDItemInfo.java	(revision 1843)
@@ -0,0 +1,115 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.io.Serializable;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+public class CMDItemInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String description;
+    private String content;
+    private String name;
+    private boolean forceUpdate = false;
+
+    private DisplayDataNode displayNode;
+
+    private boolean deletable = false;
+    private boolean undeletable = false;
+
+    private boolean editable = false;
+
+    public void setDescription(String descriptionText) {
+        this.description = descriptionText;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        if (displayNode != null) {
+            name = displayNode.toString();
+        }
+        return name;
+    }
+
+    public DisplayDataNode getDataNode() {
+        return displayNode;
+    }
+
+    public void setDataNode(DisplayDataNode dataNode) {
+        this.displayNode = dataNode;
+        setUndeletable(false);
+        setDeletable(false);
+        setEditable(false);
+        setDescription("");
+        setContent("");
+        if (dataNode != null) {
+            AbstractDescription desc = dataNode.getDescription();
+            if (desc != null) {
+                String content = MDMarshaller.marshalToString(desc);
+                setDescription(content);
+                setEditable(true);
+                if (dataNode.isDeleted()) {
+                    setUndeletable(true);
+                } else {
+                    setDeletable(true);
+                } 
+            }
+        }
+
+    }
+
+    public void setDeletable(boolean deletable) {
+        this.deletable = deletable;
+    }
+
+    public boolean isDeletable() {
+        return deletable;
+    }
+
+    public void setUndeletable(boolean undeletable) {
+        this.undeletable = undeletable;
+    }
+
+    public boolean isUndeletable() {
+        return undeletable;
+    }
+
+    public boolean isEditable() {
+        return editable;
+    }
+
+    public void setEditable(boolean editable) {
+        this.editable = editable;
+    }
+
+
+    public boolean isInUserWorkSpace() {
+        return !displayNode.isPublic();
+    }
+
+    public void setForceUpdate(boolean forceUpdate) {
+        this.forceUpdate = forceUpdate;
+    }
+
+    public boolean isForceUpdate() {
+        return forceUpdate;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayDataNode.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayDataNode.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayDataNode.java	(revision 1843)
@@ -0,0 +1,47 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.io.Serializable;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+public class DisplayDataNode implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private final String name;
+    private final boolean isDeleted;
+    private AbstractDescription desc;
+    private final boolean isPublic;
+
+    public DisplayDataNode(String name, boolean isDeleted) {
+        this(name, isDeleted, null, false);
+    }
+
+    public DisplayDataNode(String name, boolean isDeleted, AbstractDescription desc, boolean isPublic) {
+        this.name = name;
+        this.isDeleted = isDeleted;
+        this.desc = desc;
+        this.isPublic = isPublic;
+    }
+
+    /**
+     * Can be null for non leaves.
+     * @return
+     */
+    public AbstractDescription getDescription() {
+        return desc;
+    }
+
+    public boolean isDeleted() {
+        return isDeleted;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public boolean isPublic() {
+        return isPublic;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayNode.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayNode.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/DisplayNode.java	(revision 1843)
@@ -0,0 +1,17 @@
+package clarin.cmdi.componentregistry.frontend;
+
+public interface DisplayNode {
+
+    public String getContent();
+
+    public boolean hasContent();
+
+    public boolean isDeleted();
+
+    public boolean isEditable();
+
+    public boolean isUserNode();
+
+    public String getId();
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.html	(revision 1843)
@@ -0,0 +1,22 @@
+<html
+	xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+<head>
+<title>CMDI ComponentRegistry MassMigrate Page</title>
+<link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+</head>
+<body>
+<span wicket:id="message"></span>
+<div class="links">
+    <span wicket:id="linksMessage"></span>
+    <a wicket:id="home">AdminHome</a>
+</div>
+
+<span wicket:id="migrate1Label"></span>
+<a wicket:id="migrate1">Migrate</a>
+
+<div id="feedbackPanel">
+    <span wicket:id="feedback"></span>
+</div>  
+
+</body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/MassMigratePage.java	(revision 1843)
@@ -0,0 +1,80 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.io.Serializable;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
+import org.apache.wicket.feedback.FeedbackMessage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.basic.MultiLineLabel;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Page that starts up somekind of migration on the underlying data in the registry. Migrations are usually one off things so do not blindly
+ * migrate but take a little time to know what you are doing. Backing up the data before a migrate is probably a good idea as well.
+ * 
+ */
+@SuppressWarnings("serial")
+public class MassMigratePage extends SecureAdminWebPage {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MassMigratePage.class);
+    private FeedbackPanel feedback;
+//    @SpringBean
+//    private ComponentDescriptionDao componentDescriptionDao;
+//    @SpringBean
+//    private ProfileDescriptionDao profileDescriptionDao;
+//    @SpringBean
+//    private UserDao userDao;
+
+    public MassMigratePage(final PageParameters pageParameters) {
+	super(pageParameters);
+	addLinks();
+	feedback = new FeedbackPanel("feedback") {
+
+	    @Override
+	    protected Component newMessageDisplayComponent(String id, FeedbackMessage message) {
+		Serializable serializable = message.getMessage();
+		MultiLineLabel label = new MultiLineLabel(id, (serializable == null) ? "" : serializable.toString());
+		label.setEscapeModelStrings(getEscapeModelStrings());
+		return label;
+	    }
+	};
+	feedback.setOutputMarkupPlaceholderTag(true);
+	add(feedback);
+	addMigrationOptions();
+    }
+
+    private void addLinks() {
+	add(new Label("linksMessage", "Do some mass migration or go to:"));
+	add(new Link("home") {
+
+	    @Override
+	    public void onClick() {
+		setResponsePage(AdminHomePage.class);
+	    }
+	});
+    }
+
+    private void addMigrationOptions() {
+	add(new Label("migrate1Label", "No migration implemented at the moment..."));
+	add(new IndicatingAjaxLink("migrate1") {
+
+	    @Override
+	    public void onClick(final AjaxRequestTarget target) {
+		if (target != null) {
+		    target.addComponent(feedback);
+		}
+		startMigration();
+	    }
+	});
+    }
+
+    private void startMigration() {
+	info("Nothing to migrate...");
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SecureAdminWebPage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SecureAdminWebPage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SecureAdminWebPage.java	(revision 1843)
@@ -0,0 +1,26 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.security.Principal;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.MultiLineLabel;
+
+import clarin.cmdi.componentregistry.Configuration;
+
+public abstract class SecureAdminWebPage extends WebPage {
+
+    public SecureAdminWebPage(final PageParameters parameters) {
+        super(parameters);
+        Principal userPrincipal = getUserPrincipal();
+        if (!Configuration.getInstance().isAdminUser(userPrincipal)) {
+            setResponsePage(new AccessDeniedPage());
+        }
+        add(new MultiLineLabel("message", "Component Registry Admin Page.\nYou are logged in as: " + userPrincipal.getName() + ".\n"));
+    }
+
+    protected final Principal getUserPrincipal() {
+	return getWebRequestCycle().getWebRequest().getHttpServletRequest().getUserPrincipal();
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.html	(revision 1843)
@@ -0,0 +1,51 @@
+<html
+    xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+    <head>
+        <title>CMDI ComponentRegistry Statistics Page</title>
+        <link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+    </head>
+    <body>
+        <span wicket:id="message"></span>
+        <div class="links">
+            <a wicket:id="home">AdminHome</a>
+        </div>
+        <br><br><br>
+        <span wicket:id="profilenumbermessage"></span>
+        <table cellspacing="5" class="dataview">
+            <tr>
+                <th align="left">Profile ID</th>
+                <th align="left">Profile name</th>
+<!--                <th align="left">Number of components</th>-->
+                <th align="left">Number of nested components</th>
+                <th align="left">Number of nested elements</th>
+                <th align="left">Number of nested conceptlinks</th>
+            </tr>
+            <tr wicket:id="repeating">
+                <td><span wicket:id="ID">[ID]</span> </td>
+                <td><span wicket:id="profname">[Name]</span> </td>
+<!--                <td><span wicket:id="nrrootcomp">[Number of components]</span> </td>-->
+                <td><span wicket:id="nrcomp">[Number of nested components]</span> </td>
+                <td><span wicket:id="nrprofelem">[Number of nested elements]</span> </td>
+                <td><span wicket:id="nrproflinks">[Number of nested links]</span> </td>
+            </tr>
+        </table>
+        <br><br><br>
+        <span wicket:id="componentnumbermessage"></span>
+        <table cellspacing="5" class="dataview">
+            <tr>
+                <th align="left">Component ID</th>
+                <th align="left">Component name</th>
+                <th align="left">Number of nested components</th>
+                <th align="left">Number of nested elements</th>
+                <th align="left">Number of nested conceptlinks</th>
+            </tr>
+            <tr wicket:id="repeatingcomp">
+                <td><span wicket:id="ID">[ID]</span> </td>
+                <td><span wicket:id="compname">[Name]</span> </td>
+                <td><span wicket:id="nrcomp">[Number of components]</span> </td>
+                <td><span wicket:id="nrelem">[Number of elements]</span> </td>
+                <td><span wicket:id="nrcomplinks">[Number of nested links]</span> </td>
+            </tr>
+        </table>
+    </body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/StatisticsPage.java	(revision 1843)
@@ -0,0 +1,118 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.WebMarkupContainer;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.markup.repeater.RepeatingView;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.components.CMDComponentType;
+import clarin.cmdi.componentregistry.components.CMDElementType;
+import clarin.cmdi.componentregistry.impl.database.CMDComponentSpecExpanderDbImpl;
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryDbImpl;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+/**
+ *
+ * @author paucas
+ */
+public class StatisticsPage extends SecureAdminWebPage {
+
+    private static final long serialVersionUID = 1L;
+    @SpringBean(name = "componentRegistryFactory")
+    private ComponentRegistryFactory componentRegistryFactory;
+
+    private static class Statistics {
+        private int componentnumber = 0;
+        private int elementcounter = 0;
+        private int conceptlinkcounter = 0;
+    }
+
+    public StatisticsPage(final PageParameters pageParameters) throws IOException, ComponentRegistryException {
+        super(pageParameters);
+        ComponentRegistry registry = componentRegistryFactory.getPublicRegistry();
+        addLinks();
+        displayStatistics(registry);
+    }
+
+    private void displayStatistics(ComponentRegistry registry) throws ComponentRegistryException {
+        List<ProfileDescription> profileList = registry.getProfileDescriptions();
+        RepeatingView repeating = new RepeatingView("repeating");
+        add(repeating);
+        add(new Label("profilenumbermessage", "Current number of profiles in the component registry: " + profileList.size()));
+        for (ProfileDescription pd : profileList) {
+            displayProfileStatistics(pd, repeating, registry);
+        }
+        List<ComponentDescription> componentList = registry.getComponentDescriptions();
+        RepeatingView repeatingcomp = new RepeatingView("repeatingcomp");
+        add(repeatingcomp);
+        add(new Label("componentnumbermessage", "Current number of components in the component registry: " + componentList.size()));
+        for (ComponentDescription cd : componentList) {
+            displayComponentStatistics(cd, repeatingcomp, registry);
+        }
+    }
+
+    private void displayProfileStatistics(ProfileDescription pd, RepeatingView repeatingview, ComponentRegistry registry) throws ComponentRegistryException {
+        WebMarkupContainer item = new WebMarkupContainer(repeatingview.newChildId());
+        repeatingview.add(item);
+        item.add(new Label("ID", pd.getId()));
+        item.add(new Label("profname", pd.getName()));
+        CMDComponentSpec profile = CMDComponentSpecExpanderDbImpl.expandProfile(pd.getId(), (ComponentRegistryDbImpl) registry);
+        Statistics stats = new Statistics();
+        componentCounter(profile.getCMDComponent(), stats);
+        item.add(new Label("nrcomp", "" + stats.componentnumber));
+        item.add(new Label("nrprofelem", "" + stats.elementcounter));
+        item.add(new Label("nrproflinks", "" + stats.conceptlinkcounter));
+    }
+
+    private void displayComponentStatistics(ComponentDescription cd, RepeatingView repeatingview,  ComponentRegistry registry) throws ComponentRegistryException {
+        WebMarkupContainer item = new WebMarkupContainer(repeatingview.newChildId());
+        repeatingview.add(item);
+        item.add(new Label("ID", cd.getId()));
+        item.add(new Label("compname", cd.getName()));
+        CMDComponentSpec compspec = CMDComponentSpecExpanderDbImpl.expandComponent(cd.getId(), (ComponentRegistryDbImpl) registry);
+        Statistics stats = new Statistics();
+        componentCounter(compspec.getCMDComponent(), stats);
+        item.add(new Label("nrcomp", "" + stats.componentnumber));
+        item.add(new Label("nrelem", "" + stats.elementcounter));
+        item.add(new Label("nrcomplinks", "" + stats.conceptlinkcounter));
+    }
+
+    private void componentCounter(List<CMDComponentType> components, Statistics stats) {
+        if (components != null) {
+            for (CMDComponentType component : components) {
+                stats.componentnumber++;
+                List<CMDElementType> elementlist = component.getCMDElement();
+                if (elementlist != null) {
+                    stats.elementcounter += elementlist.size();
+                    for (CMDElementType elem : elementlist) {
+                        if (elem.getConceptLink() != null) {
+                            stats.conceptlinkcounter++;
+                        }
+                    }
+                }
+                componentCounter(component.getCMDComponent(), stats);
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    private void addLinks() {
+        add(new Link("home") {
+
+            @Override
+            public void onClick() {
+                setResponsePage(AdminHomePage.class);
+            }
+        });
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SubmitFailedException.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SubmitFailedException.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/SubmitFailedException.java	(revision 1843)
@@ -0,0 +1,21 @@
+package clarin.cmdi.componentregistry.frontend;
+
+public class SubmitFailedException extends Exception {
+
+    public SubmitFailedException(String message) {
+        super(message);
+    }
+
+    public SubmitFailedException(Throwable cause) {
+        super(cause);
+    }
+    public SubmitFailedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.html	(revision 1843)
@@ -0,0 +1,22 @@
+<html
+    xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+    <head>
+        <title>CMDI ComponentRegistry Admin Page</title>
+        <link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+    </head>
+    <body>
+	<h1>
+	    User settings for <span wicket:id="userName">userName</span>
+	</h1>
+	<div wicket:id="feedback">[Feedback Panel]</div>
+        <form wicket:id="settingsForm">
+	    <p>
+		<label>User display name:</label>
+		<input wicket:id="displayName"/>
+	    </p>
+	    <p>
+		<input type="submit" value="Submit"/>
+	    </p>
+	</form>
+    </body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/UserSettingsPage.java	(revision 1843)
@@ -0,0 +1,75 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package clarin.cmdi.componentregistry.frontend;
+
+import clarin.cmdi.componentregistry.impl.database.UserDao;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import java.security.Principal;
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.markup.html.WebPage;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.RequiredTextField;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.markup.html.panel.FeedbackPanel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.spring.injection.annot.SpringBean;
+import org.springframework.dao.DataAccessException;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class UserSettingsPage extends WebPage {
+
+    @SpringBean
+    private UserDao userDao;
+    private RegistryUser registryUser;
+
+    public UserSettingsPage(PageParameters parameters) {
+	super(parameters);
+
+	Principal userPrincipal = ((WebRequestCycle) (RequestCycle.get())).getWebRequest().getHttpServletRequest().getUserPrincipal();
+	registryUser = userDao.getByPrincipalName(userPrincipal.getName());
+	
+	add(new Label("userName", registryUser.getPrincipalName()));
+
+	add(new FeedbackPanel("feedback"));
+	add(new SettingsForm("settingsForm"));
+    }
+
+    private class SettingsForm extends Form {
+
+	public SettingsForm(String id) {
+	    super(id);
+
+	    final TextField displayNameField = new RequiredTextField<String>("displayName", new IModel<String>() {
+
+		@Override
+		public String getObject() {
+		    return registryUser.getName();
+		}
+
+		@Override
+		public void setObject(String newName) {
+		    registryUser.setName(newName);
+		    try {
+			userDao.updateUser(registryUser.getId(), registryUser);
+			info("User info has been updated");
+		    } catch (DataAccessException daEx) {
+			error("Database error: " + daEx.getMessage());
+		    }
+		}
+
+		@Override
+		public void detach() {
+		}
+	    });
+	    add(displayNameField);
+	}
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.html	(revision 1843)
@@ -0,0 +1,14 @@
+<html
+    xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd">
+    <head>
+        <title>CMDI ComponentRegistry View Log Page</title>
+        <link rel="stylesheet" type="text/css" href="css/adminstyle.css"/>
+    </head>
+    <body>
+        <span wicket:id="message"></span>
+        <div class="links">
+            <a wicket:id="home">AdminHome</a>
+        </div>
+        <textarea cols="150" rows="50"  wicket:id="logText" >log text</textarea>
+    </body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/frontend/ViewLogPage.java	(revision 1843)
@@ -0,0 +1,47 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package clarin.cmdi.componentregistry.frontend;
+
+import java.io.File;
+import java.io.IOException;
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.FileAppender;
+import org.apache.log4j.Logger;
+import org.apache.wicket.PageParameters;
+import org.apache.wicket.markup.html.form.TextArea;
+import org.apache.wicket.markup.html.link.Link;
+import org.apache.wicket.model.Model;
+
+/**
+ *
+ * @author paucas
+ */
+public class ViewLogPage extends SecureAdminWebPage {
+
+    public ViewLogPage(final PageParameters pageParameters) throws IOException {
+        super(pageParameters);
+        addLinks();
+
+        File file = getLogFile();
+        String content = FileUtils.readFileToString(file, "UTF-8");
+        add(new TextArea("logText", new Model(content)));
+    }
+
+    private void addLinks() {
+        add(new Link("home") {
+
+            @Override
+            public void onClick() {
+                setResponsePage(AdminHomePage.class);
+            }
+        });
+    }
+
+    private File getLogFile() {
+        FileAppender appender = (FileAppender) Logger.getRootLogger().getAppender("ROOT");
+        File logFile = new File(appender.getFile());
+        return logFile;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/ComponentRegistryImplBase.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/ComponentRegistryImplBase.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/ComponentRegistryImplBase.java	(revision 1843)
@@ -0,0 +1,146 @@
+package clarin.cmdi.componentregistry.impl;
+
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.components.CMDComponentType;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec.Header;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+/**
+ * 
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public abstract class ComponentRegistryImplBase implements ComponentRegistry {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryImplBase.class);
+
+    @Override
+    public List<ComponentDescription> getUsageInComponents(String componentId) throws ComponentRegistryException {
+        List<ComponentDescription> result = new ArrayList<ComponentDescription>();
+        List<ComponentDescription> descs = getComponentDescriptions();
+        for (ComponentDescription desc : descs) {
+            CMDComponentSpec spec = getMDComponent(desc.getId());
+            if (spec != null && findComponentId(componentId, spec.getCMDComponent())) {
+                result.add(desc);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public List<ProfileDescription> getUsageInProfiles(String componentId) throws ComponentRegistryException {
+        List<ProfileDescription> result = new ArrayList<ProfileDescription>();
+        for (ProfileDescription profileDescription : getProfileDescriptions()) {
+            CMDComponentSpec profile = getMDProfile(profileDescription.getId());
+            if (profile != null && findComponentId(componentId, profile.getCMDComponent())) {
+                result.add(profileDescription);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 
+     * @return List of profile descriptions ordered by name ascending, only the ones marked for showing in metadata editor
+     * @throws ComponentRegistryException
+     */
+    @Override
+    public List<ProfileDescription> getProfileDescriptionsForMetadaEditor() throws ComponentRegistryException {
+        // TODO: Below can also be done by accepting and passing a parameter in the ProfileDescriptionDao, should have better performance
+
+        // Get all profile descriptions
+        List<ProfileDescription> descriptionsCollection = getProfileDescriptions();
+        // Filter out ones that do should not be shown for metadata editor
+        ArrayList<ProfileDescription> descriptions = new ArrayList<ProfileDescription>(descriptionsCollection.size());
+        for (ProfileDescription profile : descriptionsCollection) {
+            if (((ProfileDescription) profile).isShowInEditor()) {
+                descriptions.add((ProfileDescription) profile);
+            }
+        }
+        // Return filtered list
+        return descriptions;
+    }
+
+    /* HELPER METHODS */
+    protected static String stripRegistryId(String id) {
+        return StringUtils.removeStart(id, ComponentRegistry.REGISTRY_ID);
+    }
+
+    protected static void enrichSpecHeader(CMDComponentSpec spec, AbstractDescription description) {
+        Header header = spec.getHeader();
+        header.setID(description.getId());
+        if (StringUtils.isEmpty(header.getName())) {
+            header.setName(description.getName());
+        }
+        if (StringUtils.isEmpty(header.getDescription())) {
+            header.setDescription(description.getDescription());
+        }
+    }
+       
+    protected static boolean findComponentId(String componentId, List<CMDComponentType> componentReferences) {
+        for (CMDComponentType cmdComponent : componentReferences) {
+            if (componentId.equals(cmdComponent.getComponentId())) {
+                return true;
+            } else if (findComponentId(componentId, cmdComponent.getCMDComponent())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    protected static void writeXsd(CMDComponentSpec expandedSpec, OutputStream outputStream) {
+        MDMarshaller.generateXsd(expandedSpec, outputStream);
+    }
+
+    protected static void writeXml(CMDComponentSpec spec, OutputStream outputStream) {
+        try {
+            MDMarshaller.marshal(spec, outputStream);
+        } catch (UnsupportedEncodingException e) {
+            LOG.error("Error in encoding: ", e);
+        } catch (JAXBException e) {
+            LOG.error("Cannot marshall spec: " + spec, e);
+        }
+    }
+
+    protected void checkStillUsed(String componentId) throws DeleteFailedException, ComponentRegistryException {
+        List<ProfileDescription> profiles = getUsageInProfiles(componentId);
+        List<ComponentDescription> components = getUsageInComponents(componentId);
+        if (!profiles.isEmpty() || !components.isEmpty()) {
+            throw new DeleteFailedException(createStillInUseMessage(profiles, components));
+        }
+    }
+
+    private String createStillInUseMessage(List<ProfileDescription> profiles, List<ComponentDescription> components) {
+        StringBuilder result = new StringBuilder();
+        if (!profiles.isEmpty()) {
+            result.append("Still used by the following profiles: \n");
+            for (ProfileDescription profileDescription : profiles) {
+                result.append(" - ").append(profileDescription.getName()).append("\n");
+            }
+        }
+        if (!components.isEmpty()) {
+            result.append("Still used by the following components: \n");
+            for (ComponentDescription componentDescription : components) {
+                result.append(" - ").append(componentDescription.getName()).append("\n");
+            }
+        }
+        result.append("Try to change above mentioned references first.");
+        return result.toString();
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDao.java	(revision 1843)
@@ -0,0 +1,440 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.ParameterizedSingleColumnRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import java.util.Arrays;
+import java.util.Collection;
+import org.apache.commons.collections.ListUtils;
+
+/**
+ * 
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public abstract class AbstractDescriptionDao<T extends AbstractDescription> extends ComponentRegistryDao<T> {
+
+    private final static Logger LOG = LoggerFactory.getLogger(AbstractDescriptionDao.class);
+    @Autowired
+    private PlatformTransactionManager txManager;
+    @Autowired
+    private TransactionDefinition txDefinition;
+
+    protected abstract String getTableName();
+
+    protected abstract String getCMDIdColumn();
+
+    protected abstract String getCommentsForeignKeyColumn();
+    /**
+     * Class object required to instantiate new description domain objects
+     */
+    private final Class<T> _class;
+
+    protected AbstractDescriptionDao(Class<T> _class) {
+	this._class = _class;
+    }
+
+    /**
+     * 
+     * @param cmdId
+     *            CMD id
+     * @return Whether the specified item is in the public space
+     */
+    public boolean isPublic(String cmdId) {
+	StringBuilder query = new StringBuilder("SELECT COUNT(*) FROM ");
+	query.append(getTableName());
+	query.append(" WHERE is_public = true AND ").append(getCMDIdColumn()).append(" = ?");
+	return (0 < getSimpleJdbcTemplate().queryForInt(query.toString(), cmdId));
+    }
+
+    /**
+     * 
+     * @param cmdId
+     *            CMD id
+     * @param userId
+     *            User db id of workspace owner
+     * @return Whether the specified item is in the specified user's workspace
+     */
+    public boolean isInUserSpace(String cmdId, Number userId) {
+	StringBuilder query = new StringBuilder("SELECT COUNT(*) FROM ");
+	query.append(getTableName());
+	query.append(" WHERE is_public = false AND user_id = ? AND ").append(getCMDIdColumn()).append(" = ?");
+	return (0 < getSimpleJdbcTemplate().queryForInt(query.toString(), userId, cmdId));
+    }
+
+    /**
+     * 
+     * @param cmdId
+     *            CMD id
+     * @param userId
+     *            User db id of workspace owner, null for public registry
+     * @return Whether the specified item is in the specified workspace (user or public)
+     */
+    public boolean isInRegistry(String cmdId, Number userId) {
+	if (userId == null) {
+	    return isPublic(cmdId);
+	} else {
+	    return isInUserSpace(cmdId, userId);
+	}
+    }
+
+    /**
+     * 
+     * @param cmdId
+     *            Profile or component Id (not primary key)
+     * @return String value of XML content for profile or component
+     */
+    public String getContent(boolean isDeleted, String cmdId) throws DataAccessException {
+	String select = "SELECT content FROM " + TABLE_XML_CONTENT + " JOIN " + getTableName() + " ON " + TABLE_XML_CONTENT + "."
+		+ COLUMN_ID + " = " + getTableName() + ".content_id" + " WHERE is_deleted = ? AND " + getTableName() + "."
+		+ getCMDIdColumn() + " = ?";
+
+	List<String> result = getSimpleJdbcTemplate().query(select, new ParameterizedSingleColumnRowMapper<String>(), isDeleted, cmdId);
+	if (result.size() > 0) {
+	    return result.get(0);
+	} else {
+	    return null;
+	}
+    }
+
+    /**
+     * @param description
+     *            Description to insert
+     * @param content
+     *            Content to insert and refer to from description
+     * @return Id of newly inserted description
+     */
+    public Number insertDescription(AbstractDescription description, String content, boolean isPublic, Number userId)
+	    throws DataAccessException {
+
+	TransactionStatus transaction = getTransaction();
+	try {
+	    SimpleJdbcInsert insert = new SimpleJdbcInsert(getDataSource()).withTableName(TABLE_XML_CONTENT).usingGeneratedKeyColumns(
+		    COLUMN_ID);
+	    Number contentId = insert.executeAndReturnKey(Collections.singletonMap("content", (Object) content));
+
+	    SimpleJdbcInsert insertDescription = new SimpleJdbcInsert(getDataSource()).withTableName(getTableName()).usingGeneratedKeyColumns(COLUMN_ID);
+	    Map<String, Object> params = new HashMap<String, Object>();
+	    putInsertParameters(params, description, contentId, userId, isPublic);
+
+	    Number id = insertDescription.executeAndReturnKey(params);
+	    txManager.commit(transaction);
+	    return id;
+	} catch (DataAccessException ex) {
+	    txManager.rollback(transaction);
+	    throw ex;
+	}
+    }
+
+    private Timestamp extractTimestamp(AbstractDescription description) {
+	if (description.getRegistrationDate() != null) {
+	    try {
+		Date date = AbstractDescription.getDate(description.getRegistrationDate());
+		return new Timestamp(date.getTime());
+	    } catch (ParseException ex) {
+		LOG.warn("Could not convert registration date " + description.getRegistrationDate() + " to date", ex);
+	    } catch (IllegalArgumentException ex) {
+		LOG.warn("Could not convert registration date " + description.getRegistrationDate() + " to timestamp", ex);
+	    }
+	}
+	return null;
+    }
+
+    /**
+     * Updates a description by database id
+     * 
+     * @param id
+     *            Id (key) of description record
+     * @param description
+     *            New values for description (leave null to not change)
+     * @param content
+     *            New content for description (leave null to not change)
+     */
+    public void updateDescription(Number id, AbstractDescription description, String content) {
+	TransactionStatus transaction = getTransaction();
+	try {
+	    if (description != null) {
+		// Update description
+		StringBuilder updateDescription = new StringBuilder();
+		updateDescription.append("UPDATE ").append(getTableName());
+		appendUpdateColumnsStatement(updateDescription);
+		updateDescription.append(" WHERE " + COLUMN_ID + " = ?");
+		Collection updateParams = ListUtils.union(getUpdateParameterValues(description), Collections.singletonList(id));
+		getSimpleJdbcTemplate().update(updateDescription.toString(), updateParams.toArray());
+	    }
+
+	    if (content != null) {
+		// Update content
+		StringBuilder updateContent = new StringBuilder();
+		updateContent.append("UPDATE " + TABLE_XML_CONTENT + " SET content = ? WHERE " + COLUMN_ID + " = ");
+		updateContent.append("(SELECT content_id FROM ").append(getTableName()).append(" WHERE " + COLUMN_ID + "= ?)");
+
+		getSimpleJdbcTemplate().update(updateContent.toString(), content, id);
+	    }
+	    txManager.commit(transaction);
+	} catch (DataAccessException ex) {
+	    txManager.rollback(transaction);
+	    throw ex;
+	}
+    }
+
+    /**
+     * Retrieves description by it's primary key Id
+     * 
+     * @param id
+     *            Description key
+     * @return The description, if it exists; null otherwise
+     */
+    public T getById(Number id) throws DataAccessException {
+	return getFirstOrNull(getSelectStatement("WHERE is_deleted = false AND id = ?"), id);
+    }
+
+    /**
+     * Get by ComponentId / ProfileId, whether in userspace or public
+     * 
+     * @param id
+     *            Full component id
+     * @return The description, if it exists; null otherwise
+     */
+    public T getByCmdId(String id) throws DataAccessException {
+	return getFirstOrNull(getSelectStatement("WHERE is_deleted = false AND " + getCMDIdColumn() + " = ?"), id);
+    }
+
+    /**
+     * Get by ComponentId / ProfileId
+     * 
+     * @param id
+     *            Full component id
+     * @param userId
+     *            Db id of user for workspace; null for public space
+     * @return The description, if it exists; null otherwise
+     */
+    public T getByCmdId(String id, Number userId) throws DataAccessException {
+	StringBuilder query = new StringBuilder("WHERE is_deleted = false AND ").append(getCMDIdColumn()).append(" = ?");
+	if (userId == null) {
+	    return getFirstOrNull(getSelectStatement(query.append(" AND is_public = true").toString()), id);
+	} else {
+	    return getFirstOrNull(getSelectStatement(query.append(" AND is_public = false AND user_id = ?").toString()), id, userId);
+	}
+    }
+
+    /**
+     * 
+     * @param cmdId
+     *            CMD Id of description
+     * @return Database id for description record
+     */
+    public Number getDbId(String cmdId) {
+	StringBuilder query = new StringBuilder("SELECT " + COLUMN_ID + " FROM ").append(getTableName());
+	query.append(" WHERE ").append(getCMDIdColumn()).append(" = ?");
+	return getSimpleJdbcTemplate().queryForInt(query.toString(), cmdId);
+    }
+
+    /**
+     * 
+     * @return All descriptions in the public space
+     */
+    public List<T> getPublicDescriptions() throws DataAccessException {
+	return getList(getSelectStatement(" WHERE is_deleted = false AND is_public = true ").append(getOrderByClause()));
+    }
+
+    /**
+     * @return List of deleted descriptions in user space or in public when userId=null
+     * @param userId
+     */
+    public List<T> getDeletedDescriptions(Number userId) {
+	if (userId != null) {
+	    String select = getSelectStatement().append(" WHERE is_deleted = true AND is_public = false AND user_id = ?").append(getOrderByClause()).toString();
+	    return getList(select, userId);
+	} else {
+	    String select = getSelectStatement().append(" WHERE is_deleted = true AND is_public = true").append(getOrderByClause()).toString();
+	    return getList(select);
+	}
+    }
+
+    /**
+     * 
+     * @return All the user's descriptions not in the public space
+     */
+    public List<T> getUserspaceDescriptions(Number userId) throws DataAccessException {
+	String select = getSelectStatement().append(" WHERE is_deleted = false AND is_public = false AND user_id = ?").append(getOrderByClause()).toString();
+	return getList(select, userId);
+    }
+
+    public void setDeleted(AbstractDescription desc, boolean isDeleted) throws DataAccessException {
+	TransactionStatus transaction = getTransaction();
+	Number dbId = getDbId(desc.getId());
+	StringBuilder update = new StringBuilder("UPDATE ").append(getTableName());
+	update.append(" SET is_deleted = ").append(Boolean.toString(isDeleted)).append(" WHERE " + COLUMN_ID + " = ?");
+	getSimpleJdbcTemplate().update(update.toString(), dbId);
+	txManager.commit(transaction);
+    }
+
+    public void setPublished(Number id, boolean published) {
+	TransactionStatus transaction = getTransaction();
+	StringBuilder update = new StringBuilder("UPDATE ").append(getTableName());
+	update.append(" SET is_public = ? WHERE " + COLUMN_ID + " = ?");
+	getSimpleJdbcTemplate().update(update.toString(), published, id);
+	txManager.commit(transaction);
+    }
+
+    /**
+     * 
+     * @param id
+     *            Id of description record
+     * @return Principal name of description's owner, if any. Otherwise, null.
+     */
+    public String getOwnerPrincipalName(Number id) {
+	StringBuilder select = new StringBuilder("SELECT principal_name FROM " + TABLE_REGISTRY_USER);
+	select.append(" JOIN ").append(getTableName());
+	select.append(" ON user_id = " + TABLE_REGISTRY_USER + ".id ");
+	select.append(" WHERE ").append(getTableName()).append(".id = ?");
+	List<String> owner = getSimpleJdbcTemplate().query(select.toString(), new ParameterizedSingleColumnRowMapper<String>(), id);
+	if (owner.isEmpty()) {
+	    return null;
+	} else {
+	    return owner.get(0);
+	}
+    }
+
+    /**
+     * @return the rowMapper
+     */
+    @Override
+    protected ParameterizedRowMapper<T> getRowMapper() {
+	return rowMapper;
+    }
+
+    /**
+     * Inserts parameters int <column, value> parameters map
+     * @param params
+     * @param description
+     * @param contentId
+     * @param userId
+     * @param isPublic 
+     */
+    protected void putInsertParameters(Map<String, Object> params, AbstractDescription description, Number contentId, Number userId, boolean isPublic) {
+	params.put("content_id", contentId);
+	params.put("user_id", userId);
+	params.put("is_public", isPublic);
+	params.put("is_deleted", Boolean.FALSE);
+	params.put(getCMDIdColumn(), description.getId());
+	params.put("name", description.getName());
+	params.put("description", description.getDescription());
+	params.put("creator_name", description.getCreatorName());
+	params.put("group_name", description.getGroupName());
+	params.put("domain_name", description.getDomainName());
+	params.put("href", description.getHref());
+	params.put("registration_date", extractTimestamp(description));
+    }
+
+    /**
+     * Sets values on a new description object from specified ResultSet
+     * @param rs ResultSet from database query
+     * @param newDescription Newly created description object to be filled
+     * @throws SQLException 
+     */
+    protected void setDescriptionValuesFromResultSet(ResultSet rs, AbstractDescription newDescription) throws SQLException {
+	Timestamp registrationDate = rs.getTimestamp("registration_date");
+	newDescription.setName(rs.getString("name"));
+	newDescription.setDescription(rs.getString("description"));
+	newDescription.setId(rs.getString(getCMDIdColumn()));
+	newDescription.setRegistrationDate(registrationDate == null ? null : AbstractDescription.createNewDate(registrationDate.getTime()));
+	newDescription.setCreatorName(rs.getString("creator_name"));
+	newDescription.setDomainName(rs.getString("domain_name"));
+	newDescription.setGroupName(rs.getString("group_name"));
+	newDescription.setHref(rs.getString("href"));
+	newDescription.setCommentsCount(rs.getInt("columns_count"));
+
+	Object userId = rs.getObject("user_id");
+	if (!rs.wasNull()) {
+	    newDescription.setUserId(userId.toString());
+	}
+    }
+
+    protected void appendUpdateColumnsStatement(StringBuilder updateDescription) {
+	updateDescription.append(" SET name = ?, description = ?, registration_date=?, creator_name=?, domain_name=?, group_name=?, href=?");
+    }
+
+    protected List getUpdateParameterValues(AbstractDescription description) {
+	List updateParams = Arrays.asList(description.getName(), description.getDescription(),
+		extractTimestamp(description), description.getCreatorName(), description.getDomainName(),
+		description.getGroupName(), description.getHref());
+	return updateParams;
+    }
+    /*
+     * DAO HELPER METHODS
+     */
+
+    private StringBuilder getSelectStatement(String... where) throws DataAccessException {
+	StringBuilder select = new StringBuilder("SELECT ").append(getDescriptionColumnList());
+	select.append(" FROM ").append(getTableName());
+	if (where.length > 0) {
+	    select.append(" ");
+	    for (String str : where) {
+		select.append(" ").append(str);
+	    }
+	}
+	return select;
+    }
+
+    /**
+     * 
+     * @return List of all description columns to be used in SELECT queries
+     */
+    protected StringBuilder getDescriptionColumnList() {
+
+	StringBuilder sb = new StringBuilder();
+	sb.append(getOrderByColumn());
+	sb.append(",description,registration_date,creator_name,domain_name,group_name,href,user_id,");
+	sb.append(getCMDIdColumn());
+	sb.append(", (SELECT COUNT(*) FROM comments WHERE ").append(getCommentsForeignKeyColumn()).append(" = ").append(getCMDIdColumn()).append(") AS columns_count");
+	return sb;
+    }
+
+    private String getOrderByColumn() {
+	return "name";
+    }
+
+    private String getOrderByClause() {
+	return " order by upper(" + getOrderByColumn() + "), " + getCMDIdColumn() + " asc ";
+    }
+    private final ParameterizedRowMapper<T> rowMapper = new ParameterizedRowMapper<T>() {
+
+	@Override
+	public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
+	    try {
+		AbstractDescription newDescription = (AbstractDescription) _class.newInstance();
+		setDescriptionValuesFromResultSet(rs, newDescription);
+		return (T) newDescription;
+	    } catch (InstantiationException ex) {
+		LOG.error("Error in row mapping", ex);
+	    } catch (IllegalAccessException ex) {
+		LOG.error("Error in row mapping", ex);
+	    }
+	    return null;
+	}
+    };
+
+    private TransactionStatus getTransaction() {
+	return txManager.getTransaction(txDefinition);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AdminRegistry.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AdminRegistry.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/AdminRegistry.java	(revision 1843)
@@ -0,0 +1,126 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DataAccessException;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.UserUnauthorizedException;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.frontend.CMDItemInfo;
+import clarin.cmdi.componentregistry.frontend.SubmitFailedException;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+public class AdminRegistry {
+    private final static Logger LOG = LoggerFactory.getLogger(AdminRegistry.class);
+
+    private ComponentRegistryFactory componentRegistryFactory;
+    private ProfileDescriptionDao profileDescriptionDao;
+    private ComponentDescriptionDao componentDescriptionDao;
+
+    public void setComponentRegistryFactory(ComponentRegistryFactory componentRegistryFactory) {
+	this.componentRegistryFactory = componentRegistryFactory;
+    }
+
+    public void setProfileDescriptionDao(ProfileDescriptionDao profileDescriptionDao) {
+	this.profileDescriptionDao = profileDescriptionDao;
+    }
+
+    public void setComponentDescriptionDao(ComponentDescriptionDao componentDescriptionDao) {
+	this.componentDescriptionDao = componentDescriptionDao;
+    }
+
+    public void submitFile(CMDItemInfo info, Principal userPrincipal) throws SubmitFailedException {
+	try {
+	    AbstractDescription originalDescription = info.getDataNode().getDescription();
+	    AbstractDescription description = null;
+	    CMDComponentSpec spec = null;
+	    if (originalDescription.isProfile()) {
+		description = MDMarshaller.unmarshal(ProfileDescription.class, IOUtils.toInputStream(info.getDescription(), "UTF-8"), null);
+	    } else {
+		description = MDMarshaller.unmarshal(ComponentDescription.class, IOUtils.toInputStream(info.getDescription(), "UTF-8"),
+			null);
+	    }
+	    spec = MDMarshaller.unmarshal(CMDComponentSpec.class, IOUtils.toInputStream(info.getContent(), "UTF-8"), null);
+	    checkId(originalDescription.getId(), description.getId());
+
+	    int result = getRegistry(userPrincipal, originalDescription, info).update(description, spec, userPrincipal, info.isForceUpdate());
+	    if (result < 0) {
+		throw new SubmitFailedException("Problem occured while registering, please check the tomcat logs for errors.");
+	    }
+	} catch (JAXBException e) {
+	    throw new SubmitFailedException(e);
+	} catch (IOException e) {
+	    throw new SubmitFailedException(e);
+	}
+    }
+
+    private void checkId(String id, String id2) throws SubmitFailedException {
+	if (id == null || id2 == null || !id.equals(id2)) {
+	    throw new SubmitFailedException("Id's do not match up, you cannot edit id's: id1=" + id + ", id2=" + id2);
+	}
+    }
+
+    public void undelete(CMDItemInfo info) throws SubmitFailedException {
+	AbstractDescription desc = info.getDataNode().getDescription();
+	try {
+	    if (desc.isProfile()) {
+		profileDescriptionDao.setDeleted(desc, false);
+	    } else {
+		componentDescriptionDao.setDeleted(desc, false);
+	    }
+	} catch (DataAccessException e) {
+	    throw new SubmitFailedException("Undelete failed", e);
+	}
+    }
+
+    public void delete(CMDItemInfo info, Principal userPrincipal) throws SubmitFailedException {
+	String id = info.getName();
+	AbstractDescription desc = info.getDataNode().getDescription();
+	try {
+	    deleteFromRegistry(userPrincipal, desc, info);
+	    LOG.info("Deleted item: " + id);
+	} catch (IOException e) {
+	    throw new SubmitFailedException(e);
+	} catch (UserUnauthorizedException e) {
+	    throw new SubmitFailedException(e);
+	} catch (DeleteFailedException e) {
+	    throw new SubmitFailedException(e);
+	} catch (ComponentRegistryException e) {
+	    throw new SubmitFailedException(e);
+	}
+
+    }
+
+    private void deleteFromRegistry(Principal userPrincipal, AbstractDescription desc, CMDItemInfo info) throws IOException,
+	    UserUnauthorizedException, ComponentRegistryException {
+	ComponentRegistry registry = getRegistry(userPrincipal, desc, info);
+	LOG.info("Deleting item: " + desc);
+	if (desc.isProfile()) {
+	    registry.deleteMDProfile(desc.getId(), userPrincipal);
+	} else {
+	    registry.deleteMDComponent(desc.getId(), userPrincipal, info.isForceUpdate());
+	}
+    }
+
+    private ComponentRegistry getRegistry(Principal userPrincipal, AbstractDescription desc, CMDItemInfo info) {
+	ComponentRegistry registry = componentRegistryFactory.getPublicRegistry();
+	if (info.isInUserWorkSpace()) {
+	    registry = componentRegistryFactory.getOtherUserComponentRegistry(userPrincipal, desc.getUserId());
+	}
+	return registry;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecCache.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecCache.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecCache.java	(revision 1843)
@@ -0,0 +1,82 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.apache.commons.collections.map.LRUMap;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class CMDComponentSpecCache implements Map<String, CMDComponentSpec> {
+
+    private Map<String, CMDComponentSpec> specCacheMap;
+
+    public CMDComponentSpecCache() {
+	specCacheMap = Collections.synchronizedMap(new LRUMap(100));
+    }
+
+    @Override
+    public int size() {
+	return specCacheMap.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+	return specCacheMap.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+	return specCacheMap.containsKey(key);
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+	return specCacheMap.containsKey(value);
+    }
+
+    @Override
+    public CMDComponentSpec get(Object key) {
+	return specCacheMap.get(key);
+    }
+
+    @Override
+    public CMDComponentSpec put(String key, CMDComponentSpec value) {
+	return specCacheMap.put(key, value);
+    }
+
+    @Override
+    public CMDComponentSpec remove(Object key) {
+	return specCacheMap.remove(key);
+    }
+
+    @Override
+    public void putAll(Map<? extends String, ? extends CMDComponentSpec> m) {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void clear() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<String> keySet() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Collection<CMDComponentSpec> values() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<Entry<String, CMDComponentSpec>> entrySet() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecExpanderDbImpl.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecExpanderDbImpl.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CMDComponentSpecExpanderDbImpl.java	(revision 1843)
@@ -0,0 +1,39 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.CMDComponentSpecExpander;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class CMDComponentSpecExpanderDbImpl extends CMDComponentSpecExpander {
+
+    private ComponentRegistryDbImpl dbImplRegistry;
+    
+    public CMDComponentSpecExpanderDbImpl(ComponentRegistryDbImpl registry) {
+        super(registry);
+        dbImplRegistry = registry;
+    }
+
+    public static CMDComponentSpec expandComponent(String componentId, ComponentRegistryDbImpl registry) throws ComponentRegistryException {
+        CMDComponentSpecExpanderDbImpl expander = new CMDComponentSpecExpanderDbImpl(registry);
+        return expander.expandComponent(componentId);
+    }
+
+    public static CMDComponentSpec expandProfile(String profileId, ComponentRegistryDbImpl registry) throws ComponentRegistryException {
+        CMDComponentSpecExpanderDbImpl expander = new CMDComponentSpecExpanderDbImpl(registry);
+        return expander.expandProfile(profileId);
+    }
+
+    @Override
+    protected CMDComponentSpec getUncachedComponent(String componentId) throws ComponentRegistryException {
+        return dbImplRegistry.getUncachedMDComponent(componentId);
+    }
+
+    @Override
+    protected CMDComponentSpec getUncachedProfile(String profileId) throws ComponentRegistryException {
+        return dbImplRegistry.getUncachedMDProfile(profileId);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CommentsDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CommentsDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/CommentsDao.java	(revision 1843)
@@ -0,0 +1,250 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.Comment;
+
+import java.util.Date;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.ParameterizedSingleColumnRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
+
+/**
+ *
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+public class CommentsDao extends ComponentRegistryDao<Comment> {
+
+    @Autowired
+    private PlatformTransactionManager txManager;
+    @Autowired
+    private TransactionDefinition txDefinition;
+    private final static Logger LOG = LoggerFactory.getLogger(CommentsDao.class);
+    private final static String SELECT_BASE = "SELECT " + COLUMN_ID + ", comments, comment_date, user_id, "
+            + "component_description_id, profile_description_id, user_name FROM " + TABLE_COMMENTS;
+
+    protected String getTableName() {
+        return TABLE_COMMENTS;
+    }
+
+    protected String getCMDIdColumn() {
+        return COLUMN_ID;
+    }
+
+    /**
+     * Get the list of all the comments available in the database
+     * The distinction between profile or component is not treated in this method
+     * @return list of Comments 
+     */
+    public List<Comment> getAllComments() throws DataAccessException {
+        return getList(SELECT_BASE);
+    }
+
+    /**
+     * Look for a specified Comment through its id
+     * @param id Database record id (key)
+     * @return Comment, if it exists
+     * @throws DataAccessException
+     */
+    public Comment getById(String id) throws DataAccessException {
+        return getFirstOrNull(SELECT_BASE + " WHERE " + COLUMN_ID + " = ?", id);
+    }
+
+    /**
+     * Retrieve the comments related to a certain profile
+     * @param id Database record id (fkey)
+     * @return list of Comments
+     */
+    public List<Comment> getCommentsFromProfile(String profileId) throws DataAccessException {
+        return getList((SELECT_BASE + " WHERE profile_description_id = ?").concat(getOrderByDate()), profileId);
+    }
+
+    /**
+     * Retrieve a specific comment related to a profile
+     * @param id Database record id (key)
+     * @return Comment
+     * @throws DataAccessException 
+     */
+    public Comment getSpecifiedCommentFromProfile(String commentId) throws DataAccessException {
+        return getFirstOrNull(SELECT_BASE + " WHERE " + COLUMN_ID + " = ?", Integer.parseInt(commentId));
+    }
+
+    /**
+     * Retrieve the comments related to a certain component
+     * @param id Database record id (fkey)
+     * @return list of Comments
+     * @throws DataAccessException 
+     */
+    public List<Comment> getCommentsFromComponent(String componentId) throws DataAccessException {
+        return getList((SELECT_BASE + " WHERE component_description_id = ?").concat(getOrderByDate()), componentId);
+    }
+
+    /**
+     * Retrieve a specific comment related to a component
+     * @param id Database record id (key)
+     * @return Comment
+     * @throws DataAccessException 
+     */
+    public Comment getSpecifiedCommentFromComponent(String commentId) throws DataAccessException {
+        return getFirstOrNull(SELECT_BASE + " WHERE " + COLUMN_ID + " =  ?", Integer.parseInt(commentId));
+    }
+
+    /**
+     * 
+     * @param id
+     *            Id of description record
+     * @return Principal name of description's owner, if any. Otherwise, null.
+     */
+    public String getOwnerPrincipalName(Number id) {
+        StringBuilder select = new StringBuilder("SELECT principal_name FROM " + TABLE_REGISTRY_USER);
+        select.append(" JOIN ").append(getTableName());
+        select.append(" ON user_id = " + TABLE_REGISTRY_USER + ".id ");
+        select.append(" WHERE ").append(getTableName()).append(".id = ?");
+        List<String> owner = getSimpleJdbcTemplate().query(select.toString(), new ParameterizedSingleColumnRowMapper<String>(), id);
+        if (owner.isEmpty()) {
+            return null;
+        }
+        {
+            return owner.get(0);
+        }
+    }
+
+    /**
+     *
+     * @param comment
+     *              the comment to be inserted
+     * @param content
+     *              
+     * @param userId
+     *              the id of the user
+     * @return Record id of the inserted comment
+     * @throws DataAccessException
+     */
+    public Number insertComment(Comment comment, Number userId) throws DataAccessException {
+        TransactionStatus transaction = getTransaction();
+        try {
+            SimpleJdbcInsert insertComment = new SimpleJdbcInsert(getDataSource()).withTableName(getTableName()).usingGeneratedKeyColumns(COLUMN_ID);
+            Map<String, Object> params = new HashMap<String, Object>();
+            putInsertComment(params, comment, userId);
+
+            Number id = insertComment.executeAndReturnKey(params);
+            txManager.commit(transaction);
+            return id;
+        } catch (DataAccessException ex) {
+            txManager.rollback(transaction);
+            throw ex;
+        }
+    }
+
+    /**
+     * 
+     * @param params
+     * @param comment
+     * @param contentId
+     * @param userId
+     * @throws DataAccessException 
+     */
+    protected void putInsertComment(Map<String, Object> params, Comment comment, Number userId) throws DataAccessException {
+        params.put("comments", comment.getComment());
+        params.put("comment_date", extractTimestamp(comment));
+        params.put("component_description_id", comment.getComponentDescriptionId());
+        params.put("profile_description_id", comment.getProfileDescriptionId());
+        params.put("user_id", userId);
+	params.put("user_name", comment.getUserName());
+    }
+
+    @Override
+    protected ParameterizedRowMapper<Comment> getRowMapper() {
+        return rowMapper;
+    }
+    private final ParameterizedRowMapper<Comment> rowMapper = new ParameterizedRowMapper<Comment>() {
+
+        @Override
+        public Comment mapRow(ResultSet rs, int rowNumber) throws SQLException {
+            Comment comment = new Comment();
+            Timestamp commentDate = rs.getTimestamp("comment_date");
+            comment.setId(rs.getString(COLUMN_ID));
+            comment.setComment(rs.getString("comments"));
+            comment.setComponentDescriptionId(rs.getString("component_description_id"));
+            comment.setProfileDescriptionId(rs.getString("profile_description_id"));
+            comment.setUserId(rs.getString("user_id"));
+	    comment.setUserName(rs.getString("user_name"));
+            comment.setCommentDate(commentDate == null ? null : Comment.createNewDate(commentDate.getTime()));
+            return comment;
+        }
+    };
+
+    /**
+     * Method that will delete a comment from the database based on its id
+     * @param com
+     *           comment to be deleted
+     * @throws DataAccessException 
+     */
+    public void deleteComment(Comment com) throws DataAccessException {
+        TransactionStatus transaction = getTransaction();
+        Number dbId = Integer.parseInt(com.getId());
+        StringBuilder delete = new StringBuilder("DELETE FROM ").append(getTableName());
+        delete.append(" WHERE " + COLUMN_ID + " = ?");
+        getSimpleJdbcTemplate().update(delete.toString(), dbId);
+        txManager.commit(transaction);
+    }
+
+    /**
+     * Retrieve comment Id From a comment
+     * @param cmdId
+     * @return query for database access to id
+     */
+    public Number getDbId(String cmdId) {
+        StringBuilder query = new StringBuilder("SELECT " + COLUMN_ID + " FROM ").append(getTableName());
+        query.append(" WHERE ").append(COLUMN_ID).append(" = ?");
+        return getSimpleJdbcTemplate().queryForInt(query.toString(), cmdId);
+    }
+
+    private Timestamp extractTimestamp(Comment comment) {
+        if (comment.getCommentDate() != null) {
+            try {
+                Date date = Comment.getDate(comment.getCommentDate());
+                return new Timestamp(date.getTime());
+            } catch (ParseException ex) {
+                LOG.warn("Could not convert registration date " + comment.getCommentDate() + " to date", ex);
+            } catch (IllegalArgumentException ex) {
+                LOG.warn("Could not convert registration date " + comment.getCommentDate() + " to timestamp", ex);
+            }
+        }
+        return null;
+    }
+
+    private TransactionStatus getTransaction() {
+        return txManager.getTransaction(txDefinition);
+    }
+
+    /**
+     * Method use for tests that will select comments based on the content
+     * @param aComment
+     * @return list of Comments
+     * @throws DataAccessException 
+     */
+    public Comment getByComment(String aComment) throws DataAccessException {
+        return getFirstOrNull(SELECT_BASE + " WHERE comments = ?", aComment);
+    }
+    
+    /**
+     * Sort the returned comments per date from the most recent to the oldest
+     * @return 
+     */
+        private String getOrderByDate() {
+	return " order by comment_date asc ";
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDao.java	(revision 1843)
@@ -0,0 +1,34 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import java.util.List;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ComponentDescriptionDao extends AbstractDescriptionDao<ComponentDescription> {
+
+    public ComponentDescriptionDao() {
+	super(ComponentDescription.class);
+    }
+
+    @Override
+    protected String getTableName() {
+	return TABLE_COMPONENT_DESCRIPTION;
+    }
+
+    @Override
+    protected String getCMDIdColumn() {
+	return "component_id";
+    }
+
+    @Override
+    protected String getCommentsForeignKeyColumn() {
+	return "component_description_id";
+    }
+
+    public List<ComponentDescription> getPublicComponentDescriptions() {
+	return getPublicDescriptions();
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryBeanFactory.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryBeanFactory.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryBeanFactory.java	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+/**
+ * Interface for a simple service factory (with ComponentRegistry implementation
+ * being the service), required for injecting the dao's into the
+ * component registry instances.
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public interface ComponentRegistryBeanFactory {
+
+    public ComponentRegistryDbImpl getNewComponentRegistry();
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDao.java	(revision 1843)
@@ -0,0 +1,51 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import java.util.List;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;
+
+/**
+ * Logic and constants shared by the dao's of the DB implementation
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ * @param <T> Type the dao maps to
+ */
+public abstract class ComponentRegistryDao<T> extends SimpleJdbcDaoSupport {
+
+
+    public final static String TABLE_COMMENTS = "comments";
+    public final static String TABLE_COMPONENT_DESCRIPTION = "component_description";
+    public final static String TABLE_PROFILE_DESCRIPTION = "profile_description";
+    public final static String TABLE_XML_CONTENT = "xml_content";
+    public final static String TABLE_REGISTRY_USER = "registry_user";
+    public final static String COLUMN_ID = "id";
+    
+
+    public ComponentRegistryDao() {
+    }
+
+    protected T getFirstOrNull(StringBuilder selectQuery, Object... args) {
+	return getFirstOrNull(selectQuery.toString(), args);
+    }
+
+    protected T getFirstOrNull(String selectQuery, Object... args) {
+	List<T> list = getList(selectQuery, args);
+	if (list.size() > 0) {
+	    return list.get(0);
+	} else {
+	    return null;
+	}
+    }
+
+    protected List<T> getList(StringBuilder selectQuery, Object... args) {
+	return getList(selectQuery.toString(), args);
+    }
+
+    protected List<T> getList(String selectQuery, Object... args) {
+	return getSimpleJdbcTemplate().query(selectQuery, getRowMapper(), args);
+    }
+
+    /**
+     * @return the rowMapper
+     */
+    protected abstract ParameterizedRowMapper<T> getRowMapper();
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImpl.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImpl.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImpl.java	(revision 1843)
@@ -0,0 +1,644 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.CMDComponentSpecExpander;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.dao.DataAccessException;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.Configuration;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.UserUnauthorizedException;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.impl.ComponentRegistryImplBase;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+
+/**
+ * Implementation of ComponentRegistry that uses Database Acces Objects for
+ * accessing the registry (ergo: a database implementation)
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ComponentRegistryDbImpl extends ComponentRegistryImplBase implements ComponentRegistry {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryDbImpl.class);
+    private Number userId;
+    @Autowired
+    private Configuration configuration;
+    @Autowired
+    private ProfileDescriptionDao profileDescriptionDao;
+    @Autowired
+    private ComponentDescriptionDao componentDescriptionDao;
+    @Autowired
+    private UserDao userDao;
+    @Autowired
+    @Qualifier("componentsCache")
+    private CMDComponentSpecCache componentsCache;
+    @Autowired
+    @Qualifier("profilesCache")
+    private CMDComponentSpecCache profilesCache;
+    @Autowired
+    private CommentsDao commentsDao;
+
+    /**
+     * Default constructor, makes this a (spring) bean. No user is set, so
+     * public registry by default. Use setUser() to make it a user registry.
+     *
+     * @see setUser
+     */
+    public ComponentRegistryDbImpl() {
+    }
+
+    /**
+     * Creates a new ComponentRegistry (either public or not) for the provided
+     * user
+     *
+     * @param userId
+     * User id of the user to create registry for. Pass null for
+     * public
+     */
+    public ComponentRegistryDbImpl(Number userId) {
+	this.userId = userId;
+    }
+
+    @Override
+    public List<ProfileDescription> getProfileDescriptions() throws ComponentRegistryException {
+	try {
+	    if (isPublic()) {
+		return profileDescriptionDao.getPublicProfileDescriptions();
+	    } else {
+		return profileDescriptionDao.getUserspaceDescriptions(getUserId());
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get profile descriptions", ex);
+	}
+    }
+
+    @Override
+    public ProfileDescription getProfileDescription(String id) throws ComponentRegistryException {
+	try {
+	    return profileDescriptionDao.getByCmdId(id, getUserId());
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get profile description", ex);
+	}
+    }
+
+    @Override
+    public List<ComponentDescription> getComponentDescriptions() throws ComponentRegistryException {
+	try {
+	    if (isPublic()) {
+		return componentDescriptionDao.getPublicComponentDescriptions();
+	    } else {
+		return componentDescriptionDao.getUserspaceDescriptions(getUserId());
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get component descriptions", ex);
+	}
+    }
+
+    @Override
+    public ComponentDescription getComponentDescription(String id) throws ComponentRegistryException {
+	try {
+	    return componentDescriptionDao.getByCmdId(id, getUserId());
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get component description", ex);
+	}
+    }
+
+    @Override
+    public List<Comment> getCommentsInProfile(String profileId) throws ComponentRegistryException {
+	try {
+	    if (profileDescriptionDao.isInRegistry(profileId, getUserId())) {
+		return commentsDao.getCommentsFromProfile(profileId);
+	    } else {
+		// Profile does not exist (at least not in this registry)
+		throw new ComponentRegistryException("Profile " + profileId + " does not exist in specified registry");
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get list of comments from profile", ex);
+	}
+    }
+
+    @Override
+    public Comment getSpecifiedCommentInProfile(String profileId, String commentId) throws ComponentRegistryException {
+	try {
+	    Comment comment = commentsDao.getSpecifiedCommentFromProfile(commentId);
+	    if (comment != null
+		    && profileId.equals(comment.getProfileDescriptionId())
+		    && profileDescriptionDao.isInRegistry(comment.getProfileDescriptionId(), getUserId())) {
+		return comment;
+	    } else {
+		// Comment exists in DB, but profile is not in this registry
+		throw new ComponentRegistryException("Comment " + commentId + " cannot be found in specified registry");
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get comment from profile", ex);
+	}
+    }
+
+    @Override
+    public List<Comment> getCommentsInComponent(String componentId) throws ComponentRegistryException {
+	try {
+	    if (componentDescriptionDao.isInRegistry(componentId, getUserId())) {
+		return commentsDao.getCommentsFromComponent(componentId);
+	    } else {
+		// Component does not exist (at least not in this registry)
+		throw new ComponentRegistryException("Component " + componentId + " does not exist in specified registry");
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get list of comments from component", ex);
+	}
+    }
+
+    @Override
+    public Comment getSpecifiedCommentInComponent(String componentId, String commentId) throws ComponentRegistryException {
+	try {
+	    Comment comment = commentsDao.getSpecifiedCommentFromComponent(commentId);
+	    if (comment != null
+		    && componentId.equals(comment.getComponentDescriptionId())
+		    && componentDescriptionDao.isInRegistry(comment.getComponentDescriptionId(), getUserId())) {
+		return comment;
+	    } else {
+		// Comment does not exists in DB or component is not in this registry
+		throw new ComponentRegistryException("Comment " + commentId + " cannot be found in specified registry for specified component");
+	    }
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get comment from component", ex);
+	}
+    }
+
+    @Override
+    public CMDComponentSpec getMDProfile(String id) throws ComponentRegistryException {
+	if (inWorkspace(profileDescriptionDao, id)) {
+	    CMDComponentSpec result = profilesCache.get(id);
+	    if (result == null && !profilesCache.containsKey(id)) {
+		result = getUncachedMDProfile(id);
+		profilesCache.put(id, result);
+	    }
+	    return result;
+	} else {
+	    // May exist, but not in this workspace
+	    return null;
+	}
+    }
+
+    public CMDComponentSpec getUncachedMDProfile(String id) throws ComponentRegistryException {
+	try {
+	    return getUncachedMDComponent(id, profileDescriptionDao);
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get profile", ex);
+	}
+    }
+
+    @Override
+    public CMDComponentSpec getMDComponent(String id) throws ComponentRegistryException {
+	if (inWorkspace(componentDescriptionDao, id)) {
+	    CMDComponentSpec result = componentsCache.get(id);
+	    if (result == null && !componentsCache.containsKey(id)) {
+		result = getUncachedMDComponent(id);
+		componentsCache.put(id, result);
+	    }
+	    return result;
+	} else {
+	    return null;
+	}
+    }
+
+    public CMDComponentSpec getUncachedMDComponent(String id) throws ComponentRegistryException {
+	try {
+	    return getUncachedMDComponent(id, componentDescriptionDao);
+	} catch (DataAccessException ex) {
+	    throw new ComponentRegistryException("Database access error while trying to get component", ex);
+	}
+    }
+
+    @Override
+    public int register(AbstractDescription description, CMDComponentSpec spec) {
+	enrichSpecHeader(spec, description);
+	try {
+	    String xml = componentSpecToString(spec);
+	    // Convert principal name to user record id
+	    Number uid = convertUserInDescription(description);
+	    getDaoForDescription(description).insertDescription(description, xml, isPublic(), uid);
+	    invalidateCache(description);
+	    return 0;
+	} catch (DataAccessException ex) {
+	    LOG.error("Database error while registering component", ex);
+	    return -1;
+	} catch (JAXBException ex) {
+	    LOG.error("Error while registering component", ex);
+	    return -2;
+	} catch (UnsupportedEncodingException ex) {
+	    LOG.error("Error while registering component", ex);
+	    return -3;
+	}
+    }
+
+    @Override
+    public int registerComment(Comment comment, String principalName) throws ComponentRegistryException {
+	try {
+	    if (comment.getComponentDescriptionId() != null && componentDescriptionDao.isInRegistry(comment.getComponentDescriptionId(), getUserId())
+		    || comment.getProfileDescriptionId() != null && profileDescriptionDao.isInRegistry(comment.getProfileDescriptionId(), getUserId())) {
+		// Convert principal name to user record id
+		Number uid = convertUserIdInComment(comment, principalName);
+		// Set date to current date
+		comment.setCommentDate(Comment.createNewDate());
+		Number commentId = commentsDao.insertComment(comment, uid);
+		comment.setId(commentId.toString());
+	    } else {
+		throw new ComponentRegistryException("Cannot insert comment into this registry. Unknown profileId or componentId");
+	    }
+	    return 0;
+	} catch (DataAccessException ex) {
+	    LOG.error("Database error while registering component", ex);
+	    return -1;
+	}
+    }
+
+    /**
+     * Calling service sets user id to principle. Our task is to convert this to
+     * an id for later reference. If none is set and this is a user's workspace,
+     * set from that user's id.
+     *
+     * It also sets the name in the description according to the display name in the database.
+     *
+     * @param description
+     * Description containing principle name as userId
+     * @return Id (from database)
+     * @throws DataAccessException
+     */
+    private Number convertUserInDescription(AbstractDescription description) throws DataAccessException {
+	Number uid = null;
+	String name = null;
+	if (description.getUserId() != null) {
+	    RegistryUser user = userDao.getByPrincipalName(description.getUserId());
+	    if (user != null) {
+		uid = user.getId();
+		name = user.getName();
+	    }
+	} else {
+	    uid = userId;
+	}
+	if (uid != null) {
+	    description.setUserId(uid.toString());
+	}
+	if (name != null) {
+	    description.setCreatorName(name);
+	}
+	return uid;
+    }
+
+    /**
+     * Calling service sets user id to principle. Our task is to convert this to
+     * an id for later reference. If none is set and this is a user's workspace,
+     * set from that user's id.
+     *
+     * @param comment
+     * Comment containing principle name as userId
+     * @return Id (from database)
+     * @throws DataAccessException
+     */
+    private Number convertUserIdInComment(Comment comment, String principalName) throws DataAccessException, ComponentRegistryException {
+	if (principalName != null) {
+	    RegistryUser user = userDao.getByPrincipalName(principalName);
+	    if (user != null) {
+		Number id = user.getId();
+		if (id != null) {
+		    // Set user id in comment for convenience of calling method 
+		    comment.setUserId(id.toString());
+		    // Set name to user's preferred display name
+		    comment.setUserName(user.getName());
+		    return id;
+		} else {
+		    throw new ComponentRegistryException("Cannot find user with principal name: " + principalName);
+		}
+	    }
+	}
+	return null;
+    }
+
+    @Override
+    public int update(AbstractDescription description, CMDComponentSpec spec, Principal principal, boolean forceUpdate) {
+	try {
+	    checkAuthorisation(description, principal);
+	    checkAge(description, principal);
+	    // For public components, check if used in other components or profiles (unless forced)
+	    if (!forceUpdate && this.isPublic() && !description.isProfile()) {
+		checkStillUsed(description.getId());
+	    }
+	    AbstractDescriptionDao<?> dao = getDaoForDescription(description);
+	    dao.updateDescription(getIdForDescription(description), description, componentSpecToString(spec));
+	    invalidateCache(description);
+	    return 0;
+	} catch (JAXBException ex) {
+	    LOG.error("Error while updating component", ex);
+	    return -1;
+	} catch (UnsupportedEncodingException ex) {
+	    LOG.error("Error while updating component", ex);
+	    return -1;
+	} catch (IllegalArgumentException ex) {
+	    LOG.error("Error while updating component", ex);
+	    return -1;
+	} catch (UserUnauthorizedException e) {
+	    LOG.error("Error while updating component", e);
+	    return -1;
+	} catch (DeleteFailedException e) {
+	    LOG.error("Error while updating component", e);
+	    return -1;
+	} catch (ComponentRegistryException e) {
+	    LOG.error("Error while updating component", e);
+	    return -1;
+	}
+    }
+
+    @Override
+    public int publish(AbstractDescription desc, CMDComponentSpec spec, Principal principal) {
+	int result = 0;
+	AbstractDescriptionDao<?> dao = getDaoForDescription(desc);
+	if (!isPublic()) { // if already in public workspace there is nothing todo
+	    desc.setHref(AbstractDescription.createPublicHref(desc.getHref()));
+	    Number id = getIdForDescription(desc);
+	    try {
+		// Update description & content
+		dao.updateDescription(id, desc, componentSpecToString(spec));
+		// Set to public
+		dao.setPublished(id, true);
+	    } catch (DataAccessException ex) {
+		LOG.error("Database error while updating component", ex);
+		return -1;
+	    } catch (JAXBException ex) {
+		LOG.error("Error while updating component", ex);
+		return -2;
+	    } catch (UnsupportedEncodingException ex) {
+		LOG.error("Error while updating component", ex);
+		return -3;
+	    }
+	}
+	return result;
+    }
+
+    @Override
+    public void getMDProfileAsXml(String profileId, OutputStream output) throws ComponentRegistryException {
+	CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandProfile(profileId, this);
+	writeXml(expandedSpec, output);
+    }
+
+    @Override
+    public void getMDProfileAsXsd(String profileId, OutputStream outputStream) throws ComponentRegistryException {
+	CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandProfile(profileId, this);
+	writeXsd(expandedSpec, outputStream);
+    }
+
+    @Override
+    public void getMDComponentAsXml(String componentId, OutputStream output) throws ComponentRegistryException {
+	CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandComponent(componentId, this);
+	writeXml(expandedSpec, output);
+    }
+
+    @Override
+    public void getMDComponentAsXsd(String componentId, OutputStream outputStream) throws ComponentRegistryException {
+	CMDComponentSpec expandedSpec = CMDComponentSpecExpanderDbImpl.expandComponent(componentId, this);
+	writeXsd(expandedSpec, outputStream);
+    }
+
+    @Override
+    public void deleteMDProfile(String profileId, Principal principal) throws UserUnauthorizedException, DeleteFailedException,
+	    ComponentRegistryException {
+	ProfileDescription desc = getProfileDescription(profileId);
+	if (desc != null) {
+	    try {
+		checkAuthorisation(desc, principal);
+		checkAge(desc, principal);
+		profileDescriptionDao.setDeleted(desc, true);
+		invalidateCache(desc);
+	    } catch (DataAccessException ex) {
+		throw new DeleteFailedException("Database access error while trying to delete profile", ex);
+	    }
+	}
+    }
+
+    @Override
+    public void deleteMDComponent(String componentId, Principal principal, boolean forceDelete) throws UserUnauthorizedException,
+	    DeleteFailedException, ComponentRegistryException {
+	ComponentDescription desc = componentDescriptionDao.getByCmdId(componentId);
+	if (desc != null) {
+	    try {
+		checkAuthorisation(desc, principal);
+		checkAge(desc, principal);
+
+		if (!forceDelete) {
+		    checkStillUsed(componentId);
+		}
+		componentDescriptionDao.setDeleted(desc, true);
+		invalidateCache(desc);
+	    } catch (DataAccessException ex) {
+		throw new DeleteFailedException("Database access error while trying to delete component", ex);
+	    }
+	}
+    }
+
+    @Override
+    public boolean isPublic() {
+	return null == userId;
+    }
+
+    public void setPublic() {
+	this.userId = null;
+    }
+
+    /**
+     * @return The user, or null if this is the public registry.
+     */
+    public Number getUserId() {
+	return userId;
+    }
+
+    /**
+     * @param User
+     * for which this should be the registry. Pass null for the
+     * public registry
+     */
+    public void setUserId(Number user) {
+	this.userId = user;
+    }
+
+    private void invalidateCache(AbstractDescription description) {
+	if (description.isProfile()) {
+	    profilesCache.remove(description.getId());
+	} else {
+	    componentsCache.remove(description.getId());
+	}
+    }
+
+    private AbstractDescriptionDao<?> getDaoForDescription(AbstractDescription description) {
+	return description.isProfile() ? profileDescriptionDao : componentDescriptionDao;
+    }
+
+    /**
+     * Looks up description on basis of CMD Id. This will also check if such a
+     * record even exists.
+     *
+     * @param description
+     * Description to look up
+     * @return Database id for description
+     * @throws IllegalArgumentException
+     * If description with non-existing id is passed
+     */
+    private Number getIdForDescription(AbstractDescription description) throws IllegalArgumentException {
+	Number dbId = null;
+	AbstractDescriptionDao<?> dao = getDaoForDescription(description);
+	try {
+	    dbId = dao.getDbId(description.getId());
+	} catch (DataAccessException ex) {
+	    LOG.error("Error getting dbId for component with id " + description.getId(), ex);
+	}
+	if (dbId == null) {
+	    throw new IllegalArgumentException("Could not get database Id for description");
+	} else {
+	    return dbId;
+	}
+    }
+
+    private String componentSpecToString(CMDComponentSpec spec) throws UnsupportedEncodingException, JAXBException {
+	ByteArrayOutputStream os = new ByteArrayOutputStream();
+	MDMarshaller.marshal(spec, os);
+	String xml = os.toString("UTF-8");
+	return xml;
+    }
+
+    private CMDComponentSpec getUncachedMDComponent(String id, AbstractDescriptionDao dao) {
+	String xml = dao.getContent(false, id);
+	if (xml != null) {
+	    try {
+		InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
+		return MDMarshaller.unmarshal(CMDComponentSpec.class, is, null);
+
+	    } catch (JAXBException ex) {
+		LOG.error(null, ex);
+	    } catch (UnsupportedEncodingException ex) {
+		LOG.error(null, ex);
+	    }
+	}
+	return null;
+    }
+
+    private void checkAuthorisation(AbstractDescription desc, Principal principal) throws UserUnauthorizedException {
+	if (!isOwnerOfDescription(desc, principal.getName()) && !configuration.isAdminUser(principal)) {
+	    throw new UserUnauthorizedException("Unauthorized operation user '" + principal.getName()
+		    + "' is not the creator (nor an administrator) of the " + (desc.isProfile() ? "profile" : "component") + "(" + desc
+		    + ").");
+	}
+    }
+
+    private void checkAuthorisationComment(Comment desc, Principal principal) throws UserUnauthorizedException {
+	if (!isOwnerOfComment(desc, principal.getName()) && !configuration.isAdminUser(principal)) {
+	    throw new UserUnauthorizedException("Unauthorized operation user '" + principal.getName()
+		    + "' is not the creator (nor an administrator) of the " + (desc.getId()) + "(" + desc
+		    + ").");
+	}
+    }
+
+    private boolean isOwnerOfDescription(AbstractDescription desc, String principalName) {
+	String owner = getDaoForDescription(desc).getOwnerPrincipalName(getIdForDescription(desc));
+	return owner != null // If owner is null, no one can be owner
+		&& principalName.equals(owner);
+    }
+
+    private boolean isOwnerOfComment(Comment com, String principalName) {
+	String owner = commentsDao.getOwnerPrincipalName(Integer.parseInt(com.getId()));
+	return owner != null // If owner is null, no one can be owner
+		&& principalName.equals(owner);
+    }
+
+    private void checkAge(AbstractDescription desc, Principal principal) throws DeleteFailedException {
+	if (isPublic() && !configuration.isAdminUser(principal)) {
+	    try {
+		Date regDate = AbstractDescription.getDate(desc.getRegistrationDate());
+		Calendar calendar = Calendar.getInstance();
+		calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);
+		if (regDate.before(calendar.getTime())) { // More then month old
+		    throw new DeleteFailedException(
+			    "The "
+			    + (desc.isProfile() ? "Profile" : "Component")
+			    + " is more then a month old and cannot be deleted anymore. It might have been used to create metadata, deleting it would invalidate that metadata.");
+		}
+	    } catch (ParseException e) {
+		LOG.error("Cannot parse date of " + desc + " Error:" + e);
+	    }
+	}
+    }
+
+    private boolean inWorkspace(AbstractDescriptionDao<?> dao, String cmdId) {
+	if (isPublic()) {
+	    return dao.isPublic(cmdId);
+	} else {
+	    return dao.isInUserSpace(cmdId, getUserId());
+	}
+    }
+
+    @Override
+    public String getName() {
+	if (isPublic()) {
+	    return ComponentRegistry.PUBLIC_NAME;
+	} else {
+	    return "Registry of " + userDao.getById(getUserId()).getName();
+	}
+    }
+
+    @Override
+    public List<ProfileDescription> getDeletedProfileDescriptions() {
+	return profileDescriptionDao.getDeletedDescriptions(getUserId());
+    }
+
+    @Override
+    public List<ComponentDescription> getDeletedComponentDescriptions() {
+	return componentDescriptionDao.getDeletedDescriptions(getUserId());
+    }
+
+    @Override
+    public void deleteComment(String commentId, Principal principal) throws IOException,
+	    ComponentRegistryException, UserUnauthorizedException, DeleteFailedException {
+	try {
+	    Comment comment = commentsDao.getById(commentId);
+	    if (comment != null
+		    // Comment must have an existing (in this registry) componentId or profileId
+		    && (comment.getComponentDescriptionId() != null && componentDescriptionDao.isInRegistry(comment.getComponentDescriptionId(), getUserId())
+		    || comment.getProfileDescriptionId() != null && profileDescriptionDao.isInRegistry(comment.getProfileDescriptionId(), getUserId()))) {
+		checkAuthorisationComment(comment, principal);
+		commentsDao.deleteComment(comment);
+	    } else {
+		// Comment exists in DB, but component is not in this registry
+		throw new ComponentRegistryException("Comment " + commentId + " cannot be found in specified registry");
+	    }
+	} catch (DataAccessException ex) {
+	    throw new DeleteFailedException("Database access error while trying to delete component", ex);
+	}
+    }
+
+    @Override
+    public CMDComponentSpecExpander getExpander() {
+	return new CMDComponentSpecExpanderDbImpl(this);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImpl.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImpl.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImpl.java	(revision 1843)
@@ -0,0 +1,130 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.Configuration;
+import clarin.cmdi.componentregistry.UserCredentials;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+
+/**
+ * Implementation of ComponentRegistryFactory that uses the
+ * ComponentRegistryDbImpl implementation of ComponentRegistry for accessing the
+ * registry
+ * 
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ComponentRegistryFactoryDbImpl implements ComponentRegistryFactory {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryFactoryDbImpl.class);
+    @Autowired
+    private Configuration configuration;
+    @Autowired
+    private ComponentRegistryBeanFactory componentRegistryBeanFactory;
+    @Autowired
+    private UserDao userDao;
+    private ComponentRegistry publicComponentRegistry = null;
+
+    @Override
+    public List<ComponentRegistry> getAllUserRegistries() {
+	// TODO: this probably could use some caching
+	try {
+	    List<RegistryUser> users = userDao.getAllUsers();
+	    List<ComponentRegistry> registries = new ArrayList<ComponentRegistry>();
+	    for (RegistryUser user : users) {
+		registries.add(getNewComponentRegistryForUser(user.getId()));
+	    }
+	    return registries;
+	} catch (DataAccessException ex) {
+	    LOG.error("Could not retrieve users", ex);
+	    throw ex;
+	}
+    }
+
+    @Override
+    public ComponentRegistry getComponentRegistry(boolean userspace, UserCredentials credentials) {
+	ComponentRegistry result = null;
+	if (userspace) {
+	    RegistryUser user = getOrCreateUser(credentials);
+	    if (user != null) {
+		try {
+		    result = getNewComponentRegistryForUser(user.getId());
+		} catch (DataAccessException ex) {
+		    LOG.error("Could not retrieve or create user", ex);
+		    throw ex;
+		}
+	    } else {
+		throw new IllegalArgumentException("No user credentials available cannot load userspace.");
+	    }
+	} else {
+	    result = getPublicRegistry();
+	}
+	return result;
+    }
+
+    @Override
+    public ComponentRegistry getOtherUserComponentRegistry(Principal adminPrincipal, String userId) {
+	try {
+	    RegistryUser user = userDao.getById(Integer.parseInt(userId));
+	    ComponentRegistry result = null;
+	    if (user != null) {
+		if (configuration.isAdminUser(adminPrincipal)) {
+		    result = getNewComponentRegistryForUser(user.getId());
+		} else {
+		    LOG.info(adminPrincipal.getName() + " not found in list of " + configuration.getAdminUsersArray().length);
+		    throw new IllegalArgumentException("User " + adminPrincipal.getName() + " is not admin user cannot load userspace.");
+		}
+	    }
+	    return result;
+	} catch (DataAccessException ex) {
+	    LOG.error("Could not retrieve user by id", ex);
+	    throw ex;
+	}
+    }
+
+    @Override
+    public ComponentRegistry getPublicRegistry() {
+	if (publicComponentRegistry == null) {
+	    publicComponentRegistry = getNewComponentRegistryForUser(null);
+	}
+	return publicComponentRegistry;
+    }
+
+    private ComponentRegistry getNewComponentRegistryForUser(Number userId) {
+	ComponentRegistryDbImpl componentRegistry = componentRegistryBeanFactory.getNewComponentRegistry();
+	componentRegistry.setUserId(userId);
+	return componentRegistry;
+    }
+
+    @Override
+    public RegistryUser getOrCreateUser(UserCredentials credentials) {
+	if (credentials != null && !ANONYMOUS_USER.equals(credentials.getPrincipalName())) {
+	    String principalName = credentials.getPrincipalName();
+	    return getOrCreateUser(principalName, credentials.getDisplayName());
+	}
+	return null;
+    }
+
+    private synchronized RegistryUser getOrCreateUser(String principalName, String displayName) {
+	// Try getting it from db
+	RegistryUser user = userDao.getByPrincipalName(principalName);
+	if (user == null) {
+	    // Create the new user
+	    user = new RegistryUser();
+	    user.setPrincipalName(principalName);
+	    user.setName(displayName);
+	    userDao.insertUser(user);
+	    // Retrieve from db
+	    user = userDao.getByPrincipalName(principalName);
+	}
+	return user;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDao.java	(revision 1843)
@@ -0,0 +1,71 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections.ListUtils;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ProfileDescriptionDao extends AbstractDescriptionDao<ProfileDescription> {
+
+    public ProfileDescriptionDao() {
+	super(ProfileDescription.class);
+    }
+
+    public List<ProfileDescription> getPublicProfileDescriptions() {
+	return getPublicDescriptions();
+    }
+
+    @Override
+    protected String getTableName() {
+	return TABLE_PROFILE_DESCRIPTION;
+    }
+
+    @Override
+    protected String getCMDIdColumn() {
+	return "profile_id";
+    }
+
+    @Override
+    protected String getCommentsForeignKeyColumn() {
+	return "profile_description_id";
+    }
+
+    @Override
+    protected StringBuilder getDescriptionColumnList() {
+	return super.getDescriptionColumnList().append(",show_in_editor");
+    }
+
+    @Override
+    protected void putInsertParameters(Map<String, Object> params, AbstractDescription description, Number contentId, Number userId, boolean isPublic) {
+	super.putInsertParameters(params, description, contentId, userId, isPublic);
+	params.put("show_in_editor", ((ProfileDescription) description).isShowInEditor());
+    }
+
+    @Override
+    protected void setDescriptionValuesFromResultSet(ResultSet rs, AbstractDescription newDescription) throws SQLException {
+	super.setDescriptionValuesFromResultSet(rs, newDescription);
+	((ProfileDescription) newDescription).setShowInEditor(rs.getBoolean("show_in_editor"));
+    }
+
+    @Override
+    protected void appendUpdateColumnsStatement(StringBuilder updateDescription) {
+	super.appendUpdateColumnsStatement(updateDescription);
+	updateDescription.append(" , show_in_editor=?");
+    }
+
+    @Override
+    protected List getUpdateParameterValues(AbstractDescription description) {
+	return ListUtils.union(
+		super.getUpdateParameterValues(description),
+		// Add value for 'shown_in_editor' to abstract description
+		Collections.singletonList(((ProfileDescription) description).isShowInEditor()));
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/UserDao.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/UserDao.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/impl/database/UserDao.java	(revision 1843)
@@ -0,0 +1,87 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class UserDao extends ComponentRegistryDao<RegistryUser> {
+
+    private final static String SELECT_BASE = "SELECT " + COLUMN_ID + ", name, principal_name FROM " + TABLE_REGISTRY_USER;
+
+    public List<RegistryUser> getAllUsers() throws DataAccessException {
+	return getList(SELECT_BASE);
+    }
+
+    /**
+     *
+     * @param principalName User's principal name
+     * @return User, if it exists
+     * @throws DataAccessException
+     */
+    public RegistryUser getByPrincipalName(String principalName) throws DataAccessException {
+	return getFirstOrNull(SELECT_BASE + " WHERE principal_name = ?", principalName);
+    }
+
+    /**
+     *
+     * @param id Database record id (key)
+     * @return User, if it exists
+     * @throws DataAccessException
+     */
+    public RegistryUser getById(Number id) throws DataAccessException {
+	return getFirstOrNull(SELECT_BASE + " WHERE " + COLUMN_ID + " = ?", id);
+    }
+
+    /**
+     *
+     * @param user
+     * @return Record id of the inserted user
+     * @throws DataAccessException
+     */
+    public Number insertUser(RegistryUser user) throws DataAccessException {
+	SimpleJdbcInsert insert = new SimpleJdbcInsert(getDataSource()).withTableName(TABLE_REGISTRY_USER).usingGeneratedKeyColumns(
+		COLUMN_ID);
+
+	Map<String, Object> params = new HashMap<String, Object>();
+	params.put("name", user.getName());
+	params.put("principal_name", user.getPrincipalName());
+	return insert.executeAndReturnKey(params);
+    }
+
+    /**
+     * Updates some data stored about the user. At this point only the display name will be updated. ID is taken from 'id' parameter,
+     * not user object.
+     * @param id ID of user to update
+     * @param user object containing new info
+     */
+    public void updateUser(Number id, RegistryUser user) throws DataAccessException {
+	String updateString = String.format("UPDATE %1$s SET name = ? WHERE %2$s = ?", TABLE_REGISTRY_USER, COLUMN_ID);
+	getSimpleJdbcTemplate().update(updateString, user.getName(), id);
+    }
+
+    @Override
+    protected ParameterizedRowMapper<RegistryUser> getRowMapper() {
+	return rowMapper;
+    }
+    private final ParameterizedRowMapper<RegistryUser> rowMapper = new ParameterizedRowMapper<RegistryUser>() {
+
+	@Override
+	public RegistryUser mapRow(ResultSet rs, int rowNumber) throws SQLException {
+	    RegistryUser user = new RegistryUser();
+	    user.setId(rs.getInt(COLUMN_ID));
+	    user.setName(rs.getString("name"));
+	    user.setPrincipalName(rs.getString("principal_name"));
+	    return user;
+	}
+    };
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/AbstractDescription.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/AbstractDescription.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/AbstractDescription.java	(revision 1843)
@@ -0,0 +1,181 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.text.ParseException;
+import java.util.Comparator;
+import java.util.Date;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+
+@XmlRootElement(name = "description")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlSeeAlso({ComponentDescription.class, ProfileDescription.class})
+public abstract class AbstractDescription {
+
+    private String id;
+    private String description;
+    private String name;
+    private String registrationDate;
+    private String creatorName;
+    private String userId;
+    private String domainName;
+    @XmlElement(namespace = "http://www.w3.org/1999/xlink")
+    private String href;
+    private String groupName;
+    private int commentsCount;
+
+    public void setId(String id) {
+	this.id = id;
+    }
+
+    public String getId() {
+	return id;
+    }
+
+    public void setDescription(String description) {
+	this.description = description;
+    }
+
+    public String getDescription() {
+	return description;
+    }
+
+    public void setName(String name) {
+	this.name = name;
+    }
+
+    public String getName() {
+	return name;
+    }
+
+    public void setRegistrationDate(String registrationDate) {
+	this.registrationDate = registrationDate;
+    }
+
+    public String getRegistrationDate() {
+	return registrationDate;
+    }
+
+    public void setCreatorName(String creatorName) {
+	this.creatorName = creatorName;
+    }
+
+    public String getCreatorName() {
+	return creatorName;
+    }
+
+    public void setUserId(String userId) {
+	this.userId = userId;
+    }
+
+    /**
+     * MD5 string representation of the user id. Storing the hash because the userId can be the email address which we don't want to make
+     * public.
+     */
+    public String getUserId() {
+	return userId;
+    }
+
+    public void setDomainName(String domainName) {
+	this.domainName = domainName;
+    }
+
+    public String getDomainName() {
+	return domainName;
+    }
+
+    public void setHref(String href) {
+	this.href = href;
+    }
+
+    public String getHref() {
+	return href;
+    }
+
+    public void setGroupName(String groupName) {
+	this.groupName = groupName;
+    }
+
+    public String getGroupName() {
+	return groupName;
+    }
+
+    /**
+     * @return the number of comments posted on this component
+     */
+    public int getCommentsCount() {
+	return commentsCount;
+    }
+
+    /**
+     * @param commentsCount the number of comments posted on this component
+     */
+    public void setCommentsCount(int commentsCount) {
+	this.commentsCount = commentsCount;
+    }
+
+    @Override
+    public String toString() {
+	return "Name=" + getName() + ", id=" + getId() + ", creatorName=" + getCreatorName() + ", userId=" + getUserId();
+    }
+
+    public boolean isProfile() {
+	return this instanceof ProfileDescription;
+    }
+
+    public String getType() {
+	return isProfile() ? "profile" : "component";
+    }
+
+    public static String createNewDate() {
+	return createNewDate(new Date().getTime());
+    }
+
+    public static String createNewDate(long time) {
+	return DateFormatUtils.formatUTC(time, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
+    }
+
+    /**
+     * Helper method.
+     * @param userId normal string which will be checked to see if it matches the md5 hash of the stored userId
+     */
+    public boolean isThisTheOwner(String userId) {
+	String userHash = DigestUtils.md5Hex(userId);
+	return userHash.equals(getUserId());
+    }
+
+    public static Date getDate(String registrationDate) throws ParseException {
+	return DateUtils.parseDate(registrationDate, new String[]{DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()});
+    }
+
+    public static String createPublicHref(String href) {
+	String result = href;
+	if (href != null) {
+	    int index = href.indexOf("?");
+	    if (index != -1) { //strip off query params the rest should be the public href.
+		result = href.substring(0, index);
+	    }
+	}
+	return result;
+    }
+    public static final Comparator<? super AbstractDescription> COMPARE_ON_NAME = new Comparator<AbstractDescription>() {
+
+	public int compare(AbstractDescription o1, AbstractDescription o2) {
+	    int result = 0;
+	    if (o1.getName() != null && o2.getName() != null) {
+		result = o1.getName().compareToIgnoreCase(o2.getName());
+	    }
+	    if (o1.getId() != null && result == 0) {
+		result = o1.getId().compareTo(o2.getId());
+	    }
+	    return result;
+	}
+    };
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/Comment.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/Comment.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/Comment.java	(revision 1843)
@@ -0,0 +1,116 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.text.ParseException;
+import java.util.Date;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.lang.time.DateUtils;
+
+/**
+ *
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+@XmlRootElement(name = "comment")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class Comment {
+
+    private String comments;
+    private String commentDate;
+    private String componentDescriptionId;
+    private String profileDescriptionId;
+    private String id;
+    private String userName;
+    @XmlTransient // this prevents userId from being serialized to XML and thus exposed (which is useless and undesirable)
+    private String userId;
+
+    public void setComment(String comment) {
+	this.comments = comment;
+    }
+
+    public String getComment() {
+	return comments;
+    }
+
+    public void setCommentDate(String commentDate) {
+	this.commentDate = commentDate;
+    }
+
+    public String getCommentDate() {
+	return commentDate;
+    }
+
+    public void setId(String commentId) {
+	this.id = commentId;
+    }
+
+    public String getId() {
+	return id;
+    }
+
+    public String getComponentDescriptionId() {
+	return componentDescriptionId;
+    }
+
+    public void setComponentDescriptionId(String ComponentDescriptionId) {
+	this.componentDescriptionId = ComponentDescriptionId;
+    }
+
+    public void setProfileDescriptionId(String profileDescriptionId) {
+	this.profileDescriptionId = profileDescriptionId;
+    }
+
+    public String getProfileDescriptionId() {
+	return profileDescriptionId;
+    }
+
+    public void setUserId(String userId) {
+	this.userId = userId;
+    }
+
+    public String getUserId() {
+	return userId;
+    }
+
+    /**
+     * 
+     * @return userName, that is the user's 'real' name, not login name
+     */
+    public String getUserName() {
+	return userName;
+    }
+
+    /**
+     * @param userName the user's 'real' name, not login name
+     */
+    public void setUserName(String userName) {
+	this.userName = userName;
+    }
+
+    public static Date getDate(String registrationDate) throws ParseException {
+	return DateUtils.parseDate(registrationDate, new String[]{DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()});
+    }
+
+    /*
+     * Helper method to set the Date
+     */
+    public static String createNewDate() {
+	return createNewDate(new Date().getTime());
+    }
+
+    /*
+     * Helper method to set the Date in the same format
+     * @param time, long that contains the time to be set 
+     */
+    public static String createNewDate(long time) {
+	return DateFormatUtils.formatUTC(time, DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern());
+    }
+
+    public static Comment createANewComment() {
+	Comment com = new Comment();
+	com.setCommentDate(createNewDate());
+	return com;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/CommentResponse.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/CommentResponse.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/CommentResponse.java	(revision 1843)
@@ -0,0 +1,27 @@
+package clarin.cmdi.componentregistry.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ *
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "commentResponse")
+
+public class CommentResponse extends ComponentRegistryResponse {
+
+    @XmlElement
+    private Comment comment;
+
+    public void setComment(Comment comment) {
+        this.comment = comment;
+    }
+
+    public Comment getComment() {
+        return comment;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentDescription.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentDescription.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentDescription.java	(revision 1843)
@@ -0,0 +1,40 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.IdSequence;
+
+@XmlRootElement(name = "componentDescription")
+public class ComponentDescription extends AbstractDescription implements Serializable{
+
+    private static final long serialVersionUID = 1L;
+    
+    public static final Comparator<? super ComponentDescription> COMPARE_ON_GROUP_AND_NAME = new Comparator<ComponentDescription>() {
+        public int compare(ComponentDescription o1, ComponentDescription o2) {
+            int result = 0;
+            if (o1.getGroupName() != null && o2.getGroupName() != null)
+                result = o1.getGroupName().compareToIgnoreCase(o2.getGroupName());
+            if (result == 0) {
+                if (o1.getName() != null && o2.getName() != null) {
+                    result = o1.getName().compareToIgnoreCase(o2.getName());
+                } else {
+                    result = o1.getId().compareTo(o2.getId());
+                }
+            }
+            return result;
+        }
+    };
+
+    public static ComponentDescription createNewDescription() {
+        String id = ComponentRegistry.REGISTRY_ID + "c_" + IdSequence.get();
+        ComponentDescription desc = new ComponentDescription();
+        desc.setId(id);
+        desc.setRegistrationDate(createNewDate());
+        return desc;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentRegistryResponse.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentRegistryResponse.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ComponentRegistryResponse.java	(revision 1843)
@@ -0,0 +1,64 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+
+/**
+ *
+ * @author jeafer
+ */
+@XmlRootElement(name = "response")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlSeeAlso({RegisterResponse.class, CommentResponse.class})
+public class ComponentRegistryResponse {
+
+    @XmlAttribute(required = true)
+    private Boolean registered;
+    
+    @XmlAttribute(required = true)
+    private Boolean isInUserSpace;
+    
+    @XmlElementWrapper(name = "errors", required = false)
+    @XmlElements(
+    @XmlElement(name = "error", type = String.class))
+    private List<String> errors = new ArrayList<String>();
+
+    public ComponentRegistryResponse() {
+    }
+
+    public void addError(String error) {
+        getErrors().add(error);
+    }
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    public boolean isRegistered() {
+        return registered;
+    }
+
+    public void setErrors(List<String> errors) {
+        this.errors = errors;
+    }
+
+    public void setRegistered(boolean registered) {
+        this.registered = registered;
+    }
+
+    public void setIsInUserSpace(Boolean isInUserSpace) {
+        this.isInUserSpace = isInUserSpace;
+    }
+
+    public Boolean isInUserSpace() {
+        return isInUserSpace;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ObjectFactory.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ObjectFactory.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ObjectFactory.java	(revision 1843)
@@ -0,0 +1,22 @@
+/**
+ * 
+ */
+package clarin.cmdi.componentregistry.model;
+
+import javax.xml.bind.annotation.XmlRegistry;
+
+@XmlRegistry
+public class ObjectFactory {
+
+    public ProfileDescription createProfileDescription() {
+        return new ProfileDescription();
+    }
+
+    public ComponentDescription createComponentDescription() {
+        return new ComponentDescription();
+    }
+
+    public RegisterResponse createRegisterErrorResponse() {
+        return new RegisterResponse();
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ProfileDescription.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ProfileDescription.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/ProfileDescription.java	(revision 1843)
@@ -0,0 +1,41 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.io.Serializable;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.IdSequence;
+
+@XmlRootElement(name = "profileDescription")
+public class ProfileDescription extends AbstractDescription implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    private boolean showInEditor = true;
+
+    public static ProfileDescription createNewDescription() {
+	String id = ComponentRegistry.REGISTRY_ID + "p_" + IdSequence.get();
+	ProfileDescription desc = new ProfileDescription();
+	desc.setId(id);
+	desc.setRegistrationDate(createNewDate());
+	return desc;
+    }
+
+    /**
+     * Whether this profile should be shown in metadata editor (e.g. Arbil)
+     *
+     * @return the value of showInEditor
+     */
+    public boolean isShowInEditor() {
+	return showInEditor;
+    }
+
+    /**
+     * Gets whether this profile should be shown in metadata editor (e.g. Arbil)
+     *
+     * @param showInEditor new value of showInEditor
+     */
+    public void setShowInEditor(boolean showInEditor) {
+	this.showInEditor = showInEditor;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegisterResponse.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegisterResponse.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegisterResponse.java	(revision 1843)
@@ -0,0 +1,36 @@
+package clarin.cmdi.componentregistry.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "registerResponse")
+public class RegisterResponse extends ComponentRegistryResponse {
+
+    @XmlAttribute(required = true)
+    private Boolean isProfile;
+
+    @XmlElement
+    private AbstractDescription description;
+
+    public void setDescription(AbstractDescription description) {
+        this.description = description;
+    }
+
+    public AbstractDescription getDescription() {
+        return description;
+    }
+
+    public boolean isProfile() {
+        return isProfile;
+    }
+
+    public void setIsProfile(boolean isProfile) {
+        this.isProfile = isProfile;
+    }
+    
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegistryUser.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegistryUser.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/model/RegistryUser.java	(revision 1843)
@@ -0,0 +1,41 @@
+package clarin.cmdi.componentregistry.model;
+
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+@XmlAccessorType(value = XmlAccessType.FIELD)
+public class RegistryUser implements Serializable {
+
+    private String name;
+    private String principalName;
+    private Number id;
+
+    public void setName(String name) {
+	this.name = name;
+    }
+
+    public String getName() {
+	return name;
+    }
+
+    public void setPrincipalName(String principalName) {
+	this.principalName = principalName;
+    }
+
+    public String getPrincipalName() {
+	return principalName;
+    }
+
+    public Number getId() {
+	return id;
+    }
+
+    public void setId(Number id) {
+	this.id = id;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/CommentValidator.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/CommentValidator.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/CommentValidator.java	(revision 1843)
@@ -0,0 +1,77 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.bind.JAXBException;
+
+/**
+ * Implementation of Validator
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+class CommentValidator implements Validator {
+
+    static final String PARSE_ERROR = "Error in validation input file. Error is: ";
+    static final String COMMENT_SPECIFICATION_ERROR = "Illegal comment specification: ";
+    static final Collection<String> ILLEGAL_ATTRIBUTE_NAMES = Collections.unmodifiableCollection(Arrays.asList("ref", "CommentId"));
+    private List<String> errorMessages = new ArrayList<String>();
+    private Comment com = null;
+    private final InputStream input;
+    private final AbstractDescription description;
+
+    /*
+     * @param input In order to validate the input is consumed. So use @see getCommentSpec to get the parsed CommentSpec.
+     * @param description use to validate the comment with the appropriate description (profile or a component)
+     */
+    public CommentValidator(InputStream input, AbstractDescription description) {
+	this.input = input;
+	this.description = description;
+    }
+
+    @Override
+    public List<String> getErrorMessages() {
+	return errorMessages;
+    }
+
+    @Override
+    public boolean validate() {
+	try {
+	    com = MDMarshaller.unmarshal(Comment.class, input, null);
+	} catch (JAXBException e) {
+	    errorMessages.add(PARSE_ERROR + e);
+	}
+	if (errorMessages.isEmpty()) {
+	    validateComment(com);
+	}
+	return errorMessages.isEmpty();
+    }
+
+    /*
+     * Method that check wether a comment is valid (good attributes)
+     * @param comment, the comment to be validated
+     */
+    private void validateComment(Comment comment) {
+	if (comment.getComment() == null || comment.getComment().isEmpty()) {
+	    errorMessages.add(COMMENT_SPECIFICATION_ERROR + "comment has to be filled in");
+	}
+	if (description.isProfile()) {
+	    if (comment.getProfileDescriptionId() == null || comment.getProfileDescriptionId().isEmpty()) {
+		errorMessages.add(COMMENT_SPECIFICATION_ERROR + "profileId could not be found");
+	    }
+	} else {
+	    if (comment.getComponentDescriptionId() == null || comment.getComponentDescriptionId().isEmpty()) {
+		errorMessages.add(COMMENT_SPECIFICATION_ERROR + "componentId could not be found");
+	    }
+	}
+    }
+
+    public Comment getCommentSpec() {
+	return com;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentClosure.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentClosure.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentClosure.java	(revision 1843)
@@ -0,0 +1,14 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+
+public class ComponentClosure implements RegistryClosure<ComponentDescription> {
+
+    @Override
+    public ComponentDescription getDescription(ComponentRegistry registry, String id) throws ComponentRegistryException {
+        return registry.getComponentDescription(id);
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestService.java	(revision 1843)
@@ -0,0 +1,883 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.StreamingOutput;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Response.Status;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.UserCredentials;
+import clarin.cmdi.componentregistry.UserUnauthorizedException;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.CommentResponse;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+import com.sun.jersey.multipart.FormDataParam;
+import com.sun.jersey.spi.inject.Inject;
+
+@Path("/registry")
+public class ComponentRegistryRestService {
+
+    @Context
+    private UriInfo uriInfo;
+    @Context
+    private SecurityContext security;
+    @Context
+    private HttpServletRequest request;
+    private final static Logger LOG = LoggerFactory.getLogger(ComponentRegistryRestService.class);
+    public static final String DATA_FORM_FIELD = "data";
+    public static final String NAME_FORM_FIELD = "name";
+    public static final String DESCRIPTION_FORM_FIELD = "description";
+    public static final String GROUP_FORM_FIELD = "group";
+    public static final String DOMAIN_FORM_FIELD = "domainName";
+    public static final String USERSPACE_PARAM = "userspace";
+    public static final String METADATA_EDITOR_PARAM = "mdEditor";
+    @Inject(value = "componentRegistryFactory")
+    private ComponentRegistryFactory componentRegistryFactory;
+
+    private ComponentRegistry getRegistry(boolean userspace) {
+	Principal userPrincipal = security.getUserPrincipal();
+	UserCredentials userCredentials = getUserCredentials(userPrincipal);
+	return getRegistry(userspace, userCredentials);
+    }
+
+    private ComponentRegistry getRegistry(boolean userspace, UserCredentials userCredentials) {
+	return componentRegistryFactory.getComponentRegistry(userspace, userCredentials);
+    }
+
+    /**
+     * 
+     * @return Principal of current request
+     * @throws IllegalArgumentException If no user principal found
+     */
+    private Principal checkAndGetUserPrincipal() throws UserUnauthorizedException {
+	Principal principal = security.getUserPrincipal();
+	if (principal == null) {
+	    throw new UserUnauthorizedException("no user principal found.");
+	}
+	return principal;
+    }
+
+    private UserCredentials getUserCredentials(Principal userPrincipal) {
+	UserCredentials userCredentials = null;
+	if (userPrincipal != null) {
+	    userCredentials = new UserCredentials(userPrincipal);
+	}
+	return userCredentials;
+    }
+
+    @GET
+    @Path("/components")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public List<ComponentDescription> getRegisteredComponents(@QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	long start = System.currentTimeMillis();
+	List<ComponentDescription> components = getRegistry(userspace).getComponentDescriptions();
+	LOG.info("Releasing " + components.size() + " registered components into the world (" + (System.currentTimeMillis() - start)
+		+ " millisecs)");
+	return components;
+    }
+
+    @GET
+    @Path("/profiles")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public List<ProfileDescription> getRegisteredProfiles(@QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace,
+	    @QueryParam(METADATA_EDITOR_PARAM) @DefaultValue("false") boolean metadataEditor) throws ComponentRegistryException {
+	long start = System.currentTimeMillis();
+
+	List<ProfileDescription> profiles;
+	if (metadataEditor) {
+	    profiles = getRegistry(userspace).getProfileDescriptionsForMetadaEditor();
+	} else {
+	    profiles = getRegistry(userspace).getProfileDescriptions();
+	}
+
+	LOG.info("Releasing " + profiles.size() + " registered profiles into the world (" + (System.currentTimeMillis() - start)
+		+ " millisecs)");
+	return profiles;
+    }
+
+    @GET
+    @Path("/components/{componentId}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public CMDComponentSpec getRegisteredComponent(@PathParam("componentId") String componentId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	LOG.info("Component with id: " + componentId + " is requested.");
+	return getRegistry(userspace).getMDComponent(componentId);
+    }
+
+    @GET
+    @Path("/components/{componentId}/{rawType}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
+    public Response getRegisteredComponentRawType(@PathParam("componentId") final String componentId, @PathParam("rawType") String rawType) {
+	LOG.info("Component with id: " + componentId + " and rawType:" + rawType + " is requested.");
+	StreamingOutput result = null;
+	try {
+	    final ComponentRegistry registry = findRegistry(componentId, new ComponentClosure());
+	    if (registry == null) {
+		return Response.status(Status.NOT_FOUND).entity("Id: " + componentId + " is not registered, cannot create data.").build();
+	    }
+	    ComponentDescription desc = registry.getComponentDescription(componentId);
+	    checkAndThrowDescription(desc, componentId);
+	    String fileName = desc.getName() + "." + rawType;
+	    if ("xml".equalsIgnoreCase(rawType)) {
+		result = new StreamingOutput() {
+
+		    @Override
+		    public void write(OutputStream output) throws IOException, WebApplicationException {
+			try {
+			    registry.getMDComponentAsXml(componentId, output);
+			} catch (ComponentRegistryException e) {
+			    LOG.info("Could not retrieve component", e);
+			    throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
+			}
+		    }
+		};
+	    } else if ("xsd".equalsIgnoreCase(rawType)) {
+		result = new StreamingOutput() {
+
+		    @Override
+		    public void write(OutputStream output) throws IOException, WebApplicationException {
+			try {
+			    registry.getMDComponentAsXsd(componentId, output);
+			} catch (ComponentRegistryException e) {
+			    LOG.info("Could not retrieve component", e);
+			    throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
+			}
+
+		    }
+		};
+	    } else {
+		throw new WebApplicationException(Response.serverError().entity(
+			"unsupported rawType: " + rawType + " (only xml or xsd are supported)").build());
+	    }
+	    return createDownloadResponse(result, fileName);
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	}
+    }
+
+    public ComponentRegistry findRegistry(String id, RegistryClosure<? extends AbstractDescription> clos) throws ComponentRegistryException {
+	AbstractDescription desc = null;
+	ComponentRegistry result = getRegistry(false);
+	desc = clos.getDescription(result, id);
+	if (desc == null) {
+	    List<ComponentRegistry> userRegs = componentRegistryFactory.getAllUserRegistries();
+	    for (ComponentRegistry reg : userRegs) {
+		desc = clos.getDescription(reg, id);
+		if (desc != null) {
+		    result = reg;
+		    break;
+		}
+	    }
+	}
+	return result;
+    }
+
+    @GET
+    @Path("/profiles/{profileId}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public CMDComponentSpec getRegisteredProfile(@PathParam("profileId") String profileId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	LOG.info("Profile with id: " + profileId + " is requested.");
+	return getRegistry(userspace).getMDProfile(profileId);
+    }
+
+    @GET
+    @Path("/components/usage/{componentId}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public List<AbstractDescription> getComponentUsage(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("true") boolean userspace) throws ComponentRegistryException {
+	try {
+	    final long start = System.currentTimeMillis();
+	    ComponentRegistry registry = getRegistry(userspace);
+	    List<ComponentDescription> components = registry.getUsageInComponents(componentId);
+	    List<ProfileDescription> profiles = registry.getUsageInProfiles(componentId);
+
+	    LOG.info("Found " + components.size() + " components and " + profiles.size() + " profiles that use component " + componentId
+		    + " (" + (System.currentTimeMillis() - start) + " millisecs)");
+
+	    List<AbstractDescription> usages = new ArrayList<AbstractDescription>(components.size() + profiles.size());
+	    usages.addAll(components);
+	    usages.addAll(profiles);
+
+	    return usages;
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve profile usage", e);
+	    throw e;
+	}
+    }
+
+    @GET
+    @Path("/profiles/{profileId}/comments")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public List<Comment> getCommentsFromProfile(@PathParam("profileId") String profileId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	long start = System.currentTimeMillis();
+	List<Comment> comments = getRegistry(userspace).getCommentsInProfile(profileId);
+	LOG.info("Releasing " + comments.size() + " registered comments in Profile into the world (" + (System.currentTimeMillis() - start)
+		+ " millisecs)");
+	return comments;
+    }
+
+    @GET
+    @Path("/components/{componentId}/comments")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public List<Comment> getCommentsFromComponent(@PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	long start = System.currentTimeMillis();
+	List<Comment> comments = getRegistry(userspace).getCommentsInComponent(componentId);
+	LOG.info("Releasing " + comments.size() + " registered comments in Component into the world (" + (System.currentTimeMillis() - start)
+		+ " millisecs)");
+	return comments;
+    }
+
+    @GET
+    @Path("/profiles/{profileId}/comments/{commentId}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public Comment getSpecifiedCommentFromProfile(@PathParam("profileId") String profileId, @PathParam("commentId") String commentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	LOG.info(" Comments of component with id" + commentId + " are requested.");
+	return getRegistry(userspace).getSpecifiedCommentInProfile(profileId, commentId);
+    }
+
+    @GET
+    @Path("/components/{componentId}/comments/{commentId}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public Comment getSpecifiedCommentFromComponent(@PathParam("componentId") String componentId, @PathParam("commentId") String commentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	LOG.info(" Comments of component with id" + commentId + " are requested.");
+	return getRegistry(userspace).getSpecifiedCommentInComponent(componentId, commentId);
+    }
+
+    /**
+     * 
+     * Purely helper method for my front-end (FLEX) which only does post/get requests. The query param is checked and the "proper" method is
+     * called.
+     * @param profileId
+     * @param method
+     * @return
+     */
+    @POST
+    @Path("/profiles/{profileId}")
+    public Response manipulateRegisteredProfile(@PathParam("profileId") String profileId, @FormParam("method") String method,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	if ("delete".equalsIgnoreCase(method)) {
+	    return deleteRegisteredProfile(profileId, userspace);
+	} else {
+	    return Response.ok().build();
+	}
+    }
+
+    @POST
+    @Path("/profiles/{profileId}/comments/{commentId}")
+    public Response manipulateCommentFromProfile(@PathParam("profileId") String profileId, @PathParam("profileId") String commentId, @FormParam("method") String method,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	if ("delete".equalsIgnoreCase(method)) {
+	    return deleteCommentFromProfile(profileId, commentId, userspace);
+	} else {
+	    return Response.ok().build();
+	}
+    }
+
+    @POST
+    @Path("/components/{componentId}/comments/{commentId}")
+    public Response manipulateCommentFromComponent(@PathParam("componentId") String componentId, @PathParam("profileId") String commentId, @FormParam("method") String method,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	if ("delete".equalsIgnoreCase(method)) {
+	    return deleteCommentFromComponent(componentId, commentId, userspace);
+	} else {
+	    return Response.ok().build();
+	}
+    }
+
+    @POST
+    @Path("/profiles/{profileId}/publish")
+    @Consumes("multipart/form-data")
+    public Response publishRegisteredProfile(@PathParam("profileId") String profileId, @FormDataParam(DATA_FORM_FIELD) InputStream input,
+	    @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
+	    @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    ProfileDescription desc = getRegistry(true).getProfileDescription(profileId);
+	    if (desc != null) {
+		updateDescription(desc, name, description, domainName, group);
+		return register(input, desc, getUserCredentials(principal), true, new PublishAction(principal));
+	    } else {
+		LOG.error("Update of nonexistent id (" + profileId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
+	    }
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @POST
+    @Path("/profiles/{profileId}/update")
+    @Consumes("multipart/form-data")
+    public Response updateRegisteredProfile(@PathParam("profileId") String profileId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, @FormDataParam(DATA_FORM_FIELD) InputStream input,
+	    @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
+	    @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    UserCredentials userCredentials = getUserCredentials(principal);
+	    ProfileDescription desc = getRegistry(userspace).getProfileDescription(profileId);
+	    if (desc != null) {
+		updateDescription(desc, name, description, domainName, group);
+		return register(input, desc, userCredentials, userspace, new UpdateAction(principal));
+	    } else {
+		LOG.error("Update of nonexistent id (" + profileId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
+	    }
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+
+    }
+
+    /**
+     * 
+     * Purely helper method for my front-end (FLEX) which van only do post/get requests. The query param is checked and the "proper" method
+     * is called.
+     * @param componentId
+     * @param method
+     * @return
+     */
+    @POST
+    @Path("/components/{componentId}")
+    public Response manipulateRegisteredComponent(@PathParam("componentId") String componentId, @FormParam("method") String method,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	if ("delete".equalsIgnoreCase(method)) {
+	    return deleteRegisteredComponent(componentId, userspace);
+	} else {
+	    return Response.ok().build();
+	}
+    }
+
+    @POST
+    @Path("/components/{componentId}/publish")
+    @Consumes("multipart/form-data")
+    public Response publishRegisteredComponent(@PathParam("componentId") String componentId,
+	    @FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
+	    @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group,
+	    @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    ComponentDescription desc = getRegistry(true).getComponentDescription(componentId);
+	    if (desc != null) {
+		updateDescription(desc, name, description, domainName, group);
+		return register(input, desc, getUserCredentials(principal), true, new PublishAction(principal));
+	    } else {
+		LOG.error("Update of nonexistent id (" + componentId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot update nonexistent profile").build();
+	    }
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @POST
+    @Path("/components/{componentId}/update")
+    @Consumes("multipart/form-data")
+    public Response updateRegisteredComponent(@PathParam("componentId") String componentId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace, @FormDataParam(DATA_FORM_FIELD) InputStream input,
+	    @FormDataParam(NAME_FORM_FIELD) String name, @FormDataParam(DESCRIPTION_FORM_FIELD) String description,
+	    @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    ComponentDescription desc = getRegistry(userspace).getComponentDescription(componentId);
+	    if (desc != null) {
+		updateDescription(desc, name, description, domainName, group);
+		return register(input, desc, getUserCredentials(principal), userspace, new UpdateAction(principal));
+	    } else {
+		LOG.error("Update of nonexistent id (" + componentId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot update nonexistent component").build();
+	    }
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    private void updateDescription(AbstractDescription desc, String name, String description, String domainName, String group) {
+	desc.setName(name);
+	desc.setDescription(description);
+	desc.setDomainName(domainName);
+	desc.setGroupName(group);
+	desc.setRegistrationDate(AbstractDescription.createNewDate());
+    }
+
+    @DELETE
+    @Path("/components/{componentId}")
+    public Response deleteRegisteredComponent(@PathParam("componentId") String componentId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    ComponentRegistry registry = getRegistry(userspace);
+	    LOG.info("Component with id: " + componentId + " set for deletion.");
+	    registry.deleteMDComponent(componentId, principal, false);
+	} catch (DeleteFailedException e) {
+	    LOG.info("Component with id: " + componentId + " deletion failed.", e);
+	    return Response.status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Component with id: " + componentId + " deletion failed.", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (IOException e) {
+	    LOG.info("Component with id: " + componentId + " deletion failed.", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException e) {
+	    LOG.info("Component with id: " + componentId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
+	}
+	LOG.info("Component with id: " + componentId + " deleted.");
+	return Response.ok().build();
+    }
+
+    @DELETE
+    @Path("/profiles/{profileId}")
+    public Response deleteRegisteredProfile(@PathParam("profileId") String profileId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    LOG.info("Profile with id: " + profileId + " set for deletion.");
+	    getRegistry(userspace).deleteMDProfile(profileId, principal);
+	} catch (DeleteFailedException e) {
+	    LOG.info("Profile with id: " + profileId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (IOException e) {
+	    LOG.info("Profile with id: " + profileId + " deletion failed.", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException e) {
+	    LOG.info("Profile with id: " + profileId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
+	}
+	LOG.info("Profile with id: " + profileId + " deleted.");
+	return Response.ok().build();
+    }
+
+    @DELETE
+    @Path("/profiles/{profileId}/comments/{commentId}")
+    public Response deleteCommentFromProfile(@PathParam("profileId") String profileId, @PathParam("commentId") String commentId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    final Principal principal = checkAndGetUserPrincipal();
+	    final ComponentRegistry registry = getRegistry(userspace);
+	    final Comment comment = registry.getSpecifiedCommentInProfile(profileId, commentId);
+	    if (comment != null && profileId.equals(comment.getProfileDescriptionId())) {
+		LOG.info("Comment with id: " + commentId + " set for deletion.");
+		registry.deleteComment(commentId, principal);
+	    } else {
+		throw new ComponentRegistryException("Comment not found for specified profile");
+	    }
+	} catch (DeleteFailedException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (IOException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed.", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
+	}
+	LOG.info("Comment with id: " + commentId + " deleted.");
+	return Response.ok().build();
+    }
+
+    @DELETE
+    @Path("/components/{componentId}/comments/{commentId}")
+    public Response deleteCommentFromComponent(@PathParam("componentId") String componentId, @PathParam("commentId") String commentId,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    final Principal principal = checkAndGetUserPrincipal();
+	    final ComponentRegistry registry = getRegistry(userspace);
+	    final Comment comment = registry.getSpecifiedCommentInComponent(componentId, commentId);
+	    if (comment != null && componentId.equals(comment.getComponentDescriptionId())) {
+		LOG.info("Comment with id: " + commentId + " set for deletion.");
+		registry.deleteComment(commentId, principal);
+	    } else {
+		throw new ComponentRegistryException("Comment not found for specified component");
+	    }
+	} catch (DeleteFailedException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.FORBIDDEN).entity("" + e.getMessage()).build();
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (IOException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed.", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	} catch (UserUnauthorizedException e) {
+	    LOG.info("Comment with id: " + commentId + " deletion failed: " + e.getMessage());
+	    return Response.serverError().status(Status.UNAUTHORIZED).entity("" + e.getMessage()).build();
+	}
+	LOG.info("Comment with id: " + commentId + " deleted.");
+	return Response.ok().build();
+    }
+
+    @GET
+    @Path("/profiles/{profileId}/{rawType}")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML})
+    public Response getRegisteredProfileRawType(@PathParam("profileId") final String profileId, @PathParam("rawType") String rawType) {
+	LOG.info("Profile with id: " + profileId + " and rawType:" + rawType + " is requested.");
+	StreamingOutput result = null;
+	try {
+	    final ComponentRegistry registry = findRegistry(profileId, new ProfileClosure());
+	    if (registry == null) {
+		return Response.status(Status.NOT_FOUND).entity("Id: " + profileId + " is not registered, cannot create data.").build();
+	    }
+	    ProfileDescription desc = registry.getProfileDescription(profileId);
+	    checkAndThrowDescription(desc, profileId);
+	    String fileName = desc.getName() + "." + rawType;
+
+	    if ("xml".equalsIgnoreCase(rawType)) {
+		result = new StreamingOutput() {
+
+		    @Override
+		    public void write(OutputStream output) throws IOException, WebApplicationException {
+			try {
+			    registry.getMDProfileAsXml(profileId, output);
+			} catch (ComponentRegistryException e) {
+			    LOG.warn("Could not retrieve component", e);
+			    throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
+			}
+		    }
+		};
+	    } else if ("xsd".equalsIgnoreCase(rawType)) {
+		result = new StreamingOutput() {
+
+		    @Override
+		    public void write(OutputStream output) throws IOException, WebApplicationException {
+			try {
+			    registry.getMDProfileAsXsd(profileId, output);
+			} catch (ComponentRegistryException e) {
+			    LOG.warn("Could not retrieve component", e);
+			    throw new WebApplicationException(e, Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build());
+			}
+		    }
+		};
+	    } else {
+		throw new WebApplicationException(Response.serverError().entity(
+			"unsupported rawType: " + rawType + " (only xml or xsd are supported)").build());
+	    }
+	    return createDownloadResponse(result, fileName);
+	} catch (ComponentRegistryException e) {
+	    LOG.info("Could not retrieve component", e);
+	    return Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build();
+	}
+    }
+
+    private void checkAndThrowDescription(AbstractDescription desc, String id) {
+	if (desc == null) {
+	    throw new WebApplicationException(Response.serverError().entity("Incorrect id:" + id + "cannot handle request").build());
+	}
+    }
+
+    private Response createDownloadResponse(StreamingOutput result, String fileName) {
+	//Making response so it triggers browsers native save as dialog.
+	Response response = Response.ok().type("application/x-download").header("Content-Disposition",
+		"attachment; filename=\"" + fileName + "\"").entity(result).build();
+	return response;
+
+    }
+
+    @POST
+    @Path("/profiles")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    @Consumes("multipart/form-data")
+    public Response registerProfile(@FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
+	    @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group, @FormDataParam(DOMAIN_FORM_FIELD) String domainName,
+	    @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    UserCredentials userCredentials = getUserCredentials(principal);
+	    ProfileDescription desc = createNewProfileDescription();
+	    desc.setCreatorName(userCredentials.getDisplayName());
+	    desc.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
+	    desc.setName(name);
+	    desc.setDescription(description);
+	    desc.setGroupName(group);
+	    desc.setDomainName(domainName);
+	    LOG.info("Trying to register Profile: " + desc);
+	    return register(input, desc, userCredentials, userspace, new NewAction());
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @POST
+    @Path("/components")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    @Consumes("multipart/form-data")
+    public Response registerComponent(@FormDataParam(DATA_FORM_FIELD) InputStream input, @FormDataParam(NAME_FORM_FIELD) String name,
+	    @FormDataParam(DESCRIPTION_FORM_FIELD) String description, @FormDataParam(GROUP_FORM_FIELD) String group,
+	    @FormDataParam(DOMAIN_FORM_FIELD) String domainName, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    UserCredentials userCredentials = getUserCredentials(principal);
+	    ComponentDescription desc = createNewComponentDescription();
+	    desc.setCreatorName(userCredentials.getDisplayName());
+	    desc.setUserId(userCredentials.getPrincipalName()); // Hash used to be created here, now Id is constructed by impl
+	    desc.setName(name);
+	    desc.setDescription(description);
+	    desc.setGroupName(group);
+	    desc.setDomainName(domainName);
+	    LOG.info("Trying to register Component: " + desc);
+	    return register(input, desc, userCredentials, userspace, new NewAction());
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @POST
+    @Path("/components/{componentId}/comments")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    @Consumes("multipart/form-data")
+    public Response registerCommentInComponent(@FormDataParam(DATA_FORM_FIELD) InputStream input,
+	    @PathParam("componentId") String componentId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    UserCredentials userCredentials = getUserCredentials(principal);
+	    if (null == componentRegistryFactory.getOrCreateUser(userCredentials)) {
+		throw new UserUnauthorizedException("Cannot materialize authenticated user");
+	    }
+	    ComponentRegistry registry = getRegistry(userspace, userCredentials);
+	    ComponentDescription description = registry.getComponentDescription(componentId);
+	    if (description != null) {
+		LOG.info("Trying to register comment to " + componentId);
+		return registerComment(input, registry, userspace, description, principal, userCredentials);
+	    } else {
+		LOG.error("Attempt to post comment on nonexistent component id (" + componentId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot comment on nonexistent component").build();
+	    }
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @POST
+    @Path("/profiles/{profileId}/comments")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    @Consumes("multipart/form-data")
+    public Response registerCommentInProfile(@FormDataParam(DATA_FORM_FIELD) InputStream input,
+	    @PathParam("profileId") String profileId, @QueryParam(USERSPACE_PARAM) @DefaultValue("false") boolean userspace) throws ComponentRegistryException {
+	try {
+	    Principal principal = checkAndGetUserPrincipal();
+	    UserCredentials userCredentials = getUserCredentials(principal);
+	    if (null == componentRegistryFactory.getOrCreateUser(userCredentials)) {
+		throw new UserUnauthorizedException("Cannot materialize authenticated user");
+	    }
+	    ComponentRegistry registry = getRegistry(userspace, userCredentials);
+	    ProfileDescription description = registry.getProfileDescription(profileId);
+	    if (description != null) {
+		LOG.info("Trying to register comment to " + profileId);
+		return registerComment(input, registry, userspace, description, principal, userCredentials);
+	    } else {
+		LOG.error("Attempt to post comment on nonexistent profile id (" + profileId + ") failed.");
+		return Response.serverError().entity("Invalid id, cannot comment on nonexistent profile").build();
+	    }
+	} catch (UserUnauthorizedException ex) {
+	    return Response.status(Status.UNAUTHORIZED).entity(ex.getMessage()).build();
+	}
+    }
+
+    @GET
+    @Path("/pingSession")
+    @Produces({MediaType.TEXT_XML, MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+    public Response pingSession() {
+	boolean stillActive = false;
+	Principal userPrincipal = security.getUserPrincipal();
+	LOG.info("ping by user: " + (userPrincipal == null ? "null" : userPrincipal.getName()));
+	if (request != null) {
+	    if (userPrincipal != null && !ComponentRegistryFactory.ANONYMOUS_USER.equals(userPrincipal.getName())) {
+		stillActive = !((HttpServletRequest) request).getSession().isNew();
+	    }
+	}
+	return Response.ok().entity("<session stillActive=\"" + stillActive + "\"/>").build();
+    }
+
+    private Response register(InputStream input, AbstractDescription desc, UserCredentials userCredentials, boolean userspace,
+	    RegisterAction action) {
+	try {
+	    ComponentRegistry registry = getRegistry(userspace, userCredentials);
+	    DescriptionValidator descriptionValidator = new DescriptionValidator(desc);
+	    MDValidator validator = new MDValidator(input, desc, registry, getRegistry(true), componentRegistryFactory.getPublicRegistry());
+	    RegisterResponse response = new RegisterResponse();
+	    response.setIsInUserSpace(userspace);
+	    validate(response, descriptionValidator, validator);
+	    if (response.getErrors().isEmpty()) {
+		CMDComponentSpec spec = validator.getCMDComponentSpec();
+		try {
+		    // Expand to check for recursion
+		    registry.getExpander().expandNestedComponent(spec.getCMDComponent(), desc.getId());
+
+		    // Add profile
+		    int returnCode = action.execute(desc, spec, response, registry);
+		    if (returnCode == 0) {
+			response.setRegistered(true);
+			response.setDescription(desc);
+		    } else {
+			response.setRegistered(false);
+			response.addError("Unable to register at this moment. Internal server error.");
+		    }
+		} catch (ComponentRegistryException ex) {
+		    // Recursion detected
+		    response.setRegistered(false);
+		    response.addError("Error while expanding specification. " + ex.getMessage());
+		}
+	    } else {
+		LOG.info("Registration failed with validation errors:" + Arrays.toString(response.getErrors().toArray()));
+		response.setRegistered(false);
+	    }
+	    response.setIsProfile(desc.isProfile());
+	    return Response.ok(response).build();
+	} finally {
+	    try {
+		input.close();//either we read the input or there was an exception, we need to close it.
+	    } catch (IOException e) {
+		LOG.error("Error when closing inputstream: ", e);
+	    }
+	}
+    }
+
+    private Response registerComment(InputStream input, ComponentRegistry registry, boolean userspace,
+	    AbstractDescription description, Principal principal, UserCredentials userCredentials) {
+	try {
+	    CommentValidator validator = new CommentValidator(input, description);
+	    CommentResponse response = new CommentResponse();
+	    response.setIsInUserSpace(userspace);
+	    validateComment(response, validator);
+	    if (response.getErrors().isEmpty()) {
+		Comment com = validator.getCommentSpec();
+		//int returnCode = action.executeComment(com, response, registry, principal.getName());
+
+		// If user name is left empty, fill it using the user's display name
+		if (null == com.getUserName() || "".equals(com.getUserName())) {
+		    if (userCredentials != null) {
+			com.setUserName(userCredentials.getDisplayName());
+		    } else {
+			com.setUserName(principal.getName());
+		    }
+		}
+
+		int returnCode = registry.registerComment(com, principal.getName());
+		if (returnCode == 0) {
+		    response.setRegistered(true);
+		    response.setComment(com);
+		} else {
+		    response.setRegistered(false);
+		    response.addError("Unable to register at this moment. Internal server error.");
+		}
+	    } else {
+		LOG.info("Registration failed with validation errors:" + Arrays.toString(response.getErrors().toArray()));
+		response.setRegistered(false);
+	    }
+	    return Response.ok(response).build();
+	} catch (ComponentRegistryException ex) {
+	    LOG.error("Error while inserting comment: ", ex);
+	    return Response.serverError().entity(ex.getMessage()).build();
+	} finally {
+	    try {
+		input.close();//either we read the input or there was an exception, we need to close it.
+	    } catch (IOException e) {
+		LOG.error("Error when closing inputstream: ", e);
+		return Response.serverError().build();
+	    }
+	}
+    }
+
+    private ComponentDescription createNewComponentDescription() {
+	ComponentDescription desc = ComponentDescription.createNewDescription();
+	desc.setHref(createXlink(desc.getId()));
+	return desc;
+    }
+
+    private ProfileDescription createNewProfileDescription() {
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	desc.setHref(createXlink(desc.getId()));
+	return desc;
+    }
+
+    private Comment createNewComment() {
+	Comment com = Comment.createANewComment();
+	return com;
+    }
+
+    private String createXlink(String id) {
+	URI uri = uriInfo.getRequestUriBuilder().path(id).build();
+	return uri.toString();
+    }
+
+    private void validate(RegisterResponse response, Validator... validators) {
+	for (Validator validator : validators) {
+	    if (!validator.validate()) {
+		for (String error : validator.getErrorMessages()) {
+		    response.addError(error);
+		}
+	    }
+	}
+    }
+
+    private void validateComment(CommentResponse response, Validator... validators) {
+	for (Validator validator : validators) {
+	    if (!validator.validate()) {
+		for (String error : validator.getErrorMessages()) {
+		    response.addError(error);
+		}
+	    }
+	}
+    }
+
+    /**
+     * @param componentRegistryFactory the componentRegistryFactory to set
+     */
+    public void setComponentRegistryFactory(ComponentRegistryFactory componentRegistryFactory) {
+	this.componentRegistryFactory = componentRegistryFactory;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/DescriptionValidator.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/DescriptionValidator.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/DescriptionValidator.java	(revision 1843)
@@ -0,0 +1,38 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+public class DescriptionValidator implements Validator {
+
+    private final AbstractDescription desc;
+    private List<String> errorMessages = new ArrayList<String>();
+
+    public DescriptionValidator(AbstractDescription desc) {
+        this.desc = desc;
+    }
+    
+    public List<String> getErrorMessages() {
+        return errorMessages;
+    }
+
+    public boolean validate() {
+        if (!isOk(desc.getCreatorName(), desc.getDescription(), desc.getName())) {
+            errorMessages.add("Fields are not filled in correctly");
+        }
+        return errorMessages.isEmpty();
+    }
+    
+    private boolean isOk(String... fields) {
+        boolean isOk = true;
+        for (String field : fields) {
+            isOk &= StringUtils.isNotBlank(field);
+        }
+        return isOk;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/MDValidator.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/MDValidator.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/MDValidator.java	(revision 1843)
@@ -0,0 +1,171 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.Configuration;
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.components.CMDComponentType;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.schema.cmd.Validator.Message;
+import clarin.cmdi.schema.cmd.ValidatorException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.bind.JAXBException;
+import javax.xml.transform.stream.StreamSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MDValidator implements Validator {
+
+    private final static Logger LOG = LoggerFactory.getLogger(MDValidator.class);
+    static final String MISMATCH_ERROR = "Cannot register component as a profile or vica versa.";
+    static final String COMPONENT_NOT_REGISTERED_ERROR = "referenced component is not registered or does not have a correct componentId: ";
+    static final String PARSE_ERROR = "Error in validation input file: ";
+    static final String SCHEMA_ERROR = "Error in reading general component schema: ";
+    static final String IO_ERROR = "Error while reading specification or general component schema: ";
+    static final String COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR = "referenced component cannot be found in the published components: ";
+    static final String COMPONENT_REGISTRY_EXCEPTION_ERROR = "An exception occurred while accessing the component registry: ";
+    static final String ILLEGAL_ATTRIBUTE_NAME_ERROR = "Illegal attribute name: ";
+    static final String UNKNOWN_VALIDATION_ERROR = "Unknown validation error";
+    static final Collection<String> ILLEGAL_ATTRIBUTE_NAMES = Collections.unmodifiableCollection(Arrays.asList("ref", "ComponentId"));
+    private List<String> errorMessages = new ArrayList<String>();
+    private CMDComponentSpec spec = null;
+    private final InputStream input;
+    private final AbstractDescription description;
+    private final ComponentRegistry registry;
+    private final ComponentRegistry userRegistry;
+    private final ComponentRegistry publicRegistry;
+
+    /**
+     * 
+     * @param input In order to validate the input is consumed. So use @see getCMDComponentSpec to get the parsed CMDComponentSpec.
+     * @param desc
+     * @param registry (registry you currently used) 
+     * @param userRegistry can be null, We get user registry as well so we can give nice error messages if needed. Can be the same as @param registry
+     */
+    public MDValidator(InputStream input, AbstractDescription description, ComponentRegistry registry, ComponentRegistry userRegistry, ComponentRegistry publicRegistry) {
+	this.input = input;
+	this.description = description;
+	this.registry = registry;
+	this.userRegistry = userRegistry;
+	this.publicRegistry = publicRegistry;
+    }
+
+    @Override
+    public List<String> getErrorMessages() {
+	return errorMessages;
+    }
+
+    @Override
+    public boolean validate() {
+	try {
+	    clarin.cmdi.schema.cmd.Validator validator = new clarin.cmdi.schema.cmd.Validator(new URL(Configuration.getInstance().getGeneralComponentSchema()));
+	    // We may need to reuse the input stream, so save it to a byte array first
+	    byte[] inputBytes = getBytesFromInputStream();
+	    StreamSource source = new StreamSource(new ByteArrayInputStream(inputBytes));
+	    if (!validator.validateProfile(source)) {
+		final List<Message> validatorMessages = validator.getMessages();
+		if (validatorMessages.size() > 0) {
+		    for (Message message : validatorMessages) {
+			errorMessages.add(PARSE_ERROR + message.getText());
+		    }
+		} else {
+		    errorMessages.add(PARSE_ERROR + UNKNOWN_VALIDATION_ERROR);
+		}
+	    } else {
+		spec = MDMarshaller.unmarshal(CMDComponentSpec.class, new ByteArrayInputStream(inputBytes), null);
+		if (spec.isIsProfile() != description.isProfile()) {
+		    errorMessages.add(MISMATCH_ERROR);
+		}
+	    }
+	} catch (MalformedURLException e) {
+	    errorMessages.add(SCHEMA_ERROR + e);
+	} catch (JAXBException e) {
+	    errorMessages.add(PARSE_ERROR + e);
+	} catch (ValidatorException e) {
+	    errorMessages.add(PARSE_ERROR + e);
+	} catch (IOException e) {
+	    errorMessages.add(IO_ERROR + e);
+	    LOG.error(IO_ERROR, e);
+	}
+	if (errorMessages.isEmpty()) {
+	    try {
+		validateComponents(spec.getCMDComponent());
+	    } catch (ComponentRegistryException e) {
+		errorMessages.add(COMPONENT_REGISTRY_EXCEPTION_ERROR + e);
+	    }
+	}
+	return errorMessages.isEmpty();
+    }
+
+    private byte[] getBytesFromInputStream() throws IOException {
+	int len;
+	byte[] b = new byte[4096];
+	final ByteArrayOutputStream bOS = new ByteArrayOutputStream();
+
+	while ((len = input.read(b)) > 0) {
+	    bOS.write(b, 0, len);
+	}
+
+	return bOS.toByteArray();
+    }
+
+    private void validateComponents(List<CMDComponentType> cmdComponents) throws ComponentRegistryException {
+	for (CMDComponentType cmdComponentType : cmdComponents) {
+	    validateDescribedComponents(cmdComponentType);
+	    validateComponents(cmdComponentType.getCMDComponent());//Recursion
+	}
+    }
+
+    private void validateDescribedComponents(CMDComponentType cmdComponentType) throws ComponentRegistryException {
+	checkPublicComponents(cmdComponentType);
+    }
+
+    private void checkPublicComponents(CMDComponentType cmdComponentType) throws ComponentRegistryException {
+	if (isDefinedInSeparateFile(cmdComponentType)) {
+	    String id = cmdComponentType.getComponentId();
+	    CMDComponentSpec registeredComponent;
+	    if (registry.isPublic()) { // public registry requires only published components
+		registeredComponent = registry.getMDComponent(id);
+		if (registeredComponent == null) {
+		    String error = cmdComponentType.getComponentId();
+		    if (userRegistry != null) {
+			ComponentDescription desc = userRegistry.getComponentDescription(id);
+			if (desc != null) {
+			    error = desc.getName() + " (" + cmdComponentType.getComponentId() + ")";
+			}
+		    }
+		    errorMessages.add(COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR + error);
+		}
+	    } else { //User registry, can link to components from public registry and the user's registry
+		registeredComponent = registry.getMDComponent(id);
+		if (registeredComponent == null) {
+		    registeredComponent = publicRegistry.getMDComponent(id);
+		    if (registeredComponent == null) {
+			errorMessages.add(COMPONENT_NOT_REGISTERED_ERROR + cmdComponentType.getComponentId());
+		    }
+		}
+
+	    }
+	}
+    }
+
+    private boolean isDefinedInSeparateFile(CMDComponentType cmdComponentType) {
+	return cmdComponentType.getName() == null;
+    }
+
+    public CMDComponentSpec getCMDComponentSpec() {
+	return spec;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/NewAction.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/NewAction.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/NewAction.java	(revision 1843)
@@ -0,0 +1,14 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+public class NewAction implements RegisterAction {
+
+    @Override
+    public int execute(AbstractDescription desc, CMDComponentSpec spec, RegisterResponse response, ComponentRegistry registry) {
+        return registry.register(desc, spec);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ProfileClosure.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ProfileClosure.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/ProfileClosure.java	(revision 1843)
@@ -0,0 +1,14 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+public class ProfileClosure implements RegistryClosure<ProfileDescription> {
+
+    @Override
+    public ProfileDescription getDescription(ComponentRegistry registry, String id) throws ComponentRegistryException {
+        return registry.getProfileDescription(id);
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/PublishAction.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/PublishAction.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/PublishAction.java	(revision 1843)
@@ -0,0 +1,23 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.security.Principal;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+public class PublishAction implements RegisterAction {
+    
+    private final Principal principal;
+
+    public PublishAction(Principal principal) {
+        this.principal = principal;
+    }
+
+    @Override
+    public int execute(AbstractDescription desc, CMDComponentSpec spec, RegisterResponse response, ComponentRegistry registry) {
+        response.setIsInUserSpace(false);
+        return registry.publish(desc, spec, principal);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegisterAction.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegisterAction.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegisterAction.java	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+public interface RegisterAction {
+
+    int execute(AbstractDescription desc, CMDComponentSpec spec, RegisterResponse response, ComponentRegistry registry);
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegistryClosure.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegistryClosure.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/RegistryClosure.java	(revision 1843)
@@ -0,0 +1,12 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+public interface RegistryClosure<T extends AbstractDescription> {
+    
+    T getDescription(ComponentRegistry registry, String id) throws ComponentRegistryException;
+
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/UpdateAction.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/UpdateAction.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/UpdateAction.java	(revision 1843)
@@ -0,0 +1,23 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.security.Principal;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+public class UpdateAction implements RegisterAction {
+    
+    private final Principal principal;
+
+    public UpdateAction(Principal principal) {
+        this.principal = principal;
+    }
+    
+    @Override
+    public int execute(AbstractDescription desc, CMDComponentSpec spec, RegisterResponse response, ComponentRegistry registry) {
+        return registry.update(desc, spec, principal, false);
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/Validator.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/Validator.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/rest/Validator.java	(revision 1843)
@@ -0,0 +1,19 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.util.List;
+
+public interface Validator {
+
+    
+    /**
+     * 
+     * @return the errormessage that might have been created by the validate().
+     */
+    public List<String> getErrorMessages();
+
+    /**
+     * Validate and create an error message when something is wrong.
+     */
+    public boolean validate();
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/CharacterEncodingFilter.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/CharacterEncodingFilter.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/CharacterEncodingFilter.java	(revision 1843)
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package clarin.cmdi.componentregistry.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * <p>
+ * Example filter that sets the character encoding to be used in parsing the incoming request, either unconditionally or only if the client
+ * did not specify a character encoding. Configuration of this filter is based on the following initialization parameters:
+ * </p>
+ * <ul>
+ * <li><strong>encoding</strong> - The character encoding to be configured for this request, either conditionally or unconditionally based
+ * on the <code>ignore</code> initialization parameter. This parameter is required, so there is no default.</li>
+ * <li><strong>ignore</strong> - If set to "true", any character encoding specified by the client is ignored, and the value returned by the
+ * <code>selectEncoding()</code> method is set. If set to "false, <code>selectEncoding()</code> is called <strong>only</strong> if the
+ * client has not already specified an encoding. By default, this parameter is set to "true".</li>
+ * </ul>
+ * 
+ * <p>
+ * Although this filter can be used unchanged, it is also easy to subclass it and make the <code>selectEncoding()</code> method more
+ * intelligent about what encoding to choose, based on characteristics of the incoming request (such as the values of the
+ * <code>Accept-Language</code> and <code>User-Agent</code> headers, or a value stashed in the current user's session.
+ * </p>
+ * 
+ * @author Craig McClanahan
+ * @version $Revision: 466607 $ $Date: 2006-10-21 17:09:50 -0600 (Sat, 21 Oct 2006) $
+ */
+
+public class CharacterEncodingFilter implements Filter {
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * The default character encoding to set for requests that pass through this filter.
+     */
+    protected String encoding = null;
+
+    /**
+     * The filter configuration object we are associated with. If this value is null, this filter instance is not currently configured.
+     */
+    protected FilterConfig filterConfig = null;
+
+    /**
+     * Should a character encoding specified by the client be ignored?
+     */
+    protected boolean ignore = true;
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * Take this filter out of service.
+     */
+    public void destroy() {
+
+        this.encoding = null;
+        this.filterConfig = null;
+
+    }
+
+    /**
+     * Select and set (if specified) the character encoding to be used to interpret request parameters for this request.
+     * 
+     * @param request The servlet request we are processing
+     * @param result The servlet response we are creating
+     * @param chain The filter chain we are processing
+     * 
+     * @exception IOException if an input/output error occurs
+     * @exception ServletException if a servlet error occurs
+     */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+
+        // Conditionally select and set the character encoding to be used
+        if (ignore || (request.getCharacterEncoding() == null)) {
+            String encoding = selectEncoding(request);
+            if (encoding != null)
+                request.setCharacterEncoding(encoding);
+        }
+
+        // Pass control on to the next filter
+        chain.doFilter(request, response);
+
+    }
+
+    /**
+     * Place this filter into service.
+     * 
+     * @param filterConfig The filter configuration object
+     */
+    public void init(FilterConfig filterConfig) throws ServletException {
+
+        this.filterConfig = filterConfig;
+        this.encoding = filterConfig.getInitParameter("encoding");
+        String value = filterConfig.getInitParameter("ignore");
+        if (value == null)
+            this.ignore = true;
+        else if (value.equalsIgnoreCase("true"))
+            this.ignore = true;
+        else if (value.equalsIgnoreCase("yes"))
+            this.ignore = true;
+        else
+            this.ignore = false;
+
+    }
+
+    // ------------------------------------------------------ Protected Methods
+
+    /**
+     * Select an appropriate character encoding to be used, based on the characteristics of the current request and/or filter initialization
+     * parameters. If no character encoding should be set, return <code>null</code>.
+     * <p>
+     * The default implementation unconditionally returns the value configured by the <strong>encoding</strong> initialization parameter for
+     * this filter.
+     * 
+     * @param request The servlet request we are processing
+     */
+    protected String selectEncoding(ServletRequest request) {
+
+        return (this.encoding);
+
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/IsocatServlet.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/IsocatServlet.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/java/clarin/cmdi/componentregistry/servlet/IsocatServlet.java	(revision 1843)
@@ -0,0 +1,57 @@
+package clarin.cmdi.componentregistry.servlet;
+
+import clarin.cmdi.componentregistry.Configuration;
+import java.io.IOException;
+import java.net.URI;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriBuilder;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+
+/**
+ * 
+ * Servlet responsible for providing a bridge to the isocat REST interface. Can be called by the frontend to circumvent crosscripting and
+ * FLASH/Browser limitation in setting the headers of a request.
+ * 
+ */
+public class IsocatServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 1L;
+    private transient WebResource service;
+    private final static String DCIF_XML = "application/dcif+xml";
+
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        URI uri = UriBuilder.fromUri(Configuration.getInstance().getIsocatRestUrl()).build();
+        Client client = Client.create();
+        service = client.resource(uri);
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl();
+        queryParams.add("dcif-mode", "list");
+        String keywords = req.getParameter("keywords");
+        queryParams.add("keywords", keywords);
+        String type = req.getParameter("type"); //simple, complex or no type param to search in everything
+        if (type != null) {
+            queryParams.add("type", type);
+        }
+        queryParams.add("profile", "Metadata"); //always search in metadata profile
+        resp.setContentType(MediaType.TEXT_XML);
+        String result = service.path("/user/guest/search").queryParams(queryParams).accept(DCIF_XML).get(String.class);
+        resp.getWriter().write(result);
+        resp.flushBuffer();
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/CatalogManager.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/CatalogManager.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/CatalogManager.properties	(revision 1843)
@@ -0,0 +1,5 @@
+catalogs=catalog.cat
+relative-catalogs=false
+static-catalog=yes
+catalog-class-name=org.apache.xml.resolver.Resolver
+verbosity=10
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/catalog.cat
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/catalog.cat	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/catalog.cat	(revision 1843)
@@ -0,0 +1,1 @@
+REWRITE_SYSTEM "http://www.w3.org/2005/08/" "."
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/findbugs-exclude.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/findbugs-exclude.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/findbugs-exclude.xml	(revision 1843)
@@ -0,0 +1,9 @@
+
+<FindBugsFilter>
+    <!-- Exclude filter for ComponentRegistry Java classes) -->
+    <Match>
+    <!-- Injection in wicket pages -->
+	<Package name="clarin.cmdi.componentregistry.frontend" />
+	<Bug pattern="SE_BAD_FIELD" />
+    </Match>
+</FindBugsFilter>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/version.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/version.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/version.properties	(revision 1843)
@@ -0,0 +1,2 @@
+ComponentRegistry=${version}
+ComponentBrowserGui=${ComponentBrowserGuiVersion}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/xml.xsd
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/xml.xsd	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/resources/xml.xsd	(revision 1843)
@@ -0,0 +1,146 @@
+<?xml version='1.0'?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   See http://www.w3.org/XML/1998/namespace.html and
+   http://www.w3.org/TR/REC-xml for information about this namespace.
+
+    This schema document describes the XML namespace, in a form
+    suitable for import by other schema documents.  
+
+    Note that local names in this namespace are intended to be defined
+    only by the World Wide Web Consortium or its subgroups.  The
+    following names are currently defined in this namespace and should
+    not be used with conflicting semantics by any Working Group,
+    specification, or document instance:
+
+    base (as an attribute name): denotes an attribute whose value
+         provides a URI to be used as the base for interpreting any
+         relative URIs in the scope of the element on which it
+         appears; its value is inherited.  This name is reserved
+         by virtue of its definition in the XML Base specification.
+
+    id   (as an attribute name): denotes an attribute whose value
+         should be interpreted as if declared to be of type ID.
+         The xml:id specification is not yet a W3C Recommendation,
+         but this attribute is included here to facilitate experimentation
+         with the mechanisms it proposes.  Note that it is _not_ included
+         in the specialAttrs attribute group.
+
+    lang (as an attribute name): denotes an attribute whose value
+         is a language code for the natural language of the content of
+         any element; its value is inherited.  This name is reserved
+         by virtue of its definition in the XML specification.
+  
+    space (as an attribute name): denotes an attribute whose
+         value is a keyword indicating what whitespace processing
+         discipline is intended for the content of the element; its
+         value is inherited.  This name is reserved by virtue of its
+         definition in the XML specification.
+
+    Father (in any context at all): denotes Jon Bosak, the chair of 
+         the original XML Working Group.  This name is reserved by 
+         the following decision of the W3C XML Plenary and 
+         XML Coordination groups:
+
+             In appreciation for his vision, leadership and dedication
+             the W3C XML Plenary on this 10th day of February, 2000
+             reserves for Jon Bosak in perpetuity the XML name
+             xml:Father
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>This schema defines attributes and an attribute group
+        suitable for use by
+        schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
+        attributes on elements they define.
+
+        To enable this, such a schema must import this schema
+        for the XML namespace, e.g. as follows:
+        &lt;schema . . .>
+         . . .
+         &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                    schemaLocation="http://www.w3.org/2005/08/xml.xsd"/>
+
+        Subsequently, qualified reference to any of the attributes
+        or the group defined below will have the desired effect, e.g.
+
+        &lt;type . . .>
+         . . .
+         &lt;attributeGroup ref="xml:specialAttrs"/>
+ 
+         will define a type which will schema-validate an instance
+         element with any of those attributes</xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>In keeping with the XML Schema WG's standard versioning
+   policy, this schema document will persist at
+   http://www.w3.org/2005/08/xml.xsd.
+   At the date of issue it can also be found at
+   http://www.w3.org/2001/xml.xsd.
+   The schema document at that URI may however change in the future,
+   in order to remain compatible with the latest version of XML Schema
+   itself, or with the XML namespace itself.  In other words, if the XML
+   Schema or XML namespaces change, the version of this document at
+   http://www.w3.org/2001/xml.xsd will change
+   accordingly; the version at
+   http://www.w3.org/2005/08/xml.xsd will not change.
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
+         codes as the enumerated possible values is probably never
+         going to be a realistic possibility.  See
+         RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
+         at http://www.iana.org/assignments/lang-tag-apps.htm for
+         further information.
+
+         The union allows for the 'un-declaration' of xml:lang with
+         the empty string.</xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:simpleType>
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+  <xs:annotation>
+   <xs:documentation>See http://www.w3.org/TR/xmlbase/ for
+                     information about this attribute.</xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>See http://www.w3.org/TR/xml-id/ for
+                     information about this attribute.</xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/clearDatabase.sql
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/clearDatabase.sql	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/clearDatabase.sql	(revision 1843)
@@ -0,0 +1,10 @@
+delete from component_description cascade;
+delete from profile_description cascade;
+delete from xml_content cascade;
+delete from comments cascade;
+delete from registry_user cascade;
+alter sequence registry_user_id_seq RESTART WITH 1;
+alter sequence xml_content_id_seq RESTART WITH 1;
+alter sequence profile_description_id_seq RESTART WITH 1;
+alter sequence component_description_id_seq RESTART WITH 1;
+alter sequence comments_id_seq RESTART WITH 1;
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/create.sql
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/create.sql	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/create.sql	(revision 1843)
@@ -0,0 +1,250 @@
+--
+-- PostgreSQL database dump
+--
+
+SET statement_timeout = 0;
+SET client_encoding = 'UTF8';
+SET standard_conforming_strings = off;
+SET check_function_bodies = false;
+SET client_min_messages = warning;
+SET escape_string_warning = off;
+
+SET search_path = public, pg_catalog;
+
+SET default_tablespace = '';
+
+SET default_with_oids = false;
+
+--
+-- Name: comments; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE comments
+(
+  id SERIAL NOT NULL,
+  comments text NOT NULL,
+  comment_date timestamp with time zone,
+  profile_description_id character varying,
+  component_description_id character varying,
+  user_id integer NOT NULL,
+  user_id integer
+
+);
+
+
+--
+-- Name: component_description; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE component_description (
+    id SERIAL NOT NULL,
+    user_id integer,
+    content_id integer NOT NULL,
+    is_public boolean NOT NULL,
+    is_deleted boolean DEFAULT false NOT NULL,
+    component_id character varying NOT NULL,
+    name character varying NOT NULL,
+    description character varying NOT NULL,
+    registration_date timestamp with time zone,
+    creator_name character varying,
+    domain_name character varying,
+    group_name character varying,
+    href character varying,
+    UNIQUE(component_id)
+);
+
+--
+-- Name: xml_content; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE xml_content (
+    id SERIAL NOT NULL,
+    content text NOT NULL
+);
+
+--
+-- Name: profile_description; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE profile_description (
+    id SERIAL NOT NULL,
+    user_id integer,
+    content_id integer NOT NULL,
+    is_public boolean NOT NULL,
+    is_deleted boolean DEFAULT false NOT NULL,
+    profile_id character varying NOT NULL,
+    name character varying NOT NULL,
+    description character varying NOT NULL,
+    registration_date timestamp with time zone,
+    creator_name character varying,
+    domain_name character varying,
+    group_name character varying,
+    href character varying,
+    show_in_editor boolean DEFAULT true NOT NULL,
+    UNIQUE(profile_id)
+);
+
+--
+-- Name: registry_user; Type: TABLE; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE TABLE registry_user (
+    id SERIAL NOT NULL,
+    name character varying,
+    principal_name character varying,
+    UNIQUE(principal_name)
+);
+
+--
+-- Name: comments_id_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
+--
+
+ALTER TABLE ONLY comments 
+    ADD CONSTRAINT comments_id_pkey PRIMARY KEY(id);
+
+--
+-- Name: component_description_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: 
+--
+
+ALTER TABLE ONLY component_description
+    ADD CONSTRAINT component_description_pkey PRIMARY KEY (id);
+
+--
+-- Name: profile_description_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: 
+--
+
+ALTER TABLE ONLY profile_description
+    ADD CONSTRAINT profile_description_pkey PRIMARY KEY (id);
+
+
+--
+-- Name: user_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace: 
+--
+
+ALTER TABLE ONLY registry_user
+    ADD CONSTRAINT user_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY xml_content
+    ADD CONSTRAINT content_pkey PRIMARY KEY (id);
+
+
+
+--
+-- Name: fki_comments_fk_user; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_comments_fk_user ON comments USING btree (user_id);
+
+
+--
+-- Name: fki_comments_profile_id; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_comments_profile_id ON comments USING btree (profile_description_id);
+
+--
+-- Name: fki_comments_component_id; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_comments_component_id ON comments USING btree (component_description_id);
+
+
+--
+-- Name: fki_component_content; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_component_content ON component_description USING btree (content_id);
+
+
+--
+-- Name: fki_component_user; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_component_user ON component_description USING btree (user_id);
+
+
+--
+-- Name: fki_profile_content; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_profile_content ON profile_description USING btree (content_id);
+
+
+--
+-- Name: fki_profile_user; Type: INDEX; Schema: public; Owner: -; Tablespace: 
+--
+
+CREATE INDEX fki_profile_user ON profile_description USING btree (user_id);
+
+
+--
+-- Name: comments_profile_id; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY comments
+    ADD CONSTRAINT comments_profile_id FOREIGN KEY (profile_description_id) REFERENCES profile_description(profile_id);
+
+
+--
+-- Name: comments_user; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY comments
+    ADD CONSTRAINT comments_user FOREIGN KEY (user_id) REFERENCES registry_user(id);
+
+
+--
+-- Name: comments_component_id; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY comments
+    ADD CONSTRAINT comments_component_id FOREIGN KEY (component_description_id) REFERENCES component_description(component_id);
+
+
+--
+-- Name: component_content; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY component_description
+    ADD CONSTRAINT component_content FOREIGN KEY (content_id) REFERENCES xml_content(id);
+
+
+--
+-- Name: component_user; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY component_description
+    ADD CONSTRAINT component_user FOREIGN KEY (user_id) REFERENCES registry_user(id);
+
+
+--
+-- Name: profile_content; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY profile_description
+    ADD CONSTRAINT profile_content FOREIGN KEY (content_id) REFERENCES xml_content(id);
+
+
+--
+-- Name: profile_user; Type: FK CONSTRAINT; Schema: public; Owner: -
+--
+
+ALTER TABLE ONLY profile_description
+    ADD CONSTRAINT profile_user FOREIGN KEY (user_id) REFERENCES registry_user(id);
+
+
+--
+-- Name: public; Type: ACL; Schema: -; Owner: -
+--
+
+-- REVOKE ALL ON SCHEMA public FROM PUBLIC;
+-- REVOKE ALL ON SCHEMA public FROM postgres;
+-- GRANT ALL ON SCHEMA public TO postgres;
+-- GRANT ALL ON SCHEMA public TO PUBLIC;
+
+
+--
+-- PostgreSQL database dump complete
+--
+
+grant all on comments, component_description, profile_description, registry_user, xml_content, comments_id_seq, component_description_id_seq, profile_description_id_seq, registry_user_id_seq, xml_content_id_seq  to compreg;
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.10.sql
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.10.sql	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.10.sql	(revision 1843)
@@ -0,0 +1,8 @@
+---
+--- This scripts adds columns to the database that are required for
+--- the component registry REST service versions 1.10 and up.
+---
+--- Apply only when upgrading from an existing version lower than 1.10
+---
+
+alter table profile_description add column show_in_editor boolean DEFAULT true NOT NULL;
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.11.sql
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.11.sql	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/sql/upgrade-1.11.sql	(revision 1843)
@@ -0,0 +1,27 @@
+---
+--- This scripts adds columns to the database that are required for
+--- the component registry REST service versions 1.10 and up.
+---
+--- Apply only when upgrading from an existing version lower than 1.11
+
+DROP TABLE comments;
+
+CREATE TABLE comments
+(
+  id SERIAL NOT NULL,
+  comments text NOT NULL,
+  comment_date timestamp with time zone NOT NULL,
+  profile_description_id character varying,
+  component_description_id character varying,
+  user_id integer NOT NULL,
+  user_name character varying
+);
+
+
+CREATE INDEX fki_comments_fk_user ON comments USING btree (user_id);
+CREATE INDEX fki_comments_profile_id ON comments USING btree (profile_description_id);
+CREATE INDEX fki_comments_component_id ON comments USING btree (component_description_id);
+ALTER TABLE ONLY comments ADD CONSTRAINT comments_id_pkey PRIMARY KEY(id);
+ALTER TABLE ONLY comments ADD CONSTRAINT comments_user FOREIGN KEY (user_id) REFERENCES registry_user(id);
+ALTER TABLE ONLY comments ADD CONSTRAINT comments_profile_id FOREIGN KEY (profile_description_id) REFERENCES profile_description(profile_id);
+ALTER TABLE ONLY comments ADD CONSTRAINT comments_component_id FOREIGN KEY (component_description_id) REFERENCES component_description(component_id);
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/AC_OETags.js
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/AC_OETags.js	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/AC_OETags.js	(revision 1843)
@@ -0,0 +1,292 @@
+// Flash Player Version Detection - Rev 1.6
+// Detect Client Browser type
+// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
+var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
+var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
+var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
+
+function ControlVersion()
+{
+	var version;
+	var axo;
+	var e;
+
+	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry
+
+	try {
+		// version will be set for 7.X or greater players
+		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+		version = axo.GetVariable("$version");
+	} catch (e) {
+	}
+
+	if (!version)
+	{
+		try {
+			// version will be set for 6.X players only
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+			
+			// installed player is some revision of 6.0
+			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
+			// so we have to be careful. 
+			
+			// default to the first public version
+			version = "WIN 6,0,21,0";
+
+			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
+			axo.AllowScriptAccess = "always";
+
+			// safe to call for 6.0r47 or greater
+			version = axo.GetVariable("$version");
+
+		} catch (e) {
+		}
+	}
+
+	if (!version)
+	{
+		try {
+			// version will be set for 4.X or 5.X player
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
+			version = axo.GetVariable("$version");
+		} catch (e) {
+		}
+	}
+
+	if (!version)
+	{
+		try {
+			// version will be set for 3.X player
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
+			version = "WIN 3,0,18,0";
+		} catch (e) {
+		}
+	}
+
+	if (!version)
+	{
+		try {
+			// version will be set for 2.X player
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+			version = "WIN 2,0,0,11";
+		} catch (e) {
+			version = -1;
+		}
+	}
+	
+	return version;
+}
+
+// JavaScript helper required to detect Flash Player PlugIn version information
+function GetSwfVer(){
+	// NS/Opera version >= 3 check for Flash plugin in plugin array
+	var flashVer = -1;
+	
+	if (navigator.plugins != null && navigator.plugins.length > 0) {
+		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
+			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
+			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
+			var descArray = flashDescription.split(" ");
+			var tempArrayMajor = descArray[2].split(".");			
+			var versionMajor = tempArrayMajor[0];
+			var versionMinor = tempArrayMajor[1];
+			var versionRevision = descArray[3];
+			if (versionRevision == "") {
+				versionRevision = descArray[4];
+			}
+			if (versionRevision[0] == "d") {
+				versionRevision = versionRevision.substring(1);
+			} else if (versionRevision[0] == "r") {
+				versionRevision = versionRevision.substring(1);
+				if (versionRevision.indexOf("d") > 0) {
+					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
+				}
+			} else if (versionRevision[0] == "b") {
+				versionRevision = versionRevision.substring(1);
+			}
+			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
+		}
+	}
+	// MSN/WebTV 2.6 supports Flash 4
+	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
+	// WebTV 2.5 supports Flash 3
+	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
+	// older WebTV supports Flash 2
+	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
+	else if ( isIE && isWin && !isOpera ) {
+		flashVer = ControlVersion();
+	}
+	return flashVer;
+}
+
+// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
+function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
+{
+	versionStr = GetSwfVer();
+	if (versionStr == -1 ) {
+		return false;
+	} else if (versionStr != 0) {
+		if(isIE && isWin && !isOpera) {
+			// Given "WIN 2,0,0,11"
+			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
+			tempString        = tempArray[1];			// "2,0,0,11"
+			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
+		} else {
+			versionArray      = versionStr.split(".");
+		}
+		var versionMajor      = versionArray[0];
+		var versionMinor      = versionArray[1];
+		var versionRevision   = versionArray[2];
+
+        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
+		if (versionMajor > parseFloat(reqMajorVer)) {
+			return true;
+		} else if (versionMajor == parseFloat(reqMajorVer)) {
+			if (versionMinor > parseFloat(reqMinorVer))
+				return true;
+			else if (versionMinor == parseFloat(reqMinorVer)) {
+				if (versionRevision >= parseFloat(reqRevision))
+					return true;
+			}
+		}
+		return false;
+	}
+}
+
+function AC_AddExtension(src, ext)
+{
+  var qIndex = src.indexOf('?');
+  if ( qIndex != -1)
+  {
+    // Add the extention (if needed) before the query params
+    var path = src.substring(0, qIndex);
+    if (path.length >= ext.length && path.lastIndexOf(ext) == (path.length - ext.length))
+      return src;
+    else
+      return src.replace(/\?/, ext+'?'); 
+  }
+  else
+  {
+    // Add the extension (if needed) to the end of the URL
+    if (src.length >= ext.length && src.lastIndexOf(ext) == (src.length - ext.length))
+      return src;  // Already have extension
+    else
+      return src + ext;
+  }
+}
+
+function AC_Generateobj(objAttrs, params, embedAttrs) 
+{ 
+    var str = '';
+    if (isIE && isWin && !isOpera)
+    {
+  		str += '<object ';
+  		for (var i in objAttrs)
+  			str += i + '="' + objAttrs[i] + '" ';
+  		str += '>';
+  		for (var i in params)
+  			str += '<param name="' + i + '" value="' + params[i] + '" /> ';
+  		str += '</object>';
+    } else {
+  		str += '<embed ';
+  		for (var i in embedAttrs)
+  			str += i + '="' + embedAttrs[i] + '" ';
+  		str += '> </embed>';
+    }
+
+    document.write(str);
+}
+
+function AC_FL_RunContent(){
+  var ret = 
+    AC_GetArgs
+    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
+     , "application/x-shockwave-flash"
+    );
+  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
+}
+
+function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
+  var ret = new Object();
+  ret.embedAttrs = new Object();
+  ret.params = new Object();
+  ret.objAttrs = new Object();
+  for (var i=0; i < args.length; i=i+2){
+    var currArg = args[i].toLowerCase();    
+
+    switch (currArg){	
+      case "classid":
+        break;
+      case "pluginspage":
+        ret.embedAttrs[args[i]] = args[i+1];
+        break;
+      case "src":
+      case "movie":	
+        args[i+1] = AC_AddExtension(args[i+1], ext);
+        ret.embedAttrs["src"] = args[i+1];
+        ret.params[srcParamName] = args[i+1];
+        break;
+      case "onafterupdate":
+      case "onbeforeupdate":
+      case "onblur":
+      case "oncellchange":
+      case "onclick":
+      case "ondblClick":
+      case "ondrag":
+      case "ondragend":
+      case "ondragenter":
+      case "ondragleave":
+      case "ondragover":
+      case "ondrop":
+      case "onfinish":
+      case "onfocus":
+      case "onhelp":
+      case "onmousedown":
+      case "onmouseup":
+      case "onmouseover":
+      case "onmousemove":
+      case "onmouseout":
+      case "onkeypress":
+      case "onkeydown":
+      case "onkeyup":
+      case "onload":
+      case "onlosecapture":
+      case "onpropertychange":
+      case "onreadystatechange":
+      case "onrowsdelete":
+      case "onrowenter":
+      case "onrowexit":
+      case "onrowsinserted":
+      case "onstart":
+      case "onscroll":
+      case "onbeforeeditfocus":
+      case "onactivate":
+      case "onbeforedeactivate":
+      case "ondeactivate":
+      case "type":
+      case "codebase":
+        ret.objAttrs[args[i]] = args[i+1];
+        break;
+      case "id":
+      case "width":
+      case "height":
+      case "align":
+      case "vspace": 
+      case "hspace":
+      case "class":
+      case "title":
+      case "accesskey":
+      case "name":
+      case "tabindex":
+        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
+        break;
+      default:
+        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
+    }
+  }
+  ret.objAttrs["classid"] = classid;
+  if (mimeType) ret.embedAttrs["type"] = mimeType;
+  return ret;
+}
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/classes/log4j.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/classes/log4j.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/classes/log4j.properties	(revision 1843)
@@ -0,0 +1,17 @@
+log4j.appender.ROOT.File=${catalina.base}/logs/componentRegistry.log
+log4j.appender.ROOT=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.ROOT.layout=org.apache.log4j.PatternLayout
+log4j.appender.ROOT.layout.ConversionPattern=%d %p [%c#%M:%L] - %m%n
+
+#log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+#log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+#log4j.appender.Stdout.layout.conversionPattern=%d %p [%c{1}#%M:%L] - %m%n
+
+log4j.rootLogger=INFO,ROOT
+
+log4j.logger.org.apache.wicket=ERROR
+log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=ERROR
+log4j.logger.org.apache.wicket.version=ERROR
+log4j.logger.org.apache.wicket.RequestCycle=ERROR
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web-shib.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web-shib.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web-shib.xml	(revision 1843)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- 
+	Configuration file for ComponentRegistry in shibbolized context, which
+	any production environment should be.
+-->
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+    <display-name>ComponentRegistry</display-name>
+    <description>Clarin Metadata Component Registry</description>
+
+
+    <context-param>
+        <param-name>ShhaaConfigLocation</param-name>
+        <param-value>/WEB-INF/shhaa.xml</param-value>
+    </context-param>
+
+    <listener>
+        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>characterEncodingFilter</filter-name>
+        <filter-class>clarin.cmdi.componentregistry.servlet.CharacterEncodingFilter</filter-class>
+        <init-param>
+            <param-name>encoding</param-name>
+            <param-value>UTF-8</param-value>
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>characterEncodingFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+  
+<!-- Make sure this one is declared before the wicket filter, the order matters. Shibboleth should trigger the login, before continuing with the wicket filter.-->
+    <filter>
+        <filter-name>AAIFilter</filter-name>
+        <filter-class>de.mpg.aai.shhaa.AuthFilter</filter-class>
+    </filter>
+    <filter-mapping>
+        <filter-name>AAIFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+  
+    <listener>
+        <listener-class>de.mpg.aai.shhaa.config.ConfigContextListener</listener-class>
+    </listener>
+
+    <filter>
+        <filter-name>wicket.componentregistry</filter-name>
+        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+        <init-param>
+            <param-name>applicationClassName</param-name>
+            <param-value>clarin.cmdi.componentregistry.frontend.AdminApp</param-value>
+        </init-param>
+        <init-param>
+            <param-name>configuration</param-name>
+<!--      <param-value>development</param-value>-->
+            <param-value>deployment</param-value>
+      <!-- you can override with -Dwicket.configuration=development -->
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>wicket.componentregistry</filter-name>
+        <url-pattern>/admin/*</url-pattern>
+    </filter-mapping>
+    <servlet>
+        <servlet-name>ComponentRegistry Web Application</servlet-name>
+        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+            <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.classnames</param-name>
+            <param-value>com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider;clarin.cmdi.componentregistry.rest.ComponentRegistryRestService</param-value>
+        </init-param>
+        <!--    <init-param>-->
+        <!--      <param-name>com.sun.jersey.config.property.packages</param-name>-->
+        <!--      <param-value>clarin.cmdi.componentregistry.rest</param-value>-->
+        <!--    </init-param>-->
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>ComponentRegistry Web Application</servlet-name>
+        <url-pattern>/rest/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet>
+        <servlet-name>Isocat Servlet</servlet-name>
+        <servlet-class>clarin.cmdi.componentregistry.servlet.IsocatServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>Isocat Servlet</servlet-name>
+        <url-pattern>/isocat/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/WEB-INF/web.xml	(revision 1843)
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+        Configuration file for ComponentRegistry in NON-SHIBBOLIZED context,
+	i.e. development or testing environments.
+-->
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+    <display-name>ComponentRegistry</display-name>
+    <description>Clarin Metadata Component Registry</description>
+    <listener>
+        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+    </listener>
+    <filter>
+        <filter-name>characterEncodingFilter</filter-name>
+        <filter-class>clarin.cmdi.componentregistry.servlet.CharacterEncodingFilter</filter-class>
+        <init-param>
+            <param-name>encoding</param-name>
+            <param-value>UTF-8</param-value>
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>characterEncodingFilter</filter-name>
+        <url-pattern>/*</url-pattern>
+    </filter-mapping>
+    <filter>
+        <filter-name>wicket.componentregistry</filter-name>
+        <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
+        <init-param>
+            <param-name>applicationClassName</param-name>
+            <param-value>clarin.cmdi.componentregistry.frontend.AdminApp</param-value>
+        </init-param>
+        <init-param>
+            <param-name>configuration</param-name>
+            <!--      <param-value>development</param-value>-->
+            <param-value>deployment</param-value>
+            <!-- you can override with -Dwicket.configuration=development -->
+        </init-param>
+    </filter>
+    <filter-mapping>
+        <filter-name>wicket.componentregistry</filter-name>
+        <url-pattern>/admin/*</url-pattern>
+    </filter-mapping>
+    <servlet>
+        <servlet-name>ComponentRegistry Web Application</servlet-name>
+        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
+            <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value>
+        </init-param>
+        <init-param>
+            <param-name>com.sun.jersey.config.property.classnames</param-name>
+            <param-value>com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider;clarin.cmdi.componentregistry.rest.ComponentRegistryRestService</param-value>
+        </init-param>
+        <!--    <init-param>-->
+        <!--      <param-name>com.sun.jersey.config.property.packages</param-name>-->
+        <!--      <param-value>clarin.cmdi.componentregistry.rest</param-value>-->
+        <!--    </init-param>-->
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>ComponentRegistry Web Application</servlet-name>
+        <url-pattern>/rest/*</url-pattern>
+    </servlet-mapping>
+    <servlet>
+        <servlet-name>Isocat Servlet</servlet-name>
+        <servlet-class>clarin.cmdi.componentregistry.servlet.IsocatServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>Isocat Servlet</servlet-name>
+        <url-pattern>/isocat/*</url-pattern>
+    </servlet-mapping>
+    <security-constraint>
+        <display-name>ComponentRegistry web service</display-name>
+        <web-resource-collection>
+            <web-resource-name>ComponentRegistry edit</web-resource-name>
+            <description/>
+            <url-pattern>/rest/*</url-pattern>
+            <http-method>DELETE</http-method>
+            <http-method>PUT</http-method>
+            <http-method>POST</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>tomcat</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <security-constraint>
+        <display-name>ComponentRegistry SWF GET</display-name>
+        <web-resource-collection>
+            <web-resource-name>ComponentRegistry access</web-resource-name>
+            <description/>
+            <url-pattern>/*</url-pattern>
+            <http-method>GET</http-method>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>tomcat</role-name>
+        </auth-constraint>
+    </security-constraint>
+    <login-config>
+        <auth-method>BASIC</auth-method>
+    </login-config>
+    <security-role>
+        <description> The role that is required to log in to the Application </description>
+        <role-name>tomcat</role-name>
+    </security-role>
+</web-app>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/css/adminstyle.css
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/css/adminstyle.css	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/css/adminstyle.css	(revision 1843)
@@ -0,0 +1,26 @@
+div.links {
+    width: 100%;
+}
+
+div.container {
+	width: 100%;
+}
+
+div.treeView {
+    float: left;
+    width: 300px;
+}
+
+div.infoView {
+    margin: 20px 0px 0px 300px;
+}
+
+textArea.contentTextArea {
+	   width: 100%;
+	   height: 500px;
+}
+
+textArea.descriptionTextArea {
+       width: 100%;
+       height: 200px;
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.css
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.css	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.css	(revision 1843)
@@ -0,0 +1,6 @@
+/* This CSS stylesheet defines styles used by required elements in a flex application page that supports browser history */
+
+#ie_historyFrame { width: 0px; height: 0px; display:none }
+#firefox_anchorDiv { width: 0px; height: 0px; display:none }
+#safari_formDiv { width: 0px; height: 0px; display:none }
+#safari_rememberDiv { width: 0px; height: 0px; display:none }
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.js
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.js	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/history.js	(revision 1843)
@@ -0,0 +1,662 @@
+BrowserHistoryUtils = {
+    addEvent: function(elm, evType, fn, useCapture) {
+        useCapture = useCapture || false;
+        if (elm.addEventListener) {
+            elm.addEventListener(evType, fn, useCapture);
+            return true;
+        }
+        else if (elm.attachEvent) {
+            var r = elm.attachEvent('on' + evType, fn);
+            return r;
+        }
+        else {
+            elm['on' + evType] = fn;
+        }
+    }
+}
+
+BrowserHistory = (function() {
+    // type of browser
+    var browser = {
+        ie: false, 
+        firefox: false, 
+        safari: false, 
+        opera: false, 
+        version: -1
+    };
+
+    // if setDefaultURL has been called, our first clue
+    // that the SWF is ready and listening
+    //var swfReady = false;
+
+    // the URL we'll send to the SWF once it is ready
+    //var pendingURL = '';
+
+    // Default app state URL to use when no fragment ID present
+    var defaultHash = '';
+
+    // Last-known app state URL
+    var currentHref = document.location.href;
+
+    // Initial URL (used only by IE)
+    var initialHref = document.location.href;
+
+    // Initial URL (used only by IE)
+    var initialHash = document.location.hash;
+
+    // History frame source URL prefix (used only by IE)
+    var historyFrameSourcePrefix = 'history/historyFrame.html?';
+
+    // History maintenance (used only by Safari)
+    var currentHistoryLength = -1;
+
+    var historyHash = [];
+
+    var initialState = createState(initialHref, initialHref + '#' + initialHash, initialHash);
+
+    var backStack = [];
+    var forwardStack = [];
+
+    var currentObjectId = null;
+
+    //UserAgent detection
+    var useragent = navigator.userAgent.toLowerCase();
+
+    if (useragent.indexOf("opera") != -1) {
+        browser.opera = true;
+    } else if (useragent.indexOf("msie") != -1) {
+        browser.ie = true;
+        browser.version = parseFloat(useragent.substring(useragent.indexOf('msie') + 4));
+    } else if (useragent.indexOf("safari") != -1) {
+        browser.safari = true;
+        browser.version = parseFloat(useragent.substring(useragent.indexOf('safari') + 7));
+    } else if (useragent.indexOf("gecko") != -1) {
+        browser.firefox = true;
+    }
+
+    if (browser.ie == true && browser.version == 7) {
+        window["_ie_firstload"] = false;
+    }
+
+    // Accessor functions for obtaining specific elements of the page.
+    function getHistoryFrame()
+    {
+        return document.getElementById('ie_historyFrame');
+    }
+
+    function getAnchorElement()
+    {
+        return document.getElementById('firefox_anchorDiv');
+    }
+
+    function getFormElement()
+    {
+        return document.getElementById('safari_formDiv');
+    }
+
+    function getRememberElement()
+    {
+        return document.getElementById("safari_remember_field");
+    }
+
+    // Get the Flash player object for performing ExternalInterface callbacks.
+    // Updated for changes to SWFObject2.
+    function getPlayer(id) {
+		if (id && document.getElementById(id)) {
+			var r = document.getElementById(id);
+			if (typeof r.SetVariable != "undefined") {
+				return r;
+			}
+			else {
+				var o = r.getElementsByTagName("object");
+				var e = r.getElementsByTagName("embed");
+				if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
+					return o[0];
+				}
+				else if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
+					return e[0];
+				}
+			}
+		}
+		else {
+			var o = document.getElementsByTagName("object");
+			var e = document.getElementsByTagName("embed");
+			if (e.length > 0 && typeof e[0].SetVariable != "undefined") {
+				return e[0];
+			}
+			else if (o.length > 0 && typeof o[0].SetVariable != "undefined") {
+				return o[0];
+			}
+			else if (o.length > 1 && typeof o[1].SetVariable != "undefined") {
+				return o[1];
+			}
+		}
+		return undefined;
+	}
+    
+    function getPlayers() {
+        var players = [];
+        if (players.length == 0) {
+            var tmp = document.getElementsByTagName('object');
+            players = tmp;
+        }
+        
+        if (players.length == 0 || players[0].object == null) {
+            var tmp = document.getElementsByTagName('embed');
+            players = tmp;
+        }
+        return players;
+    }
+
+	function getIframeHash() {
+		var doc = getHistoryFrame().contentWindow.document;
+		var hash = String(doc.location.search);
+		if (hash.length == 1 && hash.charAt(0) == "?") {
+			hash = "";
+		}
+		else if (hash.length >= 2 && hash.charAt(0) == "?") {
+			hash = hash.substring(1);
+		}
+		return hash;
+	}
+
+    /* Get the current location hash excluding the '#' symbol. */
+    function getHash() {
+       // It would be nice if we could use document.location.hash here,
+       // but it's faulty sometimes.
+       var idx = document.location.href.indexOf('#');
+       return (idx >= 0) ? document.location.href.substr(idx+1) : '';
+    }
+
+    /* Get the current location hash excluding the '#' symbol. */
+    function setHash(hash) {
+       // It would be nice if we could use document.location.hash here,
+       // but it's faulty sometimes.
+       if (hash == '') hash = '#'
+       document.location.hash = hash;
+    }
+
+    function createState(baseUrl, newUrl, flexAppUrl) {
+        return { 'baseUrl': baseUrl, 'newUrl': newUrl, 'flexAppUrl': flexAppUrl, 'title': null };
+    }
+
+    /* Add a history entry to the browser.
+     *   baseUrl: the portion of the location prior to the '#'
+     *   newUrl: the entire new URL, including '#' and following fragment
+     *   flexAppUrl: the portion of the location following the '#' only
+     */
+    function addHistoryEntry(baseUrl, newUrl, flexAppUrl) {
+
+        //delete all the history entries
+        forwardStack = [];
+
+        if (browser.ie) {
+            //Check to see if we are being asked to do a navigate for the first
+            //history entry, and if so ignore, because it's coming from the creation
+            //of the history iframe
+            if (flexAppUrl == defaultHash && document.location.href == initialHref && window['_ie_firstload']) {
+                currentHref = initialHref;
+                return;
+            }
+            if ((!flexAppUrl || flexAppUrl == defaultHash) && window['_ie_firstload']) {
+                newUrl = baseUrl + '#' + defaultHash;
+                flexAppUrl = defaultHash;
+            } else {
+                // for IE, tell the history frame to go somewhere without a '#'
+                // in order to get this entry into the browser history.
+                getHistoryFrame().src = historyFrameSourcePrefix + flexAppUrl;
+            }
+            setHash(flexAppUrl);
+        } else {
+
+            //ADR
+            if (backStack.length == 0 && initialState.flexAppUrl == flexAppUrl) {
+                initialState = createState(baseUrl, newUrl, flexAppUrl);
+            } else if(backStack.length > 0 && backStack[backStack.length - 1].flexAppUrl == flexAppUrl) {
+                backStack[backStack.length - 1] = createState(baseUrl, newUrl, flexAppUrl);
+            }
+
+            if (browser.safari) {
+                // for Safari, submit a form whose action points to the desired URL
+                if (browser.version <= 419.3) {
+                    var file = window.location.pathname.toString();
+                    file = file.substring(file.lastIndexOf("/")+1);
+                    getFormElement().innerHTML = '<form name="historyForm" action="'+file+'#' + flexAppUrl + '" method="GET"></form>';
+                    //get the current elements and add them to the form
+                    var qs = window.location.search.substring(1);
+                    var qs_arr = qs.split("&");
+                    for (var i = 0; i < qs_arr.length; i++) {
+                        var tmp = qs_arr[i].split("=");
+                        var elem = document.createElement("input");
+                        elem.type = "hidden";
+                        elem.name = tmp[0];
+                        elem.value = tmp[1];
+                        document.forms.historyForm.appendChild(elem);
+                    }
+                    document.forms.historyForm.submit();
+                } else {
+                    top.location.hash = flexAppUrl;
+                }
+                // We also have to maintain the history by hand for Safari
+                historyHash[history.length] = flexAppUrl;
+                _storeStates();
+            } else {
+                // Otherwise, write an anchor into the page and tell the browser to go there
+                addAnchor(flexAppUrl);
+                setHash(flexAppUrl);
+            }
+        }
+        backStack.push(createState(baseUrl, newUrl, flexAppUrl));
+    }
+
+    function _storeStates() {
+        if (browser.safari) {
+            getRememberElement().value = historyHash.join(",");
+        }
+    }
+
+    function handleBackButton() {
+        //The "current" page is always at the top of the history stack.
+        var current = backStack.pop();
+        if (!current) { return; }
+        var last = backStack[backStack.length - 1];
+        if (!last && backStack.length == 0){
+            last = initialState;
+        }
+        forwardStack.push(current);
+    }
+
+    function handleForwardButton() {
+        //summary: private method. Do not call this directly.
+
+        var last = forwardStack.pop();
+        if (!last) { return; }
+        backStack.push(last);
+    }
+
+    function handleArbitraryUrl() {
+        //delete all the history entries
+        forwardStack = [];
+    }
+
+    /* Called periodically to poll to see if we need to detect navigation that has occurred */
+    function checkForUrlChange() {
+
+        if (browser.ie) {
+            if (currentHref != document.location.href && currentHref + '#' != document.location.href) {
+                //This occurs when the user has navigated to a specific URL
+                //within the app, and didn't use browser back/forward
+                //IE seems to have a bug where it stops updating the URL it
+                //shows the end-user at this point, but programatically it
+                //appears to be correct.  Do a full app reload to get around
+                //this issue.
+                if (browser.version < 7) {
+                    currentHref = document.location.href;
+                    document.location.reload();
+                } else {
+					if (getHash() != getIframeHash()) {
+						// this.iframe.src = this.blankURL + hash;
+						var sourceToSet = historyFrameSourcePrefix + getHash();
+						getHistoryFrame().src = sourceToSet;
+					}
+                }
+            }
+        }
+
+        if (browser.safari) {
+            // For Safari, we have to check to see if history.length changed.
+            if (currentHistoryLength >= 0 && history.length != currentHistoryLength) {
+                //alert("did change: " + history.length + ", " + historyHash.length + "|" + historyHash[history.length] + "|>" + historyHash.join("|"));
+                // If it did change, then we have to look the old state up
+                // in our hand-maintained array since document.location.hash
+                // won't have changed, then call back into BrowserManager.
+                currentHistoryLength = history.length;
+                var flexAppUrl = historyHash[currentHistoryLength];
+                if (flexAppUrl == '') {
+                    //flexAppUrl = defaultHash;
+                }
+                //ADR: to fix multiple
+                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
+                    var pl = getPlayers();
+                    for (var i = 0; i < pl.length; i++) {
+                        pl[i].browserURLChange(flexAppUrl);
+                    }
+                } else {
+                    getPlayer().browserURLChange(flexAppUrl);
+                }
+                _storeStates();
+            }
+        }
+        if (browser.firefox) {
+            if (currentHref != document.location.href) {
+                var bsl = backStack.length;
+
+                var urlActions = {
+                    back: false, 
+                    forward: false, 
+                    set: false
+                }
+
+                if ((window.location.hash == initialHash || window.location.href == initialHref) && (bsl == 1)) {
+                    urlActions.back = true;
+                    // FIXME: could this ever be a forward button?
+                    // we can't clear it because we still need to check for forwards. Ugg.
+                    // clearInterval(this.locationTimer);
+                    handleBackButton();
+                }
+                
+                // first check to see if we could have gone forward. We always halt on
+                // a no-hash item.
+                if (forwardStack.length > 0) {
+                    if (forwardStack[forwardStack.length-1].flexAppUrl == getHash()) {
+                        urlActions.forward = true;
+                        handleForwardButton();
+                    }
+                }
+
+                // ok, that didn't work, try someplace back in the history stack
+                if ((bsl >= 2) && (backStack[bsl - 2])) {
+                    if (backStack[bsl - 2].flexAppUrl == getHash()) {
+                        urlActions.back = true;
+                        handleBackButton();
+                    }
+                }
+                
+                if (!urlActions.back && !urlActions.forward) {
+                    var foundInStacks = {
+                        back: -1, 
+                        forward: -1
+                    }
+
+                    for (var i = 0; i < backStack.length; i++) {
+                        if (backStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
+                            arbitraryUrl = true;
+                            foundInStacks.back = i;
+                        }
+                    }
+                    for (var i = 0; i < forwardStack.length; i++) {
+                        if (forwardStack[i].flexAppUrl == getHash() && i != (bsl - 2)) {
+                            arbitraryUrl = true;
+                            foundInStacks.forward = i;
+                        }
+                    }
+                    handleArbitraryUrl();
+                }
+
+                // Firefox changed; do a callback into BrowserManager to tell it.
+                currentHref = document.location.href;
+                var flexAppUrl = getHash();
+                if (flexAppUrl == '') {
+                    //flexAppUrl = defaultHash;
+                }
+                //ADR: to fix multiple
+                if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
+                    var pl = getPlayers();
+                    for (var i = 0; i < pl.length; i++) {
+                        pl[i].browserURLChange(flexAppUrl);
+                    }
+                } else {
+                    getPlayer().browserURLChange(flexAppUrl);
+                }
+            }
+        }
+        //setTimeout(checkForUrlChange, 50);
+    }
+
+    /* Write an anchor into the page to legitimize it as a URL for Firefox et al. */
+    function addAnchor(flexAppUrl)
+    {
+       if (document.getElementsByName(flexAppUrl).length == 0) {
+           getAnchorElement().innerHTML += "<a name='" + flexAppUrl + "'>" + flexAppUrl + "</a>";
+       }
+    }
+
+    var _initialize = function () {
+        if (browser.ie)
+        {
+            var scripts = document.getElementsByTagName('script');
+            for (var i = 0, s; s = scripts[i]; i++) {
+                if (s.src.indexOf("history.js") > -1) {
+                    var iframe_location = (new String(s.src)).replace("history.js", "historyFrame.html");
+                }
+            }
+            historyFrameSourcePrefix = iframe_location + "?";
+            var src = historyFrameSourcePrefix;
+
+            var iframe = document.createElement("iframe");
+            iframe.id = 'ie_historyFrame';
+            iframe.name = 'ie_historyFrame';
+            //iframe.src = historyFrameSourcePrefix;
+            try {
+                document.body.appendChild(iframe);
+            } catch(e) {
+                setTimeout(function() {
+                    document.body.appendChild(iframe);
+                }, 0);
+            }
+        }
+
+        if (browser.safari)
+        {
+            var rememberDiv = document.createElement("div");
+            rememberDiv.id = 'safari_rememberDiv';
+            document.body.appendChild(rememberDiv);
+            rememberDiv.innerHTML = '<input type="text" id="safari_remember_field" style="width: 500px;">';
+
+            var formDiv = document.createElement("div");
+            formDiv.id = 'safari_formDiv';
+            document.body.appendChild(formDiv);
+
+            var reloader_content = document.createElement('div');
+            reloader_content.id = 'safarireloader';
+            var scripts = document.getElementsByTagName('script');
+            for (var i = 0, s; s = scripts[i]; i++) {
+                if (s.src.indexOf("history.js") > -1) {
+                    html = (new String(s.src)).replace(".js", ".html");
+                }
+            }
+            reloader_content.innerHTML = '<iframe id="safarireloader-iframe" src="about:blank" frameborder="no" scrolling="no"></iframe>';
+            document.body.appendChild(reloader_content);
+            reloader_content.style.position = 'absolute';
+            reloader_content.style.left = reloader_content.style.top = '-9999px';
+            iframe = reloader_content.getElementsByTagName('iframe')[0];
+
+            if (document.getElementById("safari_remember_field").value != "" ) {
+                historyHash = document.getElementById("safari_remember_field").value.split(",");
+            }
+
+        }
+
+        if (browser.firefox)
+        {
+            var anchorDiv = document.createElement("div");
+            anchorDiv.id = 'firefox_anchorDiv';
+            document.body.appendChild(anchorDiv);
+        }
+        
+        //setTimeout(checkForUrlChange, 50);
+    }
+
+    return {
+        historyHash: historyHash, 
+        backStack: function() { return backStack; }, 
+        forwardStack: function() { return forwardStack }, 
+        getPlayer: getPlayer, 
+        initialize: function(src) {
+            _initialize(src);
+        }, 
+        setURL: function(url) {
+            document.location.href = url;
+        }, 
+        getURL: function() {
+            return document.location.href;
+        }, 
+        getTitle: function() {
+            return document.title;
+        }, 
+        setTitle: function(title) {
+            try {
+                backStack[backStack.length - 1].title = title;
+            } catch(e) { }
+            //if on safari, set the title to be the empty string. 
+            if (browser.safari) {
+                if (title == "") {
+                    try {
+                    var tmp = window.location.href.toString();
+                    title = tmp.substring((tmp.lastIndexOf("/")+1), tmp.lastIndexOf("#"));
+                    } catch(e) {
+                        title = "";
+                    }
+                }
+            }
+            document.title = title;
+        }, 
+        setDefaultURL: function(def)
+        {
+            defaultHash = def;
+            def = getHash();
+            //trailing ? is important else an extra frame gets added to the history
+            //when navigating back to the first page.  Alternatively could check
+            //in history frame navigation to compare # and ?.
+            if (browser.ie)
+            {
+                window['_ie_firstload'] = true;
+                var sourceToSet = historyFrameSourcePrefix + def;
+                var func = function() {
+                    getHistoryFrame().src = sourceToSet;
+                    window.location.replace("#" + def);
+                    setInterval(checkForUrlChange, 50);
+                }
+                try {
+                    func();
+                } catch(e) {
+                    window.setTimeout(function() { func(); }, 0);
+                }
+            }
+
+            if (browser.safari)
+            {
+                currentHistoryLength = history.length;
+                if (historyHash.length == 0) {
+                    historyHash[currentHistoryLength] = def;
+                    var newloc = "#" + def;
+                    window.location.replace(newloc);
+                } else {
+                    //alert(historyHash[historyHash.length-1]);
+                }
+                //setHash(def);
+                setInterval(checkForUrlChange, 50);
+            }
+            
+            
+            if (browser.firefox || browser.opera)
+            {
+                var reg = new RegExp("#" + def + "$");
+                if (window.location.toString().match(reg)) {
+                } else {
+                    var newloc ="#" + def;
+                    window.location.replace(newloc);
+                }
+                setInterval(checkForUrlChange, 50);
+                //setHash(def);
+            }
+
+        }, 
+
+        /* Set the current browser URL; called from inside BrowserManager to propagate
+         * the application state out to the container.
+         */
+        setBrowserURL: function(flexAppUrl, objectId) {
+            if (browser.ie && typeof objectId != "undefined") {
+                currentObjectId = objectId;
+            }
+           //fromIframe = fromIframe || false;
+           //fromFlex = fromFlex || false;
+           //alert("setBrowserURL: " + flexAppUrl);
+           //flexAppUrl = (flexAppUrl == "") ? defaultHash : flexAppUrl ;
+
+           var pos = document.location.href.indexOf('#');
+           var baseUrl = pos != -1 ? document.location.href.substr(0, pos) : document.location.href;
+           var newUrl = baseUrl + '#' + flexAppUrl;
+
+           if (document.location.href != newUrl && document.location.href + '#' != newUrl) {
+               currentHref = newUrl;
+               addHistoryEntry(baseUrl, newUrl, flexAppUrl);
+               currentHistoryLength = history.length;
+           }
+
+           return false;
+        }, 
+
+        browserURLChange: function(flexAppUrl) {
+            var objectId = null;
+            if (browser.ie && currentObjectId != null) {
+                objectId = currentObjectId;
+            }
+            pendingURL = '';
+            
+            if (typeof BrowserHistory_multiple != "undefined" && BrowserHistory_multiple == true) {
+                var pl = getPlayers();
+                for (var i = 0; i < pl.length; i++) {
+                    try {
+                        pl[i].browserURLChange(flexAppUrl);
+                    } catch(e) { }
+                }
+            } else {
+                try {
+                    getPlayer(objectId).browserURLChange(flexAppUrl);
+                } catch(e) { }
+            }
+
+            currentObjectId = null;
+        }
+
+    }
+
+})();
+
+// Initialization
+
+// Automated unit testing and other diagnostics
+
+function setURL(url)
+{
+    document.location.href = url;
+}
+
+function backButton()
+{
+    history.back();
+}
+
+function forwardButton()
+{
+    history.forward();
+}
+
+function goForwardOrBackInHistory(step)
+{
+    history.go(step);
+}
+
+//BrowserHistoryUtils.addEvent(window, "load", function() { BrowserHistory.initialize(); });
+(function(i) {
+    var u =navigator.userAgent;var e=/*@cc_on!@*/false; 
+    var st = setTimeout;
+    if(/webkit/i.test(u)){
+        st(function(){
+            var dr=document.readyState;
+            if(dr=="loaded"||dr=="complete"){i()}
+            else{st(arguments.callee,10);}},10);
+    } else if((/mozilla/i.test(u)&&!/(compati)/.test(u)) || (/opera/i.test(u))){
+        document.addEventListener("DOMContentLoaded",i,false);
+    } else if(e){
+    (function(){
+        var t=document.createElement('doc:rdy');
+        try{t.doScroll('left');
+            i();t=null;
+        }catch(e){st(arguments.callee,0);}})();
+    } else{
+        window.onload=i;
+    }
+})( function() {BrowserHistory.initialize();} );
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/historyFrame.html
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/historyFrame.html	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/history/historyFrame.html	(revision 1843)
@@ -0,0 +1,29 @@
+<html>
+    <head>
+        <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 
+        <META HTTP-EQUIV="Expires" CONTENT="-1"> 
+    </head>
+    <body>
+    <script>
+        function processUrl()
+        {
+
+            var pos = url.indexOf("?");
+            url = pos != -1 ? url.substr(pos + 1) : "";
+            if (!parent._ie_firstload) {
+                parent.BrowserHistory.setBrowserURL(url);
+                try {
+                    parent.BrowserHistory.browserURLChange(url);
+                } catch(e) { }
+            } else {
+                parent._ie_firstload = false;
+            }
+        }
+
+        var url = document.location.href;
+        processUrl();
+        document.write(encodeURIComponent(url));
+    </script>
+    Hidden frame for Browser History support.
+    </body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/js/extMouseWheel.js
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/js/extMouseWheel.js	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webapp/js/extMouseWheel.js	(revision 1843)
@@ -0,0 +1,228 @@
+/* 
+*  Mouse wheel support for OS X - implemented in javascript because Adobe
+*  hasn't implemented it in the mac version of Flash Player  >:(
+*  
+*  Copyright (c) 2007-2008 Ali Rantakari ( http://hasseg.org/blog )
+*  
+*  Requires related ActionScript 3 class:
+*  org.hasseg.externalMouseWheel.ExternalMouseWheelSupport
+*  
+*  
+*  Changelog:
+*  ---------------------------------------------------------------------------------
+*  VERSION 1.0 (Ali Rantakari)
+*  July 2007
+*  
+*  - Initial implementation
+*  
+*  
+*  ---------------------------------------------------------------------------------
+*  VERSION 1.5 (Changes by Pavel Fljot, http://inreflected.com)
+*  Jan 2008
+*  
+*  - Added statement to support Safari under Windows
+*  
+*  
+*  ---------------------------------------------------------------------------------
+*  VERSION 2.0 (Changes by Ali Rantakari)
+*  Apr 2008
+*  
+*  - Changed structure of JavaScript so that everything is encapsulated
+*    inside one top-level function
+*  - Added support for modifier keys (ctrl (i.e. command on a Mac,) alt, shift)
+*  - Fixed code for determining coordinates on different (recent) browsers
+*  - Added support for registering multiple Flash objects and their container DIVs
+*  
+*  
+*  ---------------------------------------------------
+*  This code is licensed under the MIT License:
+*  
+*  Permission is hereby granted, free of charge, to any person obtaining a copy
+*  of this software and associated documentation files (the "Software"), to deal
+*  in the Software without restriction, including without limitation the rights
+*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+*  copies of the Software, and to permit persons to whom the Software is
+*  furnished to do so, subject to the following conditions:
+*  
+*  The above copyright notice and this permission notice shall be included in
+*  all copies or substantial portions of the Software.
+*  
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+*  THE SOFTWARE.
+*/
+
+var extMouseWheel = function()
+{
+	// let's not allow other deltas than +/- 3 because that's what flash player does:
+	var keepDeltaAtPlusMinusThree = true;
+	
+	
+	// an associative array, where the keys are the ids of flash
+	// objects that have registered for the mouse wheel support, and
+	// the values their respective container div elements.
+	var f = [];
+	
+	
+	
+	
+	// helper function courtesy of the Adobe peepz
+	var thisMovie = function(movieName)
+	{
+		if (navigator.appName.indexOf("Microsoft") != -1) {
+			return window[movieName];
+		} else {
+			return document[movieName];
+		}
+	}
+	
+	// helper functions for getting the position of
+	// an element
+	// from:  http://blog.firetree.net/2005/07/04/javascript-find-position/
+	var findPosX = function(obj)
+	{
+		var curleft = 0;
+		if(obj.offsetParent)
+			while(1) 
+			{
+			  curleft += obj.offsetLeft;
+			  if(!obj.offsetParent)
+				break;
+			  obj = obj.offsetParent;
+			}
+		else if(obj.x)
+			curleft += obj.x;
+		return curleft;
+	}
+	var findPosY = function(obj)
+	{
+		var curtop = 0;
+		if(obj.offsetParent)
+			while(1)
+			{
+			  curtop += obj.offsetTop;
+			  if(!obj.offsetParent)
+				break;
+			  obj = obj.offsetParent;
+			}
+		else if(obj.y)
+			curtop += obj.y;
+		return curtop;
+	}
+	
+	// helper function for searching the user-agent string
+	var uaContains = function(str)
+	{
+		return (navigator.userAgent.indexOf(str) != -1);
+	}
+	
+	
+	
+	
+	
+	
+	// Handler for mouse wheel event:
+	var onWheelHandler = function(event)
+	{
+		var delta = 0;
+		if (!event) event = window.event;
+		if (event.wheelDelta)
+		{
+			// Safari
+			delta = event.wheelDelta/120;
+			if (window.opera) delta = -delta;
+		}
+		else if (event.detail) // Firefox
+			delta = -event.detail*3;
+		
+		if (keepDeltaAtPlusMinusThree)
+		{
+			if (delta > 0) delta = 3;
+			else if (delta == 0) delta = 0;
+			else delta = -3;
+		}
+		
+		if (delta)
+		{
+			
+			var thisFlashMovieId = null;
+			for (var j in f)
+				if (f[j] != null && f[j] == event.currentTarget) thisFlashMovieId = j;
+			
+			var thisMouse;
+			
+			if (uaContains("Camino"))
+				thisMouse = {x:event.layerX, y:event.layerY};
+			else if (uaContains('Firefox'))
+				thisMouse = {x:(event.layerX - findPosX(event.currentTarget)), y:(event.layerY - findPosY(event.currentTarget))};
+			else
+				thisMouse = {x:event.offsetX, y:event.offsetY};
+			
+			thisMouse.ctrlKey = (uaContains('Mac')) ? (event.metaKey || event.ctrlKey) : event.ctrlKey;
+			thisMouse.altKey = event.altKey;
+			thisMouse.shiftKey = event.shiftKey;
+			thisMouse.buttonDown = false;
+			
+			if (thisMovie(thisFlashMovieId).dispatchExternalMouseWheelEvent)
+				thisMovie(thisFlashMovieId).dispatchExternalMouseWheelEvent(delta, thisMouse.x, thisMouse.y,
+																			thisMouse.ctrlKey, thisMouse.altKey,
+																			thisMouse.shiftKey, thisMouse.buttonDown);
+		};
+		
+		// Prevent default actions caused by mouse wheel
+		if (event.preventDefault) event.preventDefault();
+		event.returnValue = false;
+		
+	}
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	return {
+		// initialize mouse wheel capturing by setting the listener
+		// (this is called from within the Flash app):
+		initCaptureFor: function(aFlashObjectId)
+		{
+			if (uaContains('Mac') || uaContains('Safari'))
+			{
+				// find flash object's div container
+				var parentdiv = document.getElementById(aFlashObjectId).parentNode;
+				while(parentdiv != null && parentdiv.nodeName != "DIV")
+					parentdiv = parentdiv.parentNode;
+				
+				if (parentdiv != undefined && parentdiv != null)
+				{
+					f[aFlashObjectId] = parentdiv;
+					
+					if (parentdiv.addEventListener) parentdiv.addEventListener('DOMMouseScroll', onWheelHandler, false); // Firefox
+					parentdiv.onmousewheel = onWheelHandler; // Safari
+					
+					return true;
+				}
+				else
+					return false;
+			}
+			else
+				return false;
+		}
+	};
+	
+}();
+
+
+
+
+
+
+
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/META-INF/context.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/META-INF/context.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/META-INF/context.xml	(revision 1843)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Component Registry context.xml
+    Twan Goosen <twan.goosen@mpi.nl>, 21/9/2011
+
+    This file contains configuration options for the ComponentRegistry 
+    package which includes both the REST service and the Flex UI.
+    
+    For information about the component registry, see 
+    <http://www.clarin.eu/cmdi> and 
+    <http://trac.clarin.eu/wiki/ComponentRegistry>.
+    
+    == DATABASE CONNECTION ==
+    
+    By default, the application assumes a named (JNDI) datasource 
+    jdbc/ComponentRegistry that provides access to the ComponentRegistry
+    database.
+    
+    For more information, or configuring a custom datasource Spring bean,
+    see WEB-INF/spring-config/datasource-jdbc.xml
+    
+    A database creation script can be found at 
+    <http://svn.clarin.eu/ComponentRegistry/tags/ComponentRegistry-${project.version}/ComponentRegistry/src/main/sql/create.sql>
+    
+    == SPRING CONFIGURATION ==
+    
+    This application uses the Spring framework <http://www.springsource.org/>,
+    version 2.5. Part of its configuration is handled through Spring beans. 
+    These are defined in WEB-INF/applicationContext.xml and the files in 
+    WEB-INF/spring-config.
+        
+    == SHIBBOLETH ==
+    
+    This application uses Shibboleth authentication. Make sure that the URIs
+    for login/logout are set correctly in WEB-INF/shhaa.xml. 
+-->
+<Context antiJARLocking="true" path="">
+    <!-- 
+	Passed to the Flex UI via index.jsp so that it can locate the 
+	ComponentRegistry REST service. Just supply the application root:
+	the '/rest/registry' part will be added by the application.
+    -->
+    <Parameter name="componentRegistryServiceRootUrl" value="${serviceRootUrl}" />
+    <!--
+	Space-separated list of users (getRemoteUser()) that should have access to the admin area of the ComponentRegistry
+    -->
+    <Parameter name="componentRegistryAdminUsers" value="twagoo@mpi.nl twan.goosen@mpi.nl guisil@mpi.nl guilherme.silva@mpi.nl daan.broeder@mpi.nl dietuyt@mpi.nl Menzo.Windhouwer@mpi.nl" />
+</Context>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/applicationContext.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/applicationContext.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/applicationContext.xml	(revision 1843)
@@ -0,0 +1,14 @@
+<?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:context="http://www.springframework.org/schema/context"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                           http://www.springframework.org/schema/context
+                           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+
+    <context:annotation-config />
+
+    <import resource="spring-config/component-registry.xml"/>
+    <import resource="spring-config/database-impl.xml"/>
+    
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/shhaa.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/shhaa.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/shhaa.xml	(revision 1843)
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ROOT>
+    <shhaa>
+
+	<authentication>
+	    <shibheader>
+		<username>eduPersonPrincipalName</username>
+		<session>Shib-Session-ID</session>
+		<idp>Shib-Identity-Provider</idp>
+		<timestamp>Shib-Authentication-Instant</timestamp>
+	    </shibheader>
+	    <fallback>
+		<username>anonymous</username>
+	    </fallback>
+	    <sso action="lI">${shibLI}</sso> 
+	    <slo action="lO">${shibLO}</slo>     
+	</authentication>
+	
+	
+	<composition action="rF">
+	    <shibheader>
+		<attribute>displayName</attribute>
+		<attribute>commonName</attribute>
+	    </shibheader>
+	</composition>
+
+	
+	<authorization>
+	    <location  target="/admin/*" />
+	</authorization>
+	
+	
+	<handler>
+	    <ignore>
+		<location target="/css/*" />
+		<location target="/img/*" />
+	    </ignore>
+		
+		<!-- configures the view-control targets -->
+	    <pages>
+           <!--  <info action="dI">/protected/info.jsp</info> -->
+		<denied action="dD">pages/noaccess.jsp</denied> 
+	    </pages>
+		
+	</handler>
+	
+    </shhaa>
+</ROOT>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/component-registry.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/component-registry.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/component-registry.xml	(revision 1843)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+    <!-- 
+	Property placeholder that allows init parameters defined in servlet context to be used as property values
+	(in this case admin users list)
+    -->
+    <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
+    </bean>
+
+    <bean id="configuration" class="clarin.cmdi.componentregistry.Configuration" factory-method="getInstance">
+	<!-- Read admin users from init param -->
+	<property name="adminUsersList" value="${componentRegistryAdminUsers}" />
+	<property name="generalComponentSchema" value="http://www.clarin.eu/cmd/general-component-schema.xsd" />
+	<property name="component2SchemaXsl" value="http://www.clarin.eu/cmd/xslt/comp2schema-v2/comp2schema.xsl"/>
+	<property name="componentSpecSchemaLocation" value="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" />
+	<property name="isocatRestUrl" value="http://www.isocat.org/rest/" />
+    <!-- Extra attribute keys that are passed in a shibboleth authenticated request principal.
+         You need to configure the shhaa.xml file to enable the extra attributes.
+     -->
+	<property name="displayNameShibbolethKeys">
+	    <list>
+		<value>displayName</value>
+		<value>commonName</value>
+	    </list>
+	</property>
+    </bean>
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/database-impl.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/database-impl.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/database-impl.xml	(revision 1843)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+    <import resource="datasource-jdbc.xml"/>
+    <import resource="persistence.xml"/>
+
+    <bean id="componentsCache" class="clarin.cmdi.componentregistry.impl.database.CMDComponentSpecCache" />
+    <bean id="profilesCache" class="clarin.cmdi.componentregistry.impl.database.CMDComponentSpecCache" />
+
+    <!-- Prototype bean for component registry (service) -->
+    <bean id="componentRegistry" class="clarin.cmdi.componentregistry.impl.database.ComponentRegistryDbImpl" scope="prototype"></bean>
+
+    <!-- Factory that will create component registries for us (and autowire them), to be used by actual ComponentRegistryFactory -->
+    <bean id="componentRegistryBeanFactory"
+            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
+	<property name="serviceLocatorInterface" value="clarin.cmdi.componentregistry.impl.database.ComponentRegistryBeanFactory"/>
+    </bean>
+
+    <!-- Component registry factory that will be used by rest service to get user and public registries -->
+    <bean id="componentRegistryFactory" class="clarin.cmdi.componentregistry.impl.database.ComponentRegistryFactoryDbImpl"></bean>
+  
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/datasource-jdbc.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/datasource-jdbc.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/datasource-jdbc.xml	(revision 1843)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+
+    <!-- Using the Datasource JNDI defined in the servlet container. See below for a sample Tomcat datasource configuration -->
+
+    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
+	<property name="jndiName" value="java:comp/env/jdbc/ComponentRegistry"/>   
+	<property name="resourceRef" value="true" />
+    </bean>
+    
+    <!-- SAMPLE TOMCAT DATASOURCE CONFIGURATION: -->
+    <!--
+	<Context>
+	    ...
+	    <Resource
+		name="jdbc/ComponentRegistry"
+		auth="Container"
+		type="javax.sql.DataSource"
+		driverClassName="org.postgresql.Driver"
+		url="jdbc:postgresql:component_registry"
+		username="compreg"
+		password="compreg"
+		maxActive="10"
+		maxIdle="5"
+		maxWait="4000"
+		removeAbandoned="false"
+		removeAbandonedTimeout="10"
+		logAbandoned="true" />
+	    ...
+	</Context>
+    -->
+    
+    <!-- To define an ad hoc datasource, use something like the following: -->
+    <!--
+        <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
+	    <property name="driverClassName" value="org.postgresql.Driver"/>
+	    <property name="url" value="jdbc:postgresql:component_registry"/>
+	    <property name="username" value="compreg"/>
+	    <property name="password" value="p4ssw0rd"/>
+	</bean>
+    -->
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/persistence.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/persistence.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/WEB-INF/spring-config/persistence.xml	(revision 1843)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+
+    <bean id="txDefinition" class="org.springframework.transaction.support.DefaultTransactionDefinition"></bean>
+
+    <bean id="profileDescriptionDao" class="clarin.cmdi.componentregistry.impl.database.ProfileDescriptionDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    <bean id="componentDescriptionDao" class="clarin.cmdi.componentregistry.impl.database.ComponentDescriptionDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    <bean id="userDao" class="clarin.cmdi.componentregistry.impl.database.UserDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+        <bean id="commentsDao" class="clarin.cmdi.componentregistry.impl.database.CommentsDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/index.jsp
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/index.jsp	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/main/webresources/index.jsp	(revision 1843)
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+	pageEncoding="UTF-8"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html
+	xmlns="http://www.w3.org/1999/xhtml" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+
+<!--  BEGIN Browser History required section -->
+<link rel="stylesheet" type="text/css" href="history/history.css" />
+<!--  END Browser History required section -->
+
+<title>${title}</title>
+<script src="AC_OETags.js" language="javascript"></script>
+
+<!--  BEGIN Browser History required section -->
+<script src="history/history.js" language="javascript"></script>
+<!--  END Browser History required section -->
+
+<style>
+body {
+	margin: 0px;
+	overflow: hidden
+}
+</style>
+<script type="text/javascript" src="./js/extMouseWheel.js"></script>
+<script language="JavaScript" type="text/javascript">
+<!--
+// -----------------------------------------------------------------------------
+// Globals
+// Major version of Flash required
+var requiredMajorVersion = ${version_major};
+// Minor version of Flash required
+var requiredMinorVersion = ${version_minor};
+// Minor version of Flash required
+var requiredRevision = ${version_revision};
+// -----------------------------------------------------------------------------
+// -->
+</script>
+</head>
+
+<body scroll="no">
+<div id="flashContainerDiv"
+	style="position: absolute; width: 100%; height: 100%"><script
+	language="JavaScript" type="text/javascript">
+<!--
+// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
+var hasProductInstall = DetectFlashVer(6, 0, 65);
+
+// Version check based upon the values defined in globals
+var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
+
+if ( hasProductInstall && !hasRequestedVersion ) {
+	// DO NOT MODIFY THE FOLLOWING FOUR LINES
+	// Location visited after installation is complete if installation is required
+	var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
+	var MMredirectURL = window.location;
+    document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+    var MMdoctitle = document.title;
+
+	AC_FL_RunContent(
+		"src", "playerProductInstall",
+		"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
+		"width", "${width}",
+		"height", "${height}",
+		"align", "middle",
+		"id", "${application}",
+		"quality", "high",
+		"bgcolor", "${bgcolor}",
+		"name", "${application}",
+		"allowScriptAccess","sameDomain",
+		"type", "application/x-shockwave-flash",
+		"pluginspage", "http://www.adobe.com/go/getflashplayer"
+	);
+} else if (hasRequestedVersion) {
+	// if we've detected an acceptable version
+	// embed the Flash Content SWF when all tests are passed
+	AC_FL_RunContent(
+			"src", "${ComponentRegistrySwfName}",
+			"width", "${width}",
+			"height", "${height}",
+			"align", "middle",
+			"id", "${application}",
+			"quality", "high",
+			"bgcolor", "${bgcolor}",
+			"name", "${application}",
+			"allowScriptAccess","sameDomain",
+			"type", "application/x-shockwave-flash",
+			"pluginspage", "http://www.adobe.com/go/getflashplayer",
+			"FlashVars", "serviceRootUrl=<%= application.getInitParameter("componentRegistryServiceRootUrl") %>&userName=${pageContext.request.remoteUser}&item=${param.item}&view=${param.view}&space=${param.space}&debug=${flexDebug}"
+			    
+	);
+  } else {  // flash is too old or we can't detect the plugin
+    var alternateContent = 'This content requires the Adobe Flash Player. '
+   	+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
+    document.write(alternateContent);  // insert non-flash content
+  }
+// -->
+</script>
+<noscript><object
+	classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+	id="${application}" width="${width}" height="${height}"
+	codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
+	<param name="movie" value="${ComponentRegistrySwfName}.swf" />
+	<param name="quality" value="high" />
+	<param name="bgcolor" value="${bgcolor}" />
+	<param name="allowScriptAccess" value="sameDomain" />
+	<embed src="${ComponentRegistrySwfName}.swf" quality="high" bgcolor="${bgcolor}"
+		width="${width}" height="${height}" name="${application}"
+		align="middle" play="true" loop="false" quality="high"
+		allowScriptAccess="sameDomain" type="application/x-shockwave-flash"
+		pluginspage="http://www.adobe.com/go/getflashplayer"
+		FlashVars="serviceRootUrl=<%= application.getInitParameter("componentRegistryServiceRootUrl") %>&userName=${pageContext.request.remoteUser}&item=${param.item}&view=${param.view}&space=${param.space}&debug=${flexDebug}">
+	</embed> 
+</object>
+</noscript>
+</div>
+</body>
+</html>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/MDMarshallerTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/MDMarshallerTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/MDMarshallerTest.java	(revision 1843)
@@ -0,0 +1,30 @@
+package clarin.cmdi.componentregistry;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import java.io.ByteArrayInputStream;
+import junit.framework.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class MDMarshallerTest {
+
+    private static Logger logger = LoggerFactory.getLogger(MDMarshallerTest.class);
+    
+    @Test
+    public void testMarshalToString() throws Exception {
+	AbstractDescription desc = ComponentDescription.createNewDescription();
+	desc.setName("Test \u00CA test");
+	String test = MDMarshaller.marshalToString(desc);
+	logger.info(test);
+	Assert.assertTrue(test.contains("Test \u00CA test"));
+	AbstractDescription result = MDMarshaller.unmarshal(ComponentDescription.class, new ByteArrayInputStream(test.getBytes("UTF-8")), null);
+	logger.info(result.getName());
+	Assert.assertEquals(desc.getName(), result.getName());
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/UserCredentialsTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/UserCredentialsTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/UserCredentialsTest.java	(revision 1843)
@@ -0,0 +1,42 @@
+package clarin.cmdi.componentregistry;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.rest.DummyPrincipal;
+import de.mpg.aai.shhaa.model.AuthAttribute;
+import de.mpg.aai.shhaa.model.AuthAttributes;
+import de.mpg.aai.shhaa.model.AuthPrincipal;
+import de.mpg.aai.shhaa.model.BaseAuthAttribute;
+
+public class UserCredentialsTest {
+
+    @Test
+    public void testUserCredentials() throws Exception {
+        UserCredentials creds = new UserCredentials(new DummyPrincipal("noot"));
+        assertEquals("noot", creds.getDisplayName());
+        assertEquals("noot", creds.getPrincipalName());
+        assertEquals(DigestUtils.md5Hex("noot"), creds.getPrincipalNameMD5Hex());
+
+        AuthPrincipal principal = new AuthPrincipal("noot");
+        creds = new UserCredentials(principal);
+        assertEquals("noot", creds.getDisplayName());
+        assertEquals("noot", creds.getPrincipalName());
+        assertEquals(DigestUtils.md5Hex("noot"), creds.getPrincipalNameMD5Hex());
+
+        principal = new AuthPrincipal("noot");
+        Set<AuthAttribute<?>> values = new HashSet<AuthAttribute<?>>();
+        values.add(new BaseAuthAttribute<String>("displayName", "Mr. Noot"));
+        AuthAttributes attributes = new AuthAttributes(values);
+        principal.setAttribues(attributes);
+        creds = new UserCredentials(principal);
+        assertEquals("Mr. Noot", creds.getDisplayName());
+        assertEquals("noot", creds.getPrincipalName());
+        assertEquals(DigestUtils.md5Hex("noot"), creds.getPrincipalNameMD5Hex());
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/frontend/CMDItemInfoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/frontend/CMDItemInfoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/frontend/CMDItemInfoTest.java	(revision 1843)
@@ -0,0 +1,61 @@
+package clarin.cmdi.componentregistry.frontend;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+public class CMDItemInfoTest {
+
+    @Test
+    public void testGetUserDir() throws Exception {
+        CMDItemInfo info = new CMDItemInfo();
+        //info.setDataNode(new FileNode(createFile("users/user1/components/c_123/description.xml"), false));
+        info.setDataNode(new DisplayDataNode("test", false, createDescription(), false));
+        assertTrue(info.isDeletable());
+        assertFalse(info.isUndeletable());
+        assertTrue(info.isEditable());
+        assertFalse(info.getDataNode().isDeleted());
+        assertTrue(info.isInUserWorkSpace());
+        //info.setDataNode(new FileNode(createFile("users/user1/components/deleted/c_123/description.xml"), true));
+        info.setDataNode(new DisplayDataNode("test", true, createDescription(), false));
+        assertFalse(info.isDeletable());
+        assertTrue(info.isUndeletable());
+        assertTrue(info.isEditable());
+        assertTrue(info.getDataNode().isDeleted());
+        assertTrue(info.isInUserWorkSpace());
+        //info.setDataNode(new FileNode(createFile("components/c_123/description.xml"), false));
+        info.setDataNode(new DisplayDataNode("test", false, createDescription(), true));
+        assertTrue(info.isDeletable());
+        assertFalse(info.isUndeletable());
+        assertTrue(info.isEditable());
+        assertFalse(info.isInUserWorkSpace());
+        //info.setDataNode(new FileNode(createFile("components/c_123/"), false));
+        info.setDataNode(new DisplayDataNode("test", false));
+        assertFalse(info.isDeletable());
+        assertFalse(info.isUndeletable());
+        assertFalse(info.isEditable());
+        //info.setDataNode(new FileNode(createFile("components/deleted/c_123/description.xml"), true));
+        info.setDataNode(new DisplayDataNode("test", true, createDescription(), true));
+        assertFalse(info.isDeletable());
+        assertTrue(info.isUndeletable());
+        assertTrue(info.isEditable());
+        assertFalse(info.isInUserWorkSpace());
+        assertTrue(info.getDescription().startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<profileDescription"));
+        //info.setDataNode(new FileNode(createFile("components/deleted/c_123/"), true));
+        info.setDataNode(new DisplayDataNode("test", true));
+        assertFalse(info.isDeletable());
+        assertFalse(info.isUndeletable());
+        assertFalse(info.isEditable());
+        assertEquals("", info.getDescription());
+    }
+
+    private AbstractDescription createDescription() {
+        return ProfileDescription.createNewDescription();
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDaoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDaoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AbstractDescriptionDaoTest.java	(revision 1843)
@@ -0,0 +1,211 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+/**
+ * 
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "/applicationContext.xml" })
+public abstract class AbstractDescriptionDaoTest {
+
+    @Autowired
+    protected JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private UserDao userDao;
+
+    protected abstract AbstractDescriptionDao getDao();
+
+    @Test
+    public void testInjection() {
+	assertNotNull(jdbcTemplate);
+	assertNotNull(getDao());
+    }
+
+    @Test
+    public void testInsertComponent() throws Exception {
+	String regDate = AbstractDescription.createNewDate();
+
+	AbstractDescription description = createNewDescription();
+	description.setName("MyComponent");
+	description.setDescription("MyDescription");
+	description.setCreatorName("Aap");
+	description.setGroupName("MyGroup");
+	description.setDomainName("MyDomain \u00CA");
+	description.setHref("http://MyHref");
+
+	description.setRegistrationDate(regDate);
+
+	String testComponent = getContentString();
+	Number newId = getDao().insertDescription(description, testComponent, true, null);
+	assertNotNull(newId);
+	AbstractDescription descr = getDao().getById(newId);
+	assertNotNull(descr);
+	assertEquals("MyComponent", descr.getName());
+	assertEquals("MyDescription", descr.getDescription());
+	assertEquals("Aap", descr.getCreatorName());
+	assertEquals("MyGroup", descr.getGroupName());
+	assertEquals("MyDomain \u00CA", descr.getDomainName());
+	assertEquals("http://MyHref", descr.getHref());
+	assertEquals(AbstractDescription.getDate(regDate), AbstractDescription.getDate(descr.getRegistrationDate()));
+	assertEquals(testComponent, getDao().getContent(false, description.getId()));
+    }
+
+    @Test
+    public void testGetDescriptionsOrdered() throws Exception {
+	insert("a", true, null);
+	insert("A", true, null);
+	insert("B", true, null);
+	insert("a", true, null);
+	
+	List<AbstractDescription> descs = getDao().getPublicDescriptions(); 
+	assertEquals(4, descs.size());
+	assertEquals("a", descs.get(0).getName()); //ordered by name case insensitive then by cmdId
+	assertEquals("A", descs.get(1).getName());
+	assertEquals("a", descs.get(2).getName());
+	assertTrue(descs.get(1).getId().compareTo(descs.get(2).getId()) < 0);
+	assertEquals("B", descs.get(3).getName());
+	
+    }
+    
+    @Test
+    public void testGetPublicComponents() throws Exception {
+	List<AbstractDescription> descriptions = getDao().getPublicDescriptions();
+	assertNotNull(descriptions);
+    }
+
+    @Test
+    public void testGetUserspaceDescriptions() throws Exception {
+	List<AbstractDescription> descriptions = getDao().getUserspaceDescriptions(-1);
+	assertEquals(0, descriptions.size());
+    }
+
+    @Test
+    public void testDeleteDescription() throws Exception {
+	AbstractDescription description = createNewDescription();
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+	String testComponent = getContentString();
+
+	int count = getDao().getPublicDescriptions().size();
+	// insert
+	getDao().insertDescription(description, testComponent, true, null);
+	assertEquals(count + 1, getDao().getPublicDescriptions().size());
+
+	List deletedDescriptions = getDao().getDeletedDescriptions(null);
+	assertEquals(0, deletedDescriptions.size());
+
+	// delete
+	getDao().setDeleted(description, true);
+	assertEquals(count, getDao().getPublicDescriptions().size());
+
+	deletedDescriptions = getDao().getDeletedDescriptions(null);
+	assertEquals(1, deletedDescriptions.size());
+    }
+
+    @Test
+    public void testUpdateDescription() {
+	AbstractDescription description = createNewDescription();
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+	description.setCreatorName("Aap");
+	description.setGroupName("MyGroup");
+	description.setDomainName("MyDomain");
+	description.setHref("http://MyHref");
+
+	String testComponent = getContentString();
+	Number newId = getDao().insertDescription(description, testComponent, true, null);
+
+	// Change values
+	description.setName("Noot");
+	description.setDescription("AnotherDescription");
+	description.setCreatorName("AnotherAap");
+	description.setGroupName("AnotherGroup");
+	description.setDomainName("AnotherDomain\u00CA");
+	description.setHref("http://AnotherHref");
+	// Update in db
+	getDao().updateDescription(newId, description, null);
+	description = getDao().getById(newId);
+	// Test if new values are there
+	assertNotNull(description);
+	assertEquals("Noot", description.getName());
+	assertEquals("AnotherDescription", description.getDescription());
+	assertEquals("AnotherAap", description.getCreatorName());
+	assertEquals("AnotherGroup", description.getGroupName());
+	assertEquals("AnotherDomain\u00CA", description.getDomainName());
+	assertEquals("http://AnotherHref", description.getHref());
+
+	// Update content
+	String testContent2 = "<test>Test content</test>";
+	getDao().updateDescription(newId, null, testContent2);
+	// Test if new content is there
+	assertEquals(testContent2, getDao().getContent(false, description.getId()));
+
+	// Update both
+	description.setName("Mies");
+	description.setDescription("YetAnotherDescription");
+	String testContent3 = "<test>More test \u00CA content</test>";
+
+	// Update in db
+	getDao().updateDescription(newId, description, testContent3);
+	description = getDao().getById(newId);
+	// Test if new values are there
+	assertNotNull(description);
+	assertEquals("Mies", description.getName());
+	assertEquals("YetAnotherDescription", description.getDescription());
+	// Test if new content is there
+	assertEquals(testContent3, getDao().getContent(false, description.getId()));
+    }
+
+    @Test
+    public void testIsPublic() {
+	Number userId = userDao.insertUser(UserDaoTest.createTestUser());
+	AbstractDescription publicDesc = insert(true, null);
+	assertTrue(getDao().isPublic(publicDesc.getId()));
+	assertFalse(getDao().isInUserSpace(publicDesc.getId(), userId));
+	
+	AbstractDescription privateDesc = insert(false, userId);
+	assertFalse(getDao().isPublic(privateDesc.getId()));
+	assertTrue(getDao().isInUserSpace(privateDesc.getId(), userId));
+	
+	getDao().setDeleted(publicDesc, true);
+	assertTrue(getDao().isPublic(publicDesc.getId()));
+	assertFalse(getDao().isInUserSpace(publicDesc.getId(), userId));
+	
+	getDao().setDeleted(privateDesc, true);
+	assertFalse(getDao().isPublic(privateDesc.getId()));
+	assertTrue(getDao().isInUserSpace(privateDesc.getId(), userId));
+    }
+
+    private AbstractDescription insert(boolean isPublic, Number userId) {
+	return insert("Aap", isPublic, userId);
+    }
+    
+    private AbstractDescription insert(String name, boolean isPublic, Number userId) {
+	AbstractDescription desc = createNewDescription();
+	desc.setName(name);
+	desc.setDescription("MyDescription");
+	getDao().insertDescription(desc, getContentString(), isPublic, userId);
+	return desc;
+    }
+
+    protected abstract String getContentString();
+
+    protected abstract AbstractDescription createNewDescription();
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AdminRegistryTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AdminRegistryTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/AdminRegistryTest.java	(revision 1843)
@@ -0,0 +1,106 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.Principal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.frontend.CMDItemInfo;
+import clarin.cmdi.componentregistry.frontend.DisplayDataNode;
+import clarin.cmdi.componentregistry.frontend.SubmitFailedException;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.rest.DummyPrincipal;
+import clarin.cmdi.componentregistry.rest.RegistryTestHelper;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class AdminRegistryTest  {
+    
+    @Autowired
+    private ComponentDescriptionDao componentDescriptionDao;
+    @Autowired
+    private ProfileDescriptionDao profileDescriptionDao;
+    @Autowired
+    private ComponentRegistryFactory componentRegistryFactory;
+    private static final Principal PRINCIPAL_ADMIN = DummyPrincipal.DUMMY_ADMIN_PRINCIPAL;
+    
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+    }
+
+    @Test
+    public void testForceUpdate() throws Exception {
+        ComponentRegistry testRegistry = componentRegistryFactory.getPublicRegistry();
+        String content1 = "";
+        content1 += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+        content1 += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+        content1 += "    <Header/>\n";
+        content1 += "    <CMD_Component name=\"XXX\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+        content1 += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+        content1 += "    </CMD_Component>\n";
+        content1 += "</CMD_ComponentSpec>\n";
+        ComponentDescription compDesc1 = RegistryTestHelper.addComponent(testRegistry, "XXX1", content1);
+
+        String content2 = "";
+        content2 += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+        content2 += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+        content2 += "    <Header/>\n";
+        content2 += "    <CMD_Component name=\"YYY\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+        content2 += "        <CMD_Component ComponentId=\"" + compDesc1.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+        content2 += "        </CMD_Component>\n";
+        content2 += "    </CMD_Component>\n";
+        content2 += "</CMD_ComponentSpec>\n";
+        ProfileDescription profileDesc = RegistryTestHelper.addProfile(testRegistry, "YYY1", content2);
+
+        AdminRegistry adminReg = new AdminRegistry();
+        adminReg.setComponentRegistryFactory(componentRegistryFactory);
+        adminReg.setComponentDescriptionDao(componentDescriptionDao);
+        adminReg.setProfileDescriptionDao(profileDescriptionDao);
+        CMDItemInfo fileInfo = new CMDItemInfo();
+        fileInfo.setForceUpdate(false);
+        fileInfo.setDataNode(new DisplayDataNode(compDesc1.getName(), false, compDesc1, true));
+        fileInfo.setContent(content1);
+        try {
+            adminReg.submitFile(fileInfo, PRINCIPAL_ADMIN);
+            fail();
+        } catch (SubmitFailedException e) {}
+        fileInfo.setForceUpdate(true);
+        adminReg.submitFile(fileInfo, PRINCIPAL_ADMIN); //Component needs to be forced because they can be used by other profiles/components
+
+        assertEquals(1, testRegistry.getComponentDescriptions().size());
+        try {
+            fileInfo.setForceUpdate(false);
+            adminReg.delete(fileInfo, PRINCIPAL_ADMIN);
+            fail();
+        } catch (SubmitFailedException e) {
+            assertTrue(e.getCause() instanceof DeleteFailedException);
+        }
+        assertEquals(1, testRegistry.getComponentDescriptions().size());
+        fileInfo.setForceUpdate(true);
+        adminReg.delete(fileInfo, PRINCIPAL_ADMIN);
+        assertEquals(0, testRegistry.getComponentDescriptions().size());
+
+        assertEquals(1, testRegistry.getProfileDescriptions().size());
+        fileInfo.setForceUpdate(false);
+        fileInfo.setDataNode(new DisplayDataNode(profileDesc.getName(), false, profileDesc, true));
+        adminReg.delete(fileInfo, PRINCIPAL_ADMIN); //Profile do not need to be forced they cannot be used by other profiles
+        assertEquals(0, testRegistry.getProfileDescriptions().size());
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/CommentsDaoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/CommentsDaoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/CommentsDaoTest.java	(revision 1843)
@@ -0,0 +1,170 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.Comment;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ *
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class CommentsDaoTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    @Autowired
+    private CommentsDao commentsDao;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetDatabase(jdbcTemplate);
+	ComponentRegistryTestDatabase.createTableComments(jdbcTemplate);
+    }
+
+    @Test
+    public void testInjection() {
+	assertNotNull(jdbcTemplate);
+	assertNotNull(commentsDao);
+    }
+
+    @Test
+    public void testInsertProfileComment() {
+	Comment comment = createTestComment();
+	comment.setProfileDescriptionId(TEST_COMMENT_PROFILE_ID);
+
+	assertEquals(0, commentsDao.getAllComments().size());
+	Number newId = commentsDao.insertComment(comment, TEST_COMMENT_USER_ID);
+	assertNotNull(newId);
+
+	List<Comment> comments = commentsDao.getAllComments();
+	assertNotNull(comments);
+	assertEquals(1, comments.size());
+
+	assertEquals(TEST_COMMENT_NAME, comments.get(0).getComment());
+	assertEquals(TEST_COMMENT_PROFILE_ID, comments.get(0).getProfileDescriptionId());
+	assertEquals(TEST_COMMENT_DATE, comments.get(0).getCommentDate());
+	assertEquals(TEST_COMMENT_USER_NAME, comments.get(0).getUserName());
+	assertEquals(Integer.toString(TEST_COMMENT_USER_ID), comments.get(0).getUserId());
+    }
+
+    @Test
+    public void testInsertComponentComment() {
+	Comment comment = createTestComment();
+	comment.setComponentDescriptionId(TEST_COMMENT_COMPONENT_ID);
+
+	assertEquals(0, commentsDao.getAllComments().size());
+	Number newId = commentsDao.insertComment(comment, TEST_COMMENT_USER_ID);
+	assertNotNull(newId);
+
+	List<Comment> comments = commentsDao.getAllComments();
+	assertNotNull(comments);
+	assertEquals(1, comments.size());
+
+	assertEquals(TEST_COMMENT_NAME, comments.get(0).getComment());
+	assertEquals(TEST_COMMENT_COMPONENT_ID, comments.get(0).getComponentDescriptionId());
+	assertEquals(TEST_COMMENT_DATE, comments.get(0).getCommentDate());
+	assertEquals(TEST_COMMENT_USER_NAME, comments.get(0).getUserName());
+	assertEquals(Integer.toString(TEST_COMMENT_USER_ID), comments.get(0).getUserId());
+    }
+
+    @Test
+    public void testGetCommentsFromProfile() {
+	List<Comment> descriptions = commentsDao.getCommentsFromProfile(TEST_COMMENT_PROFILE_ID);
+	assertNotNull(descriptions);
+
+	int size = descriptions.size();
+	Comment comment1 = createTestComment();
+	comment1.setProfileDescriptionId(TEST_COMMENT_PROFILE_ID);
+	commentsDao.insertComment(comment1, TEST_COMMENT_USER_ID);
+
+	descriptions = commentsDao.getCommentsFromProfile(TEST_COMMENT_PROFILE_ID);
+	assertEquals(size + 1, descriptions.size());
+
+	Comment comment2 = createTestComment();
+	comment2.setProfileDescriptionId(TEST_COMMENT_PROFILE_ID);
+	commentsDao.insertComment(comment2, TEST_COMMENT_USER_ID);
+
+	descriptions = commentsDao.getCommentsFromProfile(TEST_COMMENT_PROFILE_ID);
+	assertEquals(size + 2, descriptions.size());
+    }
+
+    @Test
+    public void testGetCommentsFromComponent() {
+	List<Comment> descriptions = commentsDao.getCommentsFromComponent(TEST_COMMENT_COMPONENT_ID);
+	assertNotNull(descriptions);
+
+	int size = descriptions.size();
+	Comment comment1 = createTestComment();
+	comment1.setComponentDescriptionId(TEST_COMMENT_COMPONENT_ID);
+	commentsDao.insertComment(comment1, TEST_COMMENT_USER_ID);
+
+	descriptions = commentsDao.getCommentsFromComponent(TEST_COMMENT_COMPONENT_ID);
+	assertEquals(size + 1, descriptions.size());
+
+	Comment comment2 = createTestComment();
+	comment2.setComponentDescriptionId(TEST_COMMENT_COMPONENT_ID);
+	commentsDao.insertComment(comment2, TEST_COMMENT_USER_ID);
+
+	descriptions = commentsDao.getCommentsFromComponent(TEST_COMMENT_COMPONENT_ID);
+	assertEquals(size + 2, descriptions.size());
+    }
+
+    @Test
+    public void testGetAllComments() {
+	assertEquals(0, commentsDao.getAllComments().size());
+    }
+
+    @Test
+    public void testGetComment() {
+	Comment comment = createTestComment();
+	commentsDao.insertComment(comment, 8);
+
+	assertNotNull(commentsDao.getByComment(TEST_COMMENT_NAME));
+	assertNull(commentsDao.getByComment("NON_EXISTENT_COMMENT_NAME"));
+    }
+
+    @Test
+    public void testSetDelete() {
+	Comment comment = createTestComment();
+	int count = commentsDao.getAllComments().size();
+
+	Number id = commentsDao.insertComment(comment, 8);
+	assertNotNull(id);
+	assertEquals(count + 1, commentsDao.getAllComments().size());
+	assertNotNull(commentsDao.getByComment(comment.getComment()));
+
+	comment.setId(id.toString());
+	commentsDao.deleteComment(comment);
+	assertEquals(count, commentsDao.getAllComments().size());
+
+	assertNull(commentsDao.getByComment(comment.getComment()));
+    }
+
+    public static Comment createTestComment() {
+	Comment testComment = new Comment();
+	testComment.setComment(TEST_COMMENT_NAME);
+	testComment.setCommentDate(TEST_COMMENT_DATE);
+	testComment.setUserId(Integer.toString(TEST_COMMENT_USER_ID));
+	testComment.setUserName(TEST_COMMENT_USER_NAME);
+	return testComment;
+    }
+    public final static String TEST_COMMENT_ID = "1";
+    public final static String TEST_COMMENT_PROFILE_ID = "clarin.eu:cr1:p_1297242111880";
+    public final static String TEST_COMMENT_COMPONENT_ID = "clarin.eu:cr1:c_1290431694600";
+    public final static String TEST_COMMENT_NAME = "test";
+    public final static int TEST_COMMENT_USER_ID = 8;
+    public final static String TEST_COMMENT_USER_NAME = "J. Unit";
+    public final static String TEST_COMMENT_DATE = Comment.createNewDate();
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDaoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDaoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentDescriptionDaoTest.java	(revision 1843)
@@ -0,0 +1,78 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import static clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase.*;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.rest.RegistryTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ComponentDescriptionDaoTest extends AbstractDescriptionDaoTest {
+
+    @Autowired
+    ComponentDescriptionDao componentDescriptionDao;
+
+    @Before
+    public void init() {
+	resetDatabase(jdbcTemplate);
+	createTableComponentDescription(jdbcTemplate);
+	createTableXmlContent(jdbcTemplate);
+	createTableRegistryUser(jdbcTemplate);
+	createTableComments(jdbcTemplate);
+    }
+
+    @Override
+    protected AbstractDescriptionDao getDao() {
+	return componentDescriptionDao;
+    }
+
+    @Override
+    protected AbstractDescription createNewDescription() {
+	return ComponentDescription.createNewDescription();
+    }
+
+    @Test
+    public void testTransaction() {
+	// Reset database and only create Content table so that inserting a description will fail
+	resetDatabase(jdbcTemplate);
+	createTableXmlContent(jdbcTemplate);
+
+	// Create description and component
+	String regDate = AbstractDescription.createNewDate();
+	AbstractDescription description = createNewDescription();
+	description.setName("MyComponent");
+	description.setDescription("MyDescription");
+	description.setCreatorName("Aap");
+	description.setGroupName("MyGroup");
+	description.setDomainName("MyDomain");
+	description.setHref("http://MyHref");
+	description.setRegistrationDate(regDate);
+	String testComponent = RegistryTestHelper.getComponentTestContentString();
+
+	// Try inserting description, which should fail because there is not ComponentDescription table
+	try {
+	    getDao().insertDescription(description, testComponent, true, null);
+	    fail("No exception thrown for missing table");
+	} catch (DataAccessException ex) {
+	}
+
+	// Check whether content was not inserted
+	final String select = "SELECT count(*) FROM " + ComponentDescriptionDao.TABLE_XML_CONTENT;
+	int count = jdbcTemplate.queryForInt(select);
+	assertEquals(0, count);
+    }
+
+    @Override
+    protected String getContentString() {
+	return RegistryTestHelper.getComponentTestContentString();
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImplTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImplTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryDbImplTest.java	(revision 1843)
@@ -0,0 +1,770 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import clarin.cmdi.componentregistry.DeleteFailedException;
+import clarin.cmdi.componentregistry.UserCredentials;
+import clarin.cmdi.componentregistry.UserUnauthorizedException;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import clarin.cmdi.componentregistry.rest.DummyPrincipal;
+import clarin.cmdi.componentregistry.rest.RegistryTestHelper;
+import java.util.Date;
+import java.util.List;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class ComponentRegistryDbImplTest {
+
+    protected final static UserCredentials USER_CREDS = DummyPrincipal.DUMMY_CREDENTIALS;
+    protected static final DummyPrincipal PRINCIPAL_ADMIN = DummyPrincipal.DUMMY_ADMIN_PRINCIPAL;
+    @Autowired
+    private ComponentRegistryBeanFactory componentRegistryBeanFactory;
+    @Autowired
+    private UserDao userDao;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+    }
+
+    @Test
+    public void testRegisterComponent() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ComponentDescription description = ComponentDescription.createNewDescription();
+
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+
+	assertEquals(0, register.getComponentDescriptions().size());
+	assertEquals(0, register.getProfileDescriptions().size());
+
+	CMDComponentSpec testComponent = RegistryTestHelper.getTestComponent();
+	assertNull(testComponent.getHeader().getID());
+	assertNull(testComponent.getHeader().getName());
+	assertNull(testComponent.getHeader().getDescription());
+	testComponent.getHeader().setDescription("Will not be overwritten");
+
+	register.register(description, testComponent);
+
+	assertEquals(1, register.getComponentDescriptions().size());
+	assertEquals(0, register.getProfileDescriptions().size());
+
+	ComponentDescription desc = register.getComponentDescriptions().get(0);
+	assertNotNull(desc);
+	CMDComponentSpec component = register.getMDComponent(desc.getId());
+	assertNotNull(component);
+
+	assertNull(register.getMDProfile(desc.getId()));
+
+	ComponentDescription componentDescription = register.getComponentDescription(description.getId());
+	assertNotNull(componentDescription);
+
+	assertEquals("Header id should be set from description id", description.getId(), component.getHeader().getID());
+	assertEquals("Aap", component.getHeader().getName());
+	assertEquals("Will not be overwritten", component.getHeader().
+		getDescription());
+    }
+
+    @Test
+    public void testRegisterProfile() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ProfileDescription description = ProfileDescription.createNewDescription();
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+
+	assertEquals(0, register.getComponentDescriptions().size());
+	assertEquals(0, register.getProfileDescriptions().size());
+
+	CMDComponentSpec testProfile = RegistryTestHelper.getTestProfile();
+	assertNull(testProfile.getHeader().getID());
+	assertNull(testProfile.getHeader().getName());
+	assertNull(testProfile.getHeader().getDescription());
+
+	register.register(description, testProfile);
+
+	assertEquals(0, register.getComponentDescriptions().size());
+	assertEquals(1, register.getProfileDescriptions().size());
+	ProfileDescription desc = register.getProfileDescriptions().get(0);
+	assertNull(register.getMDComponent(desc.getId()));
+
+	CMDComponentSpec profile = register.getMDProfile(desc.getId());
+
+	ProfileDescription profileDescription = register.getProfileDescription(description.getId());
+	assertNotNull(profileDescription);
+
+	assertNotNull(profile);
+	assertEquals("Header id should be set from description id", description.getId(), profile.getHeader().getID());
+	assertEquals("Aap", profile.getHeader().getName());
+	assertEquals("MyDescription", profile.getHeader().getDescription());
+    }
+
+    @Test
+    public void testDeletePublicProfile() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ProfileDescription description = createProfile(register);
+
+	// Delete as admin
+	register.deleteMDProfile(description.getId(), PRINCIPAL_ADMIN);
+
+	assertEquals(0, register.getProfileDescriptions().size());
+	assertNull(register.getMDProfile(description.getId()));
+    }
+
+    @Test
+    public void testDeleteUserProfile() throws Exception {
+	RegistryUser user = createUser();
+	Number userId = userDao.insertUser(user);
+	ComponentRegistry registry = getComponentRegistryForUser(userId);
+	ProfileDescription description = createProfile(registry);
+	// Delete as user
+	registry.deleteMDProfile(description.getId(), USER_CREDS.getPrincipal());
+	assertEquals(0, registry.getComponentDescriptions().size());
+	assertNull(registry.getMDProfile(description.getId()));
+	// Delete as admin
+	description = createProfile(registry);
+
+	registry.deleteMDProfile(description.getId(), PRINCIPAL_ADMIN);
+	assertEquals(0, registry.getProfileDescriptions().size());
+	assertNull(registry.getMDProfile(description.getId()));
+    }
+
+    @Test
+    public void testGetDeletedDescriptions() throws Exception {
+	RegistryUser user = createUser();
+	Number userId = userDao.insertUser(user);
+	ComponentRegistry registry = getComponentRegistryForUser(userId);
+	ComponentRegistry publicReg = getComponentRegistryForUser(null);
+	ProfileDescription desc1 = createProfile(registry);
+	ProfileDescription desc2 = createProfile(publicReg);
+	ComponentDescription desc3 = createComponent(registry);
+	ComponentDescription desc4 = createComponent(publicReg);
+
+	assertEquals(0, registry.getDeletedProfileDescriptions().size());
+	assertEquals(0, publicReg.getDeletedProfileDescriptions().size());
+	assertEquals(0, registry.getDeletedComponentDescriptions().size());
+	assertEquals(0, publicReg.getDeletedComponentDescriptions().size());
+
+	registry.deleteMDProfile(desc1.getId(), USER_CREDS.getPrincipal());
+
+	assertEquals(1, registry.getDeletedProfileDescriptions().size());
+	assertEquals(0, publicReg.getDeletedProfileDescriptions().size());
+	assertEquals(0, registry.getDeletedComponentDescriptions().size());
+	assertEquals(0, publicReg.getDeletedComponentDescriptions().size());
+
+	publicReg.deleteMDProfile(desc2.getId(), USER_CREDS.getPrincipal());
+
+	assertEquals(1, registry.getDeletedProfileDescriptions().size());
+	assertEquals(1, publicReg.getDeletedProfileDescriptions().size());
+	assertEquals(0, registry.getDeletedComponentDescriptions().size());
+	assertEquals(0, publicReg.getDeletedComponentDescriptions().size());
+
+	registry.deleteMDComponent(desc3.getId(), USER_CREDS.getPrincipal(), false);
+
+	assertEquals(1, registry.getDeletedProfileDescriptions().size());
+	assertEquals(1, publicReg.getDeletedProfileDescriptions().size());
+	assertEquals(1, registry.getDeletedComponentDescriptions().size());
+	assertEquals(0, publicReg.getDeletedComponentDescriptions().size());
+
+	publicReg.deleteMDComponent(desc4.getId(), USER_CREDS.getPrincipal(), false);
+
+	assertEquals(1, registry.getDeletedProfileDescriptions().size());
+	assertEquals(1, publicReg.getDeletedProfileDescriptions().size());
+	assertEquals(1, registry.getDeletedComponentDescriptions().size());
+	assertEquals(1, publicReg.getDeletedComponentDescriptions().size());
+
+    }
+
+    private Comment createComment(ComponentRegistry register, ProfileDescription description) throws Exception {
+	Comment comment = createComment(description);
+	register.registerComment(comment, USER_CREDS.getPrincipalName());
+	assertEquals(1, register.getCommentsInProfile(description.getId()).size());
+	return comment;
+    }
+
+    private Comment createComment(AbstractDescription description) {
+	Comment comment = Comment.createANewComment();
+	if (description instanceof ComponentDescription) {
+	    comment.setComponentDescriptionId(description.getId());
+	} else if (description instanceof ProfileDescription) {
+	    comment.setProfileDescriptionId(description.getId());
+	}
+	comment.setComment("Test comment at " + new Date().toString());
+	comment.setUserName(USER_CREDS.getDisplayName());
+	return comment;
+    }
+
+    private ProfileDescription createProfile(ComponentRegistry register) throws Exception {
+	ProfileDescription description = getProfileDesc();
+
+	CMDComponentSpec testProfile = RegistryTestHelper.getTestProfile();
+	register.register(description, testProfile);
+
+	assertEquals(1, register.getProfileDescriptions().size());
+	assertNotNull(register.getMDProfile(description.getId()));
+	// Non authorized user should never be able to delete
+	try {
+	    register.deleteMDProfile(description.getId(), new DummyPrincipal("Fake User"));
+	    fail("Should have thrown exception");
+	} catch (UserUnauthorizedException e) {
+	}
+
+	assertEquals(1, register.getProfileDescriptions().size());
+	assertNotNull(register.getMDProfile(description.getId()));
+	return description;
+    }
+
+    private ProfileDescription getProfileDesc() {
+	ProfileDescription description = ProfileDescription.createNewDescription();
+	description.setName("Aap");
+	description.setCreatorName(USER_CREDS.getDisplayName());
+	description.setUserId(USER_CREDS.getPrincipalName());
+	description.setDescription("MyDescription");
+	return description;
+    }
+
+//    @Test
+//    public void testPostComponentcomment() throws Exception {
+//	ComponentRegistry registry = getComponentRegistryForUser(null);
+//	ComponentDescription description = createComponent(registry);
+//
+//    }
+    @Test
+    public void testDeletePublicComponent() throws Exception {
+	ComponentRegistry registry = getComponentRegistryForUser(null);
+	ComponentDescription description = createComponent(registry);
+	// Delete as admin
+	registry.deleteMDComponent(description.getId(), PRINCIPAL_ADMIN, false);
+	assertEquals(0, registry.getComponentDescriptions().size());
+	assertNull(registry.getMDComponent(description.getId()));
+    }
+
+    @Test
+    public void testDeleteUserComponent() throws Exception {
+	RegistryUser user = createUser();
+	Number userId = userDao.insertUser(user);
+	ComponentRegistry registry = getComponentRegistryForUser(userId);
+	ComponentDescription description = createComponent(registry);
+	// Delete as user
+	registry.deleteMDComponent(description.getId(), USER_CREDS.getPrincipal(), false);
+	assertEquals(0, registry.getComponentDescriptions().size());
+	assertNull(registry.getMDProfile(description.getId()));
+
+	// Delete as admin
+	description = createComponent(registry);
+
+	registry.deleteMDComponent(description.getId(), PRINCIPAL_ADMIN, false);
+	assertEquals(0, registry.getComponentDescriptions().size());
+	assertNull(registry.getMDComponent(description.getId()));
+    }
+
+    @Test
+    public void testDoNotDeleteOldPublicComponent() throws Exception {
+	Number userId = userDao.insertUser(createUser());
+	ComponentRegistry registry = getComponentRegistryForUser(userId);
+
+	ComponentDescription description = getComponentDesc();
+	Calendar calendar = Calendar.getInstance();
+	calendar.set(Calendar.YEAR, 1999);
+	description.setRegistrationDate(DateFormatUtils.formatUTC(calendar.getTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()));
+	CMDComponentSpec testComp = RegistryTestHelper.getTestComponent();
+
+	registry.register(description, testComp);
+	registry.publish(description, testComp, USER_CREDS.getPrincipal());
+
+	// Switch to public registry
+	registry = getComponentRegistryForUser(null);
+
+	try {
+	    registry.deleteMDComponent(description.getId(), USER_CREDS.getPrincipal(), false);
+	    fail("Should have thrown exception");
+	} catch (DeleteFailedException e) {
+	}
+	assertEquals(1, registry.getComponentDescriptions().size());
+	registry.deleteMDComponent(description.getId(), PRINCIPAL_ADMIN, false);
+	assertEquals(0, registry.getComponentDescriptions().size());
+
+	registry = getComponentRegistryForUser(userId); // ComponentRegistryFactoryImpl.getInstance().getComponentRegistry(true, USER_CREDS); //user registry
+	description = getComponentDesc();
+	registry.register(description, testComp);
+	assertEquals(1, registry.getComponentDescriptions().size());
+	registry.deleteMDComponent(description.getId(), USER_CREDS.getPrincipal(), false); //user workspace can always delete
+	assertEquals(0, registry.getComponentDescriptions().size());
+    }
+
+    @Test
+    public void testDoNotDeleteOldPublicProfile() throws Exception {
+	Number userId = userDao.insertUser(createUser());
+	ComponentRegistry registry = getComponentRegistryForUser(userId);
+
+	ProfileDescription description = getProfileDesc();
+	Calendar calendar = Calendar.getInstance();
+	calendar.set(Calendar.YEAR, 1999);
+	description.setRegistrationDate(DateFormatUtils.formatUTC(calendar.getTime(), DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.getPattern()));
+	CMDComponentSpec testComp = RegistryTestHelper.getTestProfile();
+
+	registry.register(description, testComp);
+	registry.publish(description, testComp, USER_CREDS.getPrincipal());
+
+	// Switch to public registry
+	registry = getComponentRegistryForUser(null);
+	try {
+	    registry.deleteMDProfile(description.getId(), USER_CREDS.getPrincipal());
+	    fail("Should have thrown exception");
+	} catch (DeleteFailedException e) {
+	}
+	assertEquals(1, registry.getProfileDescriptions().size());
+	registry.deleteMDProfile(description.getId(), PRINCIPAL_ADMIN);
+	assertEquals(0, registry.getProfileDescriptions().size());
+
+	registry = getComponentRegistryForUser(userId);
+	description = getProfileDesc();//Need to create a new one for a new id
+	registry.register(description, testComp);
+	assertEquals(1, registry.getProfileDescriptions().size());
+	registry.deleteMDProfile(description.getId(), USER_CREDS.getPrincipal()); //user workspace can always delete
+	assertEquals(0, registry.getProfileDescriptions().size());
+    }
+
+    private ComponentDescription createComponent(ComponentRegistry registry) throws Exception {
+	ComponentDescription description = getComponentDesc();
+	CMDComponentSpec testComp = RegistryTestHelper.getTestComponent();
+
+	registry.register(description, testComp);
+
+	// Non authorized user should never be able to delete
+	try {
+	    registry.deleteMDComponent(description.getId(), new DummyPrincipal("Fake User"), false);
+	    fail("Should have thrown exception");
+	} catch (UserUnauthorizedException e) {
+	}
+
+	assertEquals(1, registry.getComponentDescriptions().size());
+	assertNotNull(registry.getMDComponent(description.getId()));
+	return description;
+    }
+
+    private ComponentDescription getComponentDesc() {
+	ComponentDescription description = ComponentDescription.createNewDescription();
+	description.setName("Aap");
+	description.setCreatorName(USER_CREDS.getDisplayName());
+	description.setUserId(USER_CREDS.getPrincipalName());
+	description.setDescription("MyDescription");
+	return description;
+    }
+
+    private ComponentRegistry getComponentRegistryForUser(Number userId) {
+	ComponentRegistryDbImpl componentRegistry = componentRegistryBeanFactory.getNewComponentRegistry();
+	componentRegistry.setUserId(userId);
+	return componentRegistry;
+    }
+
+    private RegistryUser createUser() {
+	return createUser(USER_CREDS);
+    }
+
+    private RegistryUser createUser(UserCredentials credentials) {
+	RegistryUser user = new RegistryUser();
+	user.setName(credentials.getDisplayName());
+	user.setPrincipalName(credentials.getPrincipalName());
+	return user;
+    }
+
+    @Test
+    public void testGetProfileAsXsd() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	String profileContent = "";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component name=\"Actor\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	profileContent += "        <CMD_Element name=\"Age\">\n";
+	profileContent += "            <ValueScheme>\n";
+	profileContent += "                <pattern>[0-9][0-9]</pattern>\n";
+	profileContent += "            </ValueScheme>\n";
+	profileContent += "        </CMD_Element>\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+
+	String id = "profile1";
+	ProfileDescription description = RegistryTestHelper.addProfile(register, id, profileContent);
+
+	OutputStream output = new ByteArrayOutputStream();
+	register.getMDProfileAsXsd(description.getId(), output);
+	String xsd = output.toString().trim();
+	assertTrue(xsd.endsWith("</xs:schema>"));
+
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "Actor", "0", "unbounded"));
+    }
+
+    @Test
+    public void testGetNestedRecursiveComponentAsXsd() throws Exception {
+	RegistryUser user = createUser();
+	Number userId = userDao.insertUser(user);
+	ComponentRegistry register = getComponentRegistryForUser(null);
+
+	String comp1Id = "component1";
+	String comp2Id = "component2";
+
+	// Component1 references component2
+
+	String comp1Content = "";
+	comp1Content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	comp1Content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	comp1Content += "    <Header/>\n";
+	comp1Content += "    <CMD_Component name=\"Recursion\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	comp1Content += "       <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	comp1Content += "	<CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + comp2Id + "\" CardinalityMin=\"0\" CardinalityMax=\"5\"/>\n";
+	comp1Content += "    </CMD_Component>\n";
+	comp1Content += "</CMD_ComponentSpec>\n";
+
+	ComponentDescription comp1Desc = RegistryTestHelper.addComponent(register, comp1Id, comp1Content);
+
+	// Component2 references component1
+
+	String comp2Content = "";
+	comp2Content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	comp2Content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	comp2Content += "    <Header/>\n";
+	comp2Content += "    <CMD_Component name=\"Recursion\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	comp2Content += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	comp2Content += "	 <CMD_Component ComponentId=\"" + comp1Desc.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"5\"/>\n";
+	comp2Content += "    </CMD_Component>\n";
+	comp2Content += "</CMD_ComponentSpec>\n";
+
+	RegistryTestHelper.addComponent(register, comp2Id, comp2Content);
+
+	String profileContent = "";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component ComponentId=\"" + comp1Desc.getId()
+		+ "\" filename=\"component-test-file\" CardinalityMin=\"0\" CardinalityMax=\"5\">\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+
+	String id = "profile1";
+	ProfileDescription description = RegistryTestHelper.addProfile(register, id, profileContent);
+
+	OutputStream output = new ByteArrayOutputStream();
+	try {
+	    register.getMDProfileAsXml(description.getId(), output);
+	    // This should throw a ComponentRegistryException for recursion
+	    fail();
+	} catch (ComponentRegistryException ex) {
+	}
+    }
+
+    @Test
+    public void testGetNestedComponentAsXsd() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+
+	String compId = "component1";
+	String compContent = "";
+	compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	compContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	compContent += "    <Header/>\n";
+	compContent += "    <CMD_Component name=\"Actor\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	compContent += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	compContent += "    </CMD_Component>\n";
+	compContent += "</CMD_ComponentSpec>\n";
+
+	ComponentDescription compDesc = RegistryTestHelper.addComponent(register, compId, compContent);
+
+	String profileContent = "";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component ComponentId=\"" + compDesc.getId()
+		+ "\" filename=\"component-test-file\" CardinalityMin=\"0\" CardinalityMax=\"5\">\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+
+	String id = "profile1";
+	ProfileDescription description = RegistryTestHelper.addProfile(register, id, profileContent);
+
+	OutputStream output = new ByteArrayOutputStream();
+	register.getMDProfileAsXsd(description.getId(), output);
+	String xsd = output.toString().trim();
+
+	assertTrue(xsd.endsWith("</xs:schema>"));
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "Actor", "0", "5"));
+    }
+
+    @Test
+    public void testGetNestedComponentAsXsdComplex() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+
+	String compContent = "";
+	compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	compContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	compContent += "    <Header/>\n";
+	compContent += "    <CMD_Component name=\"XXX\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	compContent += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	compContent += "    </CMD_Component>\n";
+	compContent += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc1 = RegistryTestHelper.addComponent(register, "component1", compContent);
+
+	compContent = "";
+	compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	compContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	compContent += "    <Header/>\n";
+	compContent += "    <CMD_Component name=\"YYY\" CardinalityMin=\"1\" CardinalityMax=\"1\">\n";
+	compContent += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	compContent += "        <CMD_Component ComponentId=\"" + compDesc1.getId() + "\" filename=\"component-test-file\">\n";
+	compContent += "        </CMD_Component>\n";
+	compContent += "    </CMD_Component>\n";
+	compContent += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc2 = RegistryTestHelper.addComponent(register, "component2", compContent);
+
+	compContent = "";
+	compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	compContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	compContent += "    <Header/>\n";
+	compContent += "    <CMD_Component name=\"ZZZ\u00e9\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+	compContent += "        <CMD_Component ComponentId=\"" + compDesc2.getId()
+		+ "\" filename=\"component-test-file\" CardinalityMin=\"0\" CardinalityMax=\"2\">\n";
+	compContent += "        </CMD_Component>\n";
+	compContent += "        <CMD_Component ComponentId=\"" + compDesc1.getId()
+		+ "\" filename=\"component-test-file\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+	compContent += "        </CMD_Component>\n";
+	compContent += "    </CMD_Component>\n";
+	compContent += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc3 = RegistryTestHelper.addComponent(register, "component3", compContent);
+
+	ByteArrayOutputStream output = new ByteArrayOutputStream();
+	register.getMDComponentAsXsd(compDesc3.getId(), output);
+	String xsd = output.toString("UTF-8").trim();
+
+	assertTrue(xsd.endsWith("</xs:schema>"));
+	// System.out.println(xsd);
+
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "YYY", "0", "2"));
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "XXX", "1", "10"));
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "XXX", "0", "99"));
+	assertTrue(RegistryTestHelper.hasComponent(xsd, "ZZZ\u00e9", "1", "unbounded"));
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ComponentDescription description = ComponentDescription.createNewDescription();
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+
+	CMDComponentSpec testComponent = RegistryTestHelper.getTestComponent("Test1");
+	register.register(description, testComponent);
+
+	// Change values
+	description.setName("Noot");
+	description.setDescription("AnotherDescription");
+	// Update in db
+	register.update(description, testComponent, PRINCIPAL_ADMIN, false);
+	description = register.getComponentDescription(description.getId());
+	// Test if new values are there
+	assertNotNull(description);
+	assertEquals("Noot", description.getName());
+	assertEquals("AnotherDescription", description.getDescription());
+
+	// Update content
+	CMDComponentSpec testComponent2 = RegistryTestHelper.getTestComponent("Test2");
+	register.update(description, testComponent2, PRINCIPAL_ADMIN, false);
+	// Test if new content is there
+	assertEquals(RegistryTestHelper.getXml(testComponent2),
+		RegistryTestHelper.getXml(register.getMDComponent(description.getId())));
+
+
+	// Update both
+	description.setName("Mies");
+	description.setDescription("YetAnotherDescription");
+	CMDComponentSpec testComponent3 = RegistryTestHelper.getTestComponent("Test3");
+
+	// Update in db
+	register.update(description, testComponent3, PRINCIPAL_ADMIN, false);
+	description = register.getComponentDescription(description.getId());
+	// Test if new values are there
+	assertNotNull(description);
+	assertEquals("Mies", description.getName());
+	assertEquals("YetAnotherDescription", description.getDescription());
+	// Test if new content is there
+	assertEquals(RegistryTestHelper.getXml(testComponent3),
+		RegistryTestHelper.getXml(register.getMDComponent(description.getId())));
+    }
+
+    @Test
+    public void testPublish() throws Exception {
+	Number userId = userDao.insertUser(createUser());
+
+	ComponentRegistry userRegistry = getComponentRegistryForUser(userId);
+	ComponentRegistry publicRegistry = getComponentRegistryForUser(null);
+	ComponentDescription description = ComponentDescription.createNewDescription();
+	description.setName("Aap");
+	description.setDescription("MyDescription");
+	description.setUserId(DummyPrincipal.DUMMY_CREDENTIALS.getPrincipalName());
+
+	CMDComponentSpec testComponent = RegistryTestHelper.getTestComponent("Test1");
+	userRegistry.register(description, testComponent);
+	description = userRegistry.getComponentDescription(description.getId());
+	assertNotNull(description);
+	assertEquals("Aap", description.getName());
+	assertEquals("MyDescription", description.getDescription());
+
+	// Change values
+	description.setName("Noot");
+	description.setDescription("AnotherDescription");
+	CMDComponentSpec testComponent2 = RegistryTestHelper.getTestComponent("Test2");
+
+	// Publish
+	int result = userRegistry.publish(description, testComponent2, DummyPrincipal.DUMMY_PRINCIPAL);
+	assertEquals(0, result);
+
+	// Should not be in user registry
+	assertNull(userRegistry.getComponentDescription(description.getId()));
+	// Get from public registry
+	description = publicRegistry.getComponentDescription(description.getId());
+	// Test if new values are there
+	assertNotNull(description);
+	assertEquals("Noot", description.getName());
+	assertEquals("AnotherDescription", description.getDescription());
+	// Test if new content is there
+	assertEquals(RegistryTestHelper.getXml(testComponent2),
+		RegistryTestHelper.getXml(publicRegistry.getMDComponent(description.getId())));
+	assertNull(userRegistry.getMDComponent(description.getId()));
+    }
+
+    @Test
+    public void testRegisterPublicComment() throws Exception {
+	// Associated user should exist when posting a comment
+	RegistryUser user = createUser();
+	userDao.insertUser(user);
+
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ProfileDescription description = createProfile(register);
+	Comment comment = createComment(register, description);
+	assertNotNull(comment);
+	assertEquals(0, description.getCommentsCount());
+
+	List<Comment> comments = register.getCommentsInProfile(description.getId());
+	assertEquals(1, comments.size());
+
+	comment = comments.get(0);
+	assertEquals("0", comment.getUserId());
+	assertEquals(USER_CREDS.getDisplayName(), comment.getUserName());
+
+	description = register.getProfileDescription(description.getId());
+	assertEquals(1, description.getCommentsCount());
+    }
+
+    @Test
+    public void testRegisterPrivateComment() throws Exception {
+	// Associated user should exist when posting a comment
+	RegistryUser user = createUser();
+	Number uid = userDao.insertUser(user);
+
+	ComponentRegistry register = getComponentRegistryForUser(uid);
+	ProfileDescription description = createProfile(register);
+	Comment comment = createComment(register, description);
+	assertNotNull(comment);
+	assertEquals(0, description.getCommentsCount());
+
+	List<Comment> comments = register.getCommentsInProfile(description.getId());
+	assertEquals(1, comments.size());
+
+	comment = comments.get(0);
+	assertEquals("0", comment.getUserId());
+	assertEquals(USER_CREDS.getDisplayName(), comment.getUserName());
+
+	description = register.getProfileDescription(description.getId());
+	assertEquals(1, description.getCommentsCount());
+    }
+
+    @Test
+    public void testDeleteComment() throws Exception {
+	// Associated user should exist when posting a comment
+	RegistryUser user = createUser();
+	userDao.insertUser(user);
+
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ProfileDescription description = createProfile(register);
+	Comment comment = createComment(register, description);
+	assertNotNull(comment);
+
+	List<Comment> comments = register.getCommentsInProfile(description.getId());
+	assertEquals(1, comments.size());
+	description = register.getProfileDescription(description.getId());
+	assertEquals(1, description.getCommentsCount());
+
+	comment = comments.get(0);
+	register.deleteComment(comment.getId(), USER_CREDS.getPrincipal());
+	comments = register.getCommentsInProfile(description.getId());
+	assertEquals(0, comments.size());
+	description = register.getProfileDescription(description.getId());
+	assertEquals(0, description.getCommentsCount());
+    }
+
+    @Test
+    public void testDeleteSomeoneElsesComment() throws Exception {
+	// User 1 posts a comment...
+
+	RegistryUser user1 = createUser(USER_CREDS);
+	userDao.insertUser(user1);
+
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	ProfileDescription description = createProfile(register);
+	Comment comment = createComment(register, description);
+	assertNotNull(comment);
+
+	List<Comment> comments = register.getCommentsInProfile(description.getId());
+	assertEquals(1, comments.size());
+	comment = comments.get(0);
+
+	// Another user comes along....
+
+	DummyPrincipal user2 = new DummyPrincipal(USER_CREDS.getPrincipalName() + "2");
+	userDao.insertUser(createUser(user2.getCredentials()));
+
+	try {
+	    register.deleteComment(comment.getId(), user2);
+	    // Should not get beyond this
+	    fail("Could delete someone else's comment!");
+	} catch (UserUnauthorizedException ex) {
+	    System.err.print(ex);
+	}
+    }
+
+    @Test
+    public void testGetName() throws Exception {
+	ComponentRegistry register = getComponentRegistryForUser(null);
+	assertEquals(ComponentRegistry.PUBLIC_NAME, register.getName());
+
+	RegistryUser user1 = createUser(USER_CREDS);
+	Number id = userDao.insertUser(user1);
+
+	register = getComponentRegistryForUser(id);
+	assertEquals("Registry of J.Unit", register.getName());
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImplTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImplTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryFactoryDbImplTest.java	(revision 1843)
@@ -0,0 +1,105 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.junit.Before;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.UserCredentials;
+import clarin.cmdi.componentregistry.rest.DummyPrincipal;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class ComponentRegistryFactoryDbImplTest {
+
+    @Autowired
+    private ComponentRegistryFactoryDbImpl componentRegistryFactory;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetDatabase(jdbcTemplate);
+	ComponentRegistryTestDatabase.createTableRegistryUser(jdbcTemplate);
+    }
+
+    @Test
+    public void testInjection() {
+	assertNotNull(componentRegistryFactory);
+	assertNotNull(jdbcTemplate);
+    }
+
+    @Test
+    public void testGetPublicRegistry() {
+	ComponentRegistry registry = componentRegistryFactory.getPublicRegistry();
+	assertNotNull(registry);
+    }
+
+    @Test
+    public void getComponentRegistry() {
+	// Get public
+	assertNotNull(componentRegistryFactory.getComponentRegistry(false, null));
+
+	// Get for non-existing user
+	final RegistryUser testUser = UserDaoTest.createTestUser();
+	UserCredentials credentials = new DummyPrincipal(testUser.
+		getPrincipalName()).getCredentials();
+
+	ComponentRegistryDbImpl cr1 = (ComponentRegistryDbImpl) componentRegistryFactory.
+		getComponentRegistry(true, credentials);
+	assertNotNull(cr1);
+	// Get for existing user
+	ComponentRegistryDbImpl cr2 = (ComponentRegistryDbImpl) componentRegistryFactory.
+		getComponentRegistry(true, credentials);
+	assertNotNull(cr2);
+	assertEquals(cr1.getUserId(), cr2.getUserId());
+
+	// Get for another new user
+	UserCredentials credentials2 = new DummyPrincipal(testUser.
+		getPrincipalName() + "2").getCredentials();
+	ComponentRegistryDbImpl cr3 = (ComponentRegistryDbImpl) componentRegistryFactory.
+		getComponentRegistry(true, credentials2);
+	assertNotNull(cr3);
+	assertNotSame(cr1.getUserId(), cr3.getUserId());
+    }
+
+    @Test
+    public void testGetOtherUserComponentRegistry() {
+	UserCredentials userCredentials = DummyPrincipal.DUMMY_PRINCIPAL.
+		getCredentials();
+
+	// Create registry for new user
+	ComponentRegistryDbImpl cr1 = (ComponentRegistryDbImpl) componentRegistryFactory.
+		getComponentRegistry(true, userCredentials);
+
+	String id = cr1.getUserId().toString();
+
+	// Get it as admin
+	ComponentRegistryDbImpl cr2 = (ComponentRegistryDbImpl) componentRegistryFactory.
+		getOtherUserComponentRegistry(DummyPrincipal.DUMMY_ADMIN_PRINCIPAL, id);
+	assertNotNull(cr2);
+	// Should be this user's registry
+	assertEquals(cr1.getUserId(), cr2.getUserId());
+
+	// Try get it as non-admin
+	try {
+	    componentRegistryFactory.getOtherUserComponentRegistry(DummyPrincipal.DUMMY_PRINCIPAL, id);
+	    fail("Non-admin can get other user's component registry");
+	} catch (Exception ex) {
+	    // Exception should occur
+	}
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryTestDatabase.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryTestDatabase.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ComponentRegistryTestDatabase.java	(revision 1843)
@@ -0,0 +1,86 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public final class ComponentRegistryTestDatabase {
+
+    private ComponentRegistryTestDatabase() {
+    }
+
+    public static void resetDatabase(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("DROP SCHEMA PUBLIC CASCADE");
+    }
+
+    public static void createTableComponentDescription(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("CREATE TABLE component_description ("
+                + "id IDENTITY NOT NULL,"
+                + "user_id integer,"
+                + "    content_id integer NOT NULL,"
+                + "  is_public boolean NOT NULL,"
+                + "  is_deleted boolean DEFAULT false NOT NULL,"
+                + "  component_id character varying NOT NULL,"
+                + "  name character varying NOT NULL,"
+                + "  description character varying NOT NULL,"
+                + "  registration_date timestamp,"// with timezone,"
+                + "  href character varying,"
+                + "  creator_name character varying,"
+                + "  domain_name character varying,"
+                + "  group_name character varying, CONSTRAINT UNIQUE_COMPONENT_ID UNIQUE (component_id));");
+    }
+
+    public static void createTableProfileDescription(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("CREATE TABLE profile_description ("
+                + "id IDENTITY NOT NULL,"
+                + "user_id integer,"
+                + "    content_id integer NOT NULL,"
+                + "  is_public boolean NOT NULL,"
+                + "  is_deleted boolean DEFAULT false NOT NULL,"
+                + "  profile_id character varying NOT NULL,"
+                + "  name character varying NOT NULL,"
+                + "  description character varying NOT NULL,"
+                + "  registration_date timestamp,"// with timezone,"
+                + "  href character varying,"
+                + "  creator_name character varying,"
+                + "  domain_name character varying,"
+                + "  group_name character varying, "
+                + "  show_in_editor boolean DEFAULT true NOT NULL, "
+                + "  CONSTRAINT UNIQUE_PROFILE_ID UNIQUE (profile_id));");
+    }
+
+    public static void createTableXmlContent(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("CREATE TABLE xml_content ("
+                + "id IDENTITY NOT NULL, content CHARACTER VARYING NOT NULL);");
+    }
+
+    public static void createTableRegistryUser(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("CREATE TABLE registry_user ("
+                + " id IDENTITY NOT NULL,"
+                + " name character varying,"
+                + " principal_name character varying);");
+    }
+
+    public static void createTableComments(JdbcTemplate jdbcTemplate) {
+        jdbcTemplate.execute("CREATE TABLE comments ("
+                + "id IDENTITY NOT NULL,"
+                + "user_id integer,"
+                + "  profile_description_id character varying,"
+                + "  component_description_id character varying,"               
+                + "  comments character varying NOT NULL,"
+                + "  comment_date timestamp,"
+		+ "  user_name character varying,"
+                + "  CONSTRAINT UNIQUE_COMMENTS_ID UNIQUE (id));");
+    }
+
+    public static void resetAndCreateAllTables(JdbcTemplate jdbcTemplate) {
+        resetDatabase(jdbcTemplate);
+        createTableComponentDescription(jdbcTemplate);
+        createTableProfileDescription(jdbcTemplate);
+        createTableXmlContent(jdbcTemplate);
+        createTableRegistryUser(jdbcTemplate);
+        createTableComments(jdbcTemplate);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDaoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDaoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/ProfileDescriptionDaoTest.java	(revision 1843)
@@ -0,0 +1,44 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import static clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase.*;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.rest.RegistryTestHelper;
+
+import org.junit.Before;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+public class ProfileDescriptionDaoTest extends AbstractDescriptionDaoTest {
+
+    @Autowired
+    ProfileDescriptionDao profileDescriptionDao;
+
+    @Before
+    public void init() {
+	resetDatabase(jdbcTemplate);
+	createTableProfileDescription(jdbcTemplate);
+	createTableXmlContent(jdbcTemplate);
+	createTableRegistryUser(jdbcTemplate);
+	createTableComments(jdbcTemplate);
+    }
+
+    @Override
+    protected AbstractDescriptionDao getDao() {
+	return profileDescriptionDao;
+    }
+
+    @Override
+    protected AbstractDescription createNewDescription() {
+	return ProfileDescription.createNewDescription();
+    }
+    
+    @Override
+    protected String getContentString() {
+	return RegistryTestHelper.getProfileTestContentString();
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/UserDaoTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/UserDaoTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/impl/database/UserDaoTest.java	(revision 1843)
@@ -0,0 +1,90 @@
+package clarin.cmdi.componentregistry.impl.database;
+
+import clarin.cmdi.componentregistry.model.RegistryUser;
+import java.util.List;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertEquals;
+import org.junit.Before;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ *
+ * @author Twan Goosen <twan.goosen@mpi.nl>
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class UserDaoTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    @Autowired
+    private UserDao userDao;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetDatabase(jdbcTemplate);
+	ComponentRegistryTestDatabase.createTableRegistryUser(jdbcTemplate);
+    }
+
+    @Test
+    public void testInjection() {
+	assertNotNull(jdbcTemplate);
+	assertNotNull(userDao);
+    }
+
+    @Test
+    public void testInsertUser() {
+	RegistryUser testUser = createTestUser();
+
+	assertEquals(0, userDao.getAllUsers().size());
+	Number newId = userDao.insertUser(testUser);
+	assertNotNull(newId);
+
+	List<RegistryUser> users = userDao.getAllUsers();
+	assertEquals(1, users.size());
+
+	assertEquals(TEST_USER_NAME, users.get(0).getName());
+	assertEquals(TEST_USER_PRINCIPAL_NAME, users.get(0).getPrincipalName());
+    }
+
+    @Test
+    public void testGetAllUsers() {
+	assertEquals(0, userDao.getAllUsers().size());
+    }
+
+    @Test
+    public void testGetUserByPrincipalName() {
+	RegistryUser testUser = createTestUser();
+	userDao.insertUser(testUser);
+
+	assertNotNull(userDao.getByPrincipalName(TEST_USER_PRINCIPAL_NAME));
+	assertNull(userDao.getByPrincipalName("NON-EXISTING PRINCIPAL NAME"));
+    }
+
+    public static RegistryUser createTestUser() {
+	RegistryUser testUser = new RegistryUser();
+	testUser.setName(TEST_USER_NAME);
+	testUser.setPrincipalName(TEST_USER_PRINCIPAL_NAME);
+	return testUser;
+    }
+
+    @Test
+    public void testUpdateUser() {
+	RegistryUser testUser = createTestUser();
+	Number id = userDao.insertUser(testUser);
+
+	testUser.setName("I. Changed");
+	userDao.updateUser(id, testUser);
+
+	assertEquals("I. Changed", userDao.getById(id).getName());
+    }
+    public final static String TEST_USER_NAME = "Aap";
+    public final static String TEST_USER_PRINCIPAL_NAME = "aap@clarin.eu";
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentResponseTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentResponseTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentResponseTest.java	(revision 1843)
@@ -0,0 +1,87 @@
+package clarin.cmdi.componentregistry.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import org.junit.Test;
+
+/**
+ *
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+public class CommentResponseTest {
+
+    /**
+     * Test with no validate attribute should return errors 
+     * @throws Exception 
+     */
+    @Test
+    public void testRegisterError() throws Exception {
+	CommentResponse resp = new CommentResponse();
+	resp.setRegistered(false);
+	resp.setIsInUserSpace(true);
+	resp.addError("Error 1");
+	resp.addError("Error 2, <!-- to be escaped -->");
+	ByteArrayOutputStream out = new ByteArrayOutputStream();
+	MDMarshaller.marshal(resp, out);
+	String expected = "";
+	expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	expected += "<commentResponse isInUserSpace=\"true\" registered=\"false\" xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	expected += "    <errors>\n";
+	expected += "        <error>Error 1</error>\n";
+	expected += "        <error>Error 2, &lt;!-- to be escaped --&gt;</error>\n";
+	expected += "    </errors>\n";
+	expected += "</commentResponse>\n";
+	assertEquals(expected, out.toString());
+
+	CommentResponse rr = MDMarshaller.unmarshal(CommentResponse.class, new ByteArrayInputStream(expected.getBytes()), null);
+	assertFalse(rr.isRegistered());
+	assertEquals(2, rr.getErrors().size());
+    }
+
+    /**
+     * Test successfully processed
+     * @throws Exception 
+     */
+    @Test
+    public void testRegisterSucces() throws Exception {
+	CommentResponse resp = new CommentResponse();
+	resp.setRegistered(true);
+	resp.setIsInUserSpace(false);
+	resp.setComment(getComment());
+	ByteArrayOutputStream out = new ByteArrayOutputStream();
+	MDMarshaller.marshal(resp, out);
+	String expected = "";
+	expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	expected += "<commentResponse isInUserSpace=\"false\" registered=\"true\" xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	expected += "    <errors/>\n";
+	expected += "    <comment>\n";
+	expected += "        <comments>Name</comments>\n";
+	expected += "        <commentDate>myDate</commentDate>\n";
+	expected += "        <profileDescriptionId>myD</profileDescriptionId>\n";
+	expected += "        <id>myId</id>\n";
+	expected += "        <userName>J. Unit</userName>\n";
+	expected += "    </comment>\n";
+	expected += "</commentResponse>\n";
+	assertEquals(expected, out.toString());
+
+	CommentResponse rr = MDMarshaller.unmarshal(CommentResponse.class, new ByteArrayInputStream(expected.getBytes()), null);
+	assertTrue(rr.isRegistered());
+	assertEquals("myId", rr.getComment().getId());
+    }
+
+    private Comment getComment() {
+	Comment com = new Comment();
+	com.setComment("Name");
+	com.setId("myId");
+	com.setUserId("myU");
+	com.setProfileDescriptionId("myD");
+	com.setCommentDate("myDate");
+	com.setUserName("J. Unit");
+	return com;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/CommentTest.java	(revision 1843)
@@ -0,0 +1,71 @@
+package clarin.cmdi.componentregistry.model;
+
+import static org.junit.Assert.assertEquals;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import org.junit.Test;
+
+/**
+ *
+ * @author jeafer
+ */
+public class CommentTest {
+
+    @Test
+    public void testProfileComment() throws Exception {
+        Comment comment1 = new Comment();
+        comment1.setCommentDate("myDate");
+        comment1.setComment("tester");
+        comment1.setId("1");
+        comment1.setProfileDescriptionId("clarin.eu:cr1:p_1297242111880");
+        comment1.setUserId("8");
+	comment1.setUserName("J. Unit");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(comment1, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <comments>tester</comments>\n";
+        expected += "    <commentDate>myDate</commentDate>\n";
+        expected += "    <profileDescriptionId>clarin.eu:cr1:p_1297242111880</profileDescriptionId>\n";
+        expected += "    <id>1</id>\n";
+        expected += "    <userName>J. Unit</userName>\n";
+        expected += "</comment>\n";
+        assertEquals(expected, out.toString());
+
+        Comment comment = MDMarshaller.unmarshal(Comment.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertEquals(comment1.getId(), comment.getId());
+	assertEquals(comment1.getProfileDescriptionId(), comment.getProfileDescriptionId());
+    }
+    
+    @Test
+    public void testComponentComment() throws Exception {
+        Comment comment1 = new Comment();
+        comment1.setCommentDate("myDate");
+        comment1.setComment("tester");
+        comment1.setId("1");
+        comment1.setComponentDescriptionId("clarin.eu:cr1:c_1297242111880");
+        comment1.setUserId("8");
+	comment1.setUserName("J. Unit");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(comment1, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <comments>tester</comments>\n";
+        expected += "    <commentDate>myDate</commentDate>\n";
+        expected += "    <componentDescriptionId>clarin.eu:cr1:c_1297242111880</componentDescriptionId>\n";
+        expected += "    <id>1</id>\n";
+        expected += "    <userName>J. Unit</userName>\n";
+        expected += "</comment>\n";
+        assertEquals(expected, out.toString());
+
+        Comment comment = MDMarshaller.unmarshal(Comment.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertEquals(comment1.getId(), comment.getId());
+	assertEquals(comment1.getComponentDescriptionId(), comment.getComponentDescriptionId());
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ComponentDescriptionTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ComponentDescriptionTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ComponentDescriptionTest.java	(revision 1843)
@@ -0,0 +1,52 @@
+package clarin.cmdi.componentregistry.model;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.bind.JAXBException;
+
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+
+public class ComponentDescriptionTest {
+
+    @Test
+    public void testComponentToXml() throws JAXBException, UnsupportedEncodingException {
+        ComponentDescription desc = new ComponentDescription();
+        desc.setName("Name");
+        desc.setId("myId");
+        desc.setCreatorName("myC");
+        desc.setUserId("user1");
+        desc.setDescription("myD");
+        desc.setRegistrationDate("myDate");
+        desc.setHref("linkToMyComponent");
+        desc.setGroupName("MyGroup");
+        desc.setDomainName("Linguistics");
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(desc, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<componentDescription xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <id>myId</id>\n";
+        expected += "    <description>myD</description>\n";
+        expected += "    <name>Name</name>\n";
+        expected += "    <registrationDate>myDate</registrationDate>\n";
+        expected += "    <creatorName>myC</creatorName>\n";
+        expected += "    <userId>user1</userId>\n";
+        expected += "    <domainName>Linguistics</domainName>\n";
+        expected += "    <ns2:href>linkToMyComponent</ns2:href>\n";
+        expected += "    <groupName>MyGroup</groupName>\n";
+        expected += "    <commentsCount>0</commentsCount>\n";
+        expected += "</componentDescription>\n";
+        assertEquals(expected, out.toString());
+
+        ComponentDescription pd = MDMarshaller.unmarshal(ComponentDescription.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertEquals(desc.getId(), pd.getId());
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ProfileDescriptionTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ProfileDescriptionTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/ProfileDescriptionTest.java	(revision 1843)
@@ -0,0 +1,59 @@
+package clarin.cmdi.componentregistry.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.xml.bind.JAXBException;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+
+public class ProfileDescriptionTest {
+
+    @Test
+    public void testProfileToXml() throws JAXBException, UnsupportedEncodingException {
+        ProfileDescription desc = new ProfileDescription();
+        desc.setName("Name");
+        desc.setId("myId");
+        desc.setCreatorName("myC");
+        desc.setUserId(DigestUtils.md5Hex("user1"));
+        desc.setDescription("myD");
+        desc.setRegistrationDate("myDate");
+        desc.setDomainName("Linguistics");
+        desc.setHref("linkToMyProfile");
+        desc.setGroupName("MyGroup");
+	desc.setCommentsCount(2);
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(desc, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<profileDescription xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <id>myId</id>\n";
+        expected += "    <description>myD</description>\n";
+        expected += "    <name>Name</name>\n";
+        expected += "    <registrationDate>myDate</registrationDate>\n";
+        expected += "    <creatorName>myC</creatorName>\n";
+        expected += "    <userId>"+DigestUtils.md5Hex("user1")+"</userId>\n";
+        expected += "    <domainName>Linguistics</domainName>\n";
+        expected += "    <ns2:href>linkToMyProfile</ns2:href>\n";
+        expected += "    <groupName>MyGroup</groupName>\n";
+        expected += "    <commentsCount>2</commentsCount>\n";
+        expected += "    <showInEditor>true</showInEditor>\n";
+	expected += "</profileDescription>\n";
+        assertEquals(expected, out.toString());
+
+        ProfileDescription pd = MDMarshaller.unmarshal(ProfileDescription.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertEquals(desc.getId(), pd.getId());
+        assertTrue(desc.isThisTheOwner("user1"));
+        assertFalse(desc.isThisTheOwner("aap"));
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/RegisterResponseTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/RegisterResponseTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/model/RegisterResponseTest.java	(revision 1843)
@@ -0,0 +1,130 @@
+package clarin.cmdi.componentregistry.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.MDMarshaller;
+
+public class RegisterResponseTest {
+
+    @Test
+    public void testRegisterError() throws Exception {
+        RegisterResponse resp = new RegisterResponse();
+        resp.setRegistered(false);
+        resp.setIsProfile(true);
+        resp.setIsInUserSpace(true);
+        resp.addError("Error 1");
+        resp.addError("Error 2, <!-- to be escaped -->");
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(resp, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<registerResponse isProfile=\"true\" isInUserSpace=\"true\" registered=\"false\" xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <errors>\n";
+        expected += "        <error>Error 1</error>\n";
+        expected += "        <error>Error 2, &lt;!-- to be escaped --&gt;</error>\n";
+        expected += "    </errors>\n";
+        expected += "</registerResponse>\n";
+        assertEquals(expected, out.toString());
+
+        RegisterResponse rr = MDMarshaller.unmarshal(RegisterResponse.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertFalse(rr.isRegistered());
+        assertTrue(rr.isProfile());
+        assertEquals(2, rr.getErrors().size());
+    }
+
+    @Test
+    public void testRegisterSucces() throws Exception {
+        RegisterResponse resp = new RegisterResponse();
+        resp.setRegistered(true);
+        resp.setIsProfile(true);
+        resp.setIsInUserSpace(false);
+        resp.setDescription(getProfileDescription());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(resp, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<registerResponse isProfile=\"true\" isInUserSpace=\"false\" registered=\"true\" xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <errors/>\n";
+        expected += "    <description xsi:type=\"profileDescription\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
+        expected += "        <id>myId</id>\n";
+        expected += "        <description>myD</description>\n";
+        expected += "        <name>Name</name>\n";
+        expected += "        <registrationDate>myDate</registrationDate>\n";
+        expected += "        <creatorName>myC</creatorName>\n";
+        expected += "        <ns2:href>linkToMyProfile</ns2:href>\n";
+        expected += "        <commentsCount>2</commentsCount>\n";
+        expected += "        <showInEditor>true</showInEditor>\n";
+	expected += "    </description>\n";
+        expected += "</registerResponse>\n";
+        assertEquals(expected, out.toString());
+
+        RegisterResponse rr = MDMarshaller.unmarshal(RegisterResponse.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertTrue(rr.isRegistered());
+        assertTrue(rr.isProfile());
+        assertEquals("myId", rr.getDescription().getId());
+    }
+
+    @Test
+    public void testRegisterSuccesComponent() throws Exception {
+        RegisterResponse resp = new RegisterResponse();
+        resp.setRegistered(true);
+        resp.setIsProfile(false);
+        resp.setIsInUserSpace(true);
+        resp.setDescription(getComponentDescription());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        MDMarshaller.marshal(resp, out);
+        String expected = "";
+        expected += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        expected += "<registerResponse isProfile=\"false\" isInUserSpace=\"true\" registered=\"true\" xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        expected += "    <errors/>\n";
+        expected += "    <description xsi:type=\"componentDescription\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
+        expected += "        <id>myId</id>\n";
+        expected += "        <description>myD</description>\n";
+        expected += "        <name>Name</name>\n";
+        expected += "        <registrationDate>myDate</registrationDate>\n";
+        expected += "        <creatorName>myC</creatorName>\n";
+        expected += "        <ns2:href>linkToMyProfile</ns2:href>\n";
+        expected += "        <groupName>imdi</groupName>\n";
+        expected += "        <commentsCount>2</commentsCount>\n";
+        expected += "    </description>\n";
+        expected += "</registerResponse>\n";
+        assertEquals(expected, out.toString());
+
+        RegisterResponse rr = MDMarshaller.unmarshal(RegisterResponse.class, new ByteArrayInputStream(expected.getBytes()), null);
+        assertTrue(rr.isRegistered());
+        assertFalse(rr.isProfile());
+        assertEquals("myId", rr.getDescription().getId());
+    }
+
+    private ComponentDescription getComponentDescription() {
+        ComponentDescription desc = new ComponentDescription();
+        desc.setName("Name");
+        desc.setId("myId");
+        desc.setGroupName("imdi");
+        desc.setCreatorName("myC");
+        desc.setDescription("myD");
+        desc.setRegistrationDate("myDate");
+        desc.setHref("linkToMyProfile");
+	desc.setCommentsCount(2);
+        return desc;
+    }
+
+    private ProfileDescription getProfileDescription() {
+        ProfileDescription desc = new ProfileDescription();
+        desc.setName("Name");
+        desc.setId("myId");
+        desc.setCreatorName("myC");
+        desc.setDescription("myD");
+        desc.setRegistrationDate("myDate");
+        desc.setHref("linkToMyProfile");
+	desc.setCommentsCount(2);
+        return desc;
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/CommentValidatorTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/CommentValidatorTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/CommentValidatorTest.java	(revision 1843)
@@ -0,0 +1,163 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * Test class for CommentValidator
+ * @author jean-charles FerriÃšres <jean-charles.ferrieres@mpi.nl>
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class CommentValidatorTest {
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+    }
+
+    /**
+     * Fully successfull comment validation
+     */
+    @Test
+    public void testValidateSucces() {
+	AbstractDescription description = ProfileDescription.createNewDescription();
+	String comContent = "";
+	comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	comContent += "    <comments>myCom</comments>\n";
+	comContent += "    <commentDate></commentDate>\n";
+	comContent += "     <profileDescriptionId>" + description.getId() + "</profileDescriptionId>";
+	comContent += "    <userId>0</userId>\n";
+	comContent += "    <id>1</id>\n";
+	comContent += "</comment>\n";
+	InputStream input = new ByteArrayInputStream(comContent.getBytes());
+	CommentValidator validator = new CommentValidator(input, description);
+	assertTrue(validator.validate());
+    }
+
+    /**
+     * Test the validation of comment with componentID
+     */
+    @Test
+    public void testValidateComponent() {
+	AbstractDescription desc = ComponentDescription.createNewDescription();
+	String comContent = "";
+	comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	comContent += "    <comments>myCom</comments>\n";
+	comContent += "    <commentDate></commentDate>\n";
+	comContent += "     <componentDescriptionId></componentDescriptionId>";
+	comContent += "    <userId>0</userId>\n";
+	comContent += "    <id>1</id>\n";
+	comContent += "</comment>\n";
+	InputStream input = new ByteArrayInputStream(comContent.getBytes());
+	CommentValidator validator = new CommentValidator(input, desc);
+	assertFalse(validator.validate());// missing componentId will return an error
+	assertEquals(validator.getErrorMessages().size(), 1);
+	assertTrue(validator.getErrorMessages().get(0).startsWith(CommentValidator.COMMENT_SPECIFICATION_ERROR));
+
+	String commentContent = "";
+	commentContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	commentContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	commentContent += "    <comments>myCom</comments>\n";
+	commentContent += "    <commentDate></commentDate>\n";
+	commentContent += "     <componentDescriptionId>" + desc.getId() + "</componentDescriptionId>";
+	commentContent += "    <userId>0</userId>\n";
+	commentContent += "    <id>1</id>\n";
+	commentContent += "</comment>\n";
+	input = new ByteArrayInputStream(commentContent.getBytes());
+	validator = new CommentValidator(input, desc);
+	assertTrue(validator.validate()); // componentId valid, validation complete
+    }
+
+    /***
+     * Test the validation of comment with profileId
+     */
+    @Test
+    public void testValidateProfile() {
+	AbstractDescription desc = ProfileDescription.createNewDescription();
+	String comContent = "";
+	comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	comContent += "    <comments>myCom</comments>\n";
+	comContent += "    <commentDate></commentDate>\n";
+	comContent += "     <profileDescriptionId></profileDescriptionId>";
+	comContent += "    <userId>0</userId>\n";
+	comContent += "    <id>1</id>\n";
+	comContent += "</comment>\n";
+	InputStream input = new ByteArrayInputStream(comContent.getBytes());
+	CommentValidator validator = new CommentValidator(input, desc);
+	assertFalse(validator.validate());// missing profileId will return an error
+	assertEquals(validator.getErrorMessages().size(), 1);
+	assertTrue(validator.getErrorMessages().get(0).startsWith(CommentValidator.COMMENT_SPECIFICATION_ERROR));
+
+	String commentContent = "";
+	commentContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	commentContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	commentContent += "    <comments>myCom</comments>\n";
+	commentContent += "    <commentDate></commentDate>\n";
+	commentContent += "     <profileDescriptionId>" + desc.getId() + "</profileDescriptionId>";
+	commentContent += "    <userId>0</userId>\n";
+	commentContent += "    <id>1</id>\n";
+	commentContent += "</comment>\n";
+	input = new ByteArrayInputStream(commentContent.getBytes());
+	validator = new CommentValidator(input, desc);
+	assertTrue(validator.validate()); // profileId valid, validation complete
+    }
+
+    /**
+     * Test the validation of comment with content comments
+     * @throws Exception 
+     */
+    @Test
+    public void testValidateNoCommentContent() throws Exception {
+	AbstractDescription desc = ProfileDescription.createNewDescription();
+	String commentContent = "";
+	commentContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	commentContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	commentContent += "    <comments></comments>\n";
+	commentContent += "    <commentDate></commentDate>\n";
+	commentContent += "     <profileDescriptionId>" + desc.getId() + "</profileDescriptionId>";
+	commentContent += "    <userId>0</userId>\n";
+	commentContent += "    <id>1</id>\n";
+	commentContent += "</comment>\n";
+	InputStream input = new ByteArrayInputStream(commentContent.getBytes());
+	CommentValidator validator = new CommentValidator(input, desc);
+	assertFalse(validator.validate()); // missing content will return an error
+	assertTrue(validator.getErrorMessages().get(0).startsWith(CommentValidator.COMMENT_SPECIFICATION_ERROR));
+
+	String comContent = "";
+	comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+	comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+	comContent += "    <comments>myCom</comments>\n";
+	comContent += "    <commentDate></commentDate>\n";
+	comContent += "     <profileDescriptionId>" + desc.getId() + "</profileDescriptionId>";
+	comContent += "    <userId>0</userId>\n";
+	comContent += "    <id>1</id>\n";
+	comContent += "</comment>\n";
+	input = new ByteArrayInputStream(comContent.getBytes());
+	validator = new CommentValidator(input, desc);
+	assertTrue(validator.validate());// content comments is fill in, validation complete
+
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTest.java	(revision 1843)
@@ -0,0 +1,1046 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryBeanFactory;
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.CommentResponse;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+import java.util.List;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.util.Assert;
+
+import static clarin.cmdi.componentregistry.rest.ComponentRegistryRestService.USERSPACE_PARAM;
+import static org.junit.Assert.*;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class ComponentRegistryRestServiceTest extends ComponentRegistryRestServiceTestCase {
+
+    @Autowired
+    private ComponentRegistryFactory componentRegistryFactory;
+    @Autowired
+    private ComponentRegistryBeanFactory componentRegistryBeanFactory;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    private ComponentRegistry testRegistry;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+	createUserRecord();
+	// Get public component registry
+	testRegistry = componentRegistryBeanFactory.getNewComponentRegistry();
+    }
+
+    @Override
+    protected String getApplicationContextFile() {
+	return "classpath:applicationContext.xml";
+    }
+
+    private ComponentRegistry getTestRegistry() {
+	return testRegistry;
+    }
+
+    private String expectedUserId(String principal) {
+	return getUserDao().getByPrincipalName(principal).getId().toString();
+    }
+
+    private void fillUp() throws Exception {
+	RegistryTestHelper.addProfile(getTestRegistry(), "profile2");
+	RegistryTestHelper.addProfile(getTestRegistry(), "profile1");
+	RegistryTestHelper.addComponent(getTestRegistry(), "component2");
+	RegistryTestHelper.addComponent(getTestRegistry(), "component1");
+	RegistryTestHelper.addComment(getTestRegistry(), "comment2", "clarin.eu:cr1:profile1", "JUnit@test.com");
+	Thread.sleep(1000); // wait so order becomes predictable
+	RegistryTestHelper.addComment(getTestRegistry(), "comment1", "clarin.eu:cr1:profile1", "JUnit@test.com");
+	Thread.sleep(1000); // wait so order becomes predictable
+	RegistryTestHelper.addComment(getTestRegistry(), "comment3", "clarin.eu:cr1:component1", "JUnit@test.com");
+	Thread.sleep(1000); // wait so order becomes predictable
+	RegistryTestHelper.addComment(getTestRegistry(), "comment4", "clarin.eu:cr1:component1", "JUnit@test.com");
+	Thread.sleep(1000); // wait so order becomes predictable
+    }
+
+    @Test
+    public void testGetRegisteredProfiles() throws Exception {
+	fillUp();
+	RegistryTestHelper.addProfile(getTestRegistry(), "PROFILE2");
+	List<ProfileDescription> response = getResource().path("/registry/profiles").accept(MediaType.APPLICATION_XML).get(
+		PROFILE_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	response = getResource().path("/registry/profiles").accept(MediaType.APPLICATION_JSON).get(PROFILE_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	assertEquals("profile1", response.get(0).getName());
+	assertEquals("PROFILE2", response.get(1).getName());
+	assertEquals("profile2", response.get(2).getName());
+    }
+
+    @Test
+    public void testGetRegisteredComponents() throws Exception {
+	fillUp();
+	RegistryTestHelper.addComponent(getTestRegistry(), "COMPONENT2");
+	List<ComponentDescription> response = getResource().path("/registry/components").accept(MediaType.APPLICATION_XML).get(
+		COMPONENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	response = getResource().path("/registry/components").accept(MediaType.APPLICATION_JSON).get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	assertEquals("component1", response.get(0).getName());
+	assertEquals("COMPONENT2", response.get(1).getName());
+	assertEquals("component2", response.get(2).getName());
+    }
+
+    @Test
+    public void testGetUserComponents() throws Exception {
+	fillUp();
+	List<ComponentDescription> response = getUserComponents();
+	assertEquals(0, response.size());
+	response = getAuthenticatedResource(getResource().path("/registry/components")).accept(MediaType.APPLICATION_JSON).get(
+		COMPONENT_LIST_GENERICTYPE);
+	assertEquals("Get public components", 2, response.size());
+	ClientResponse cResponse = getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true").accept(
+		MediaType.APPLICATION_JSON).get(ClientResponse.class);
+	assertEquals("Trying to get userspace without credentials", 500, cResponse.getStatus());
+    }
+
+    @Test
+    public void testGetRegisteredComponent() throws Exception {
+	fillUp();
+	CMDComponentSpec component = getResource().path("/registry/components/clarin.eu:cr1:component1").accept(MediaType.APPLICATION_JSON).get(CMDComponentSpec.class);
+	assertNotNull(component);
+	assertEquals("Access", component.getCMDComponent().get(0).getName());
+	component = getResource().path("/registry/components/clarin.eu:cr1:component2").accept(MediaType.APPLICATION_XML).get(
+		CMDComponentSpec.class);
+	assertNotNull(component);
+	assertEquals("Access", component.getCMDComponent().get(0).getName());
+
+	assertEquals("clarin.eu:cr1:component2", component.getHeader().getID());
+	assertEquals("component2", component.getHeader().getName());
+	assertEquals("Test Description", component.getHeader().getDescription());
+    }
+
+    @Test
+    public void testGetRegisteredCommentsInProfile() throws Exception {
+	fillUp();
+	RegistryTestHelper.addComment(getTestRegistry(), "COMMENT1", "clarin.eu:cr1:profile1", "JUnit@test.com");
+	List<Comment> response = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments/").accept(MediaType.APPLICATION_XML).
+		get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	response = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments").accept(MediaType.APPLICATION_JSON).get(
+		COMMENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	assertEquals("comment2", response.get(0).getComment());
+	assertEquals("comment1", response.get(1).getComment());
+	assertEquals("COMMENT1", response.get(2).getComment());
+
+	assertEquals("Database test user", response.get(0).getUserName());
+    }
+
+    @Test
+    public void testGetRegisteredCommentsInComponent() throws Exception {
+	fillUp();
+	RegistryTestHelper.addComment(getTestRegistry(), "COMMENT2", "clarin.eu:cr1:component1", "JUnit@test.com");
+	List<Comment> response = getResource().path("/registry/components/clarin.eu:cr1:component1/comments/").accept(MediaType.APPLICATION_XML).
+		get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	response = getResource().path("/registry/components/clarin.eu:cr1:component1/comments").accept(MediaType.APPLICATION_JSON).get(
+		COMMENT_LIST_GENERICTYPE);
+	assertEquals(3, response.size());
+	assertEquals("comment3", response.get(0).getComment());
+	assertEquals("comment4", response.get(1).getComment());
+	assertEquals("COMMENT2", response.get(2).getComment());
+
+	assertEquals("Database test user", response.get(0).getUserName());
+    }
+
+    @Test
+    public void testGetSpecifiedCommentInComponent() throws Exception {
+	fillUp();
+	Comment comment = getResource().path("/registry/components/clarin.eu:cr1:component1/comments/2").accept(MediaType.APPLICATION_JSON).get(Comment.class);
+	assertNotNull(comment);
+	assertEquals("comment3", comment.getComment());
+	assertEquals("2", comment.getId());
+	comment = getResource().path("/registry/components/clarin.eu:cr1:component1/comments/3").accept(MediaType.APPLICATION_JSON).get(Comment.class);
+	assertNotNull(comment);
+	assertEquals("comment4", comment.getComment());
+	assertEquals("3", comment.getId());
+	assertEquals("clarin.eu:cr1:component1", comment.getComponentDescriptionId());
+    }
+
+    @Test
+    public void testGetSpecifiedCommentInProfile() throws Exception {
+	fillUp();
+	Comment comment = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments/0").accept(MediaType.APPLICATION_JSON).get(Comment.class);
+	assertNotNull(comment);
+	assertEquals("comment2", comment.getComment());
+	assertEquals("0", comment.getId());
+	comment = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments/1").accept(MediaType.APPLICATION_JSON).get(Comment.class);
+	assertNotNull(comment);
+	assertEquals("comment1", comment.getComment());
+	assertEquals("1", comment.getId());
+	assertEquals("clarin.eu:cr1:profile1", comment.getProfileDescriptionId());
+    }
+
+    @Test
+    public void testDeleteCommentFromComponent() throws Exception {
+	fillUp();
+	List<Comment> comments = getResource().path("/registry/components/clarin.eu:cr1:component1/comments").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(2, comments.size());
+	Comment aComment = getResource().path("/registry/components/clarin.eu:cr1:component1/comments/2").get(Comment.class);
+	assertNotNull(aComment);
+
+	// Try to delete from other component
+	ClientResponse response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component2/comments/2").delete(ClientResponse.class);
+	assertEquals(500, response.getStatus());
+	// Delete from correct component
+	response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component1/comments/2").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	comments = getResource().path("/registry/components/clarin.eu:cr1:component1/comments/").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(1, comments.size());
+
+	response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component1/comments/3").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	comments = getResource().path("/registry/components/clarin.eu:cr1:component1/comments").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(0, comments.size());
+    }
+
+    @Test
+    public void testDeleteCommentFromProfile() throws Exception {
+	fillUp();
+	List<Comment> comments = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(2, comments.size());
+	Comment aComment = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments/0").get(Comment.class);
+	assertNotNull(aComment);
+
+	// Try to delete from other profile
+	ClientResponse response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile2/comments/0").delete(ClientResponse.class);
+	assertEquals(500, response.getStatus());
+	// Delete from correct profile
+	response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile1/comments/0").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	comments = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments/").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(1, comments.size());
+
+	response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile1/comments/1").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	comments = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments").get(COMMENT_LIST_GENERICTYPE);
+	assertEquals(0, comments.size());
+    }
+
+    @Test
+    public void testDeleteRegisteredComponent() throws Exception {
+	fillUp();
+	List<ComponentDescription> components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(2, components.size());
+	CMDComponentSpec profile = getResource().path("/registry/components/clarin.eu:cr1:component1").get(CMDComponentSpec.class);
+	assertNotNull(profile);
+	ClientResponse response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component1").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(1, components.size());
+
+	response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component2").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(0, components.size());
+
+	response = getAuthenticatedResource("/registry/components/clarin.eu:cr1:component1").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+    }
+
+    @Test
+    public void testDeleteRegisteredComponentStillUsed() throws Exception {
+	String content = "";
+	content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"XXX\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	content += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc1 = RegistryTestHelper.addComponent(getTestRegistry(), "XXX1", content);
+
+	content = "";
+	content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"YYY\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+	content += "        <CMD_Component ComponentId=\"" + compDesc1.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+	content += "        </CMD_Component>\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc2 = RegistryTestHelper.addComponent(getTestRegistry(), "YYY1", content);
+
+	content = "";
+	content += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"ZZZ\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+	content += "        <CMD_Component ComponentId=\"" + compDesc1.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+	content += "        </CMD_Component>\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+	ProfileDescription profile = RegistryTestHelper.addProfile(getTestRegistry(), "TestProfile3", content);
+
+	List<ComponentDescription> components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(2, components.size());
+
+	ClientResponse response = getAuthenticatedResource("/registry/components/" + compDesc1.getId()).delete(ClientResponse.class);
+	assertEquals(Status.FORBIDDEN.getStatusCode(), response.getStatus());
+	assertEquals(
+		"Still used by the following profiles: \n - TestProfile3\nStill used by the following components: \n - YYY1\nTry to change above mentioned references first.",
+		response.getEntity(String.class));
+
+	components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(2, components.size());
+
+	response = getAuthenticatedResource("/registry/profiles/" + profile.getId()).delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+	response = getAuthenticatedResource("/registry/components/" + compDesc2.getId()).delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+	response = getAuthenticatedResource("/registry/components/" + compDesc1.getId()).delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+	components = getResource().path("/registry/components").get(COMPONENT_LIST_GENERICTYPE);
+	assertEquals(0, components.size());
+    }
+
+    @Test
+    public void testGetRegisteredProfile() throws Exception {
+	fillUp();
+	CMDComponentSpec profile = getResource().path("/registry/profiles/clarin.eu:cr1:profile1").accept(MediaType.APPLICATION_JSON).get(
+		CMDComponentSpec.class);
+	assertNotNull(profile);
+	assertEquals("Actor", profile.getCMDComponent().get(0).getName());
+	profile = getResource().path("/registry/profiles/clarin.eu:cr1:profile2").accept(MediaType.APPLICATION_XML).get(
+		CMDComponentSpec.class);
+	assertNotNull(profile);
+	assertEquals("Actor", profile.getCMDComponent().get(0).getName());
+
+	assertEquals("clarin.eu:cr1:profile2", profile.getHeader().getID());
+	assertEquals("profile2", profile.getHeader().getName());
+	assertEquals("Test Description", profile.getHeader().getDescription());
+
+	try {
+	    profile = getResource().path("/registry/profiles/clarin.eu:cr1:profileXXXX").accept(MediaType.APPLICATION_XML).get(
+		    CMDComponentSpec.class);
+	    fail("Exception should have been thrown resource does not exist, HttpStatusCode 204");
+	} catch (UniformInterfaceException e) {
+	    assertEquals(204, e.getResponse().getStatus());
+	}
+    }
+
+    @Test
+    public void testGetRegisteredProfileRawData() throws Exception {
+	fillUp();
+	String profile = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/xsd").accept(MediaType.TEXT_XML).get(String.class).trim();
+	assertTrue(profile.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema"));
+	assertTrue(profile.endsWith("</xs:schema>"));
+
+	profile = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/xml").accept(MediaType.TEXT_XML).get(String.class).trim();
+	assertTrue(profile.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<CMD_ComponentSpec"));
+	assertTrue(profile.endsWith("</CMD_ComponentSpec>"));
+	assertTrue(profile.contains("xsi:schemaLocation"));
+
+	try {
+	    getResource().path("/registry/components/clarin.eu:cr1:component1/xsl").accept(MediaType.TEXT_XML).get(String.class);
+	    fail("Should have thrown exception, unsupported path parameter");
+	} catch (UniformInterfaceException e) {//server error
+	}
+    }
+
+    @Test
+    public void testPrivateProfileXsd() throws Exception {
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getTestProfileContent());
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isProfile());
+	assertEquals(1, getUserProfiles().size());
+	AbstractDescription desc = response.getDescription();
+	String profile = getResource().path("/registry/profiles/" + desc.getId() + "/xsd").accept(MediaType.TEXT_XML).get(String.class).trim();
+	assertTrue(profile.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema"));
+	assertTrue(profile.endsWith("</xs:schema>"));
+    }
+
+    @Test
+    public void testPrivateComponentXsd() throws Exception {
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getComponentTestContent());
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertFalse(response.isProfile());
+	assertEquals(1, getUserComponents().size());
+	AbstractDescription desc = response.getDescription();
+	String profile = getResource().path("/registry/components/" + desc.getId() + "/xsd").accept(MediaType.TEXT_XML).get(String.class).trim();
+	assertTrue(profile.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema"));
+	assertTrue(profile.endsWith("</xs:schema>"));
+    }
+
+    @Test
+    public void testDeleteRegisteredProfile() throws Exception {
+	fillUp();
+	List<ProfileDescription> profiles = getResource().path("/registry/profiles").get(PROFILE_LIST_GENERICTYPE);
+	assertEquals(2, profiles.size());
+	CMDComponentSpec profile = getResource().path("/registry/profiles/clarin.eu:cr1:profile1").get(CMDComponentSpec.class);
+	assertNotNull(profile);
+
+	ClientResponse response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile1").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	profiles = getResource().path("/registry/profiles").get(PROFILE_LIST_GENERICTYPE);
+	assertEquals(1, profiles.size());
+
+	response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile2").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+
+	profiles = getResource().path("/registry/profiles").get(PROFILE_LIST_GENERICTYPE);
+	assertEquals(0, profiles.size());
+
+	response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile1").delete(ClientResponse.class);
+	assertEquals(200, response.getStatus());
+    }
+
+    @Test
+    public void testGetRegisteredComponentRawData() throws Exception {
+	fillUp();
+	String component = getResource().path("/registry/components/clarin.eu:cr1:component1/xsd").accept(MediaType.TEXT_XML).get(
+		String.class).trim();
+	assertTrue(component.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema"));
+	assertTrue(component.endsWith("</xs:schema>"));
+
+	component = getResource().path("/registry/components/clarin.eu:cr1:component1/xml").accept(MediaType.TEXT_XML).get(String.class).trim();
+	assertTrue(component.startsWith("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<CMD_ComponentSpec"));
+	assertTrue(component.endsWith("</CMD_ComponentSpec>"));
+	assertTrue(component.contains("xsi:schemaLocation"));
+
+	try {
+	    getResource().path("/registry/components/clarin.eu:cr1:component1/jpg").accept(MediaType.TEXT_XML).get(String.class);
+	    fail("Should have thrown exception, unsopported path parameter");
+	} catch (UniformInterfaceException e) {
+	}
+    }
+
+    @Test
+    public void testRegisterProfile() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getTestProfileContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "ProfileTest1");
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "TestDomain");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, "My Test Profile");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "My Test Group");
+	RegisterResponse response = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertTrue(response.isProfile());
+	assertFalse(response.isInUserSpace());
+	ProfileDescription profileDesc = (ProfileDescription) response.getDescription();
+	assertNotNull(profileDesc);
+	assertEquals("ProfileTest1", profileDesc.getName());
+	assertEquals("My Test Profile", profileDesc.getDescription());
+	assertEquals("TestDomain", profileDesc.getDomainName());
+	assertEquals("My Test Group", profileDesc.getGroupName());
+	assertEquals(expectedUserId("JUnit@test.com"), profileDesc.getUserId());
+	assertEquals("Database test user", profileDesc.getCreatorName());
+	assertTrue(profileDesc.getId().startsWith(ComponentRegistry.REGISTRY_ID + "p_"));
+	assertNotNull(profileDesc.getRegistrationDate());
+	assertEquals("http://localhost:9998/registry/profiles/" + profileDesc.getId(), profileDesc.getHref());
+    }
+
+    @Test
+    public void testPublishProfile() throws Exception {
+	assertEquals("user registered profiles", 0, getUserProfiles().size());
+	assertEquals("public registered profiles", 0, getPublicProfiles().size());
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getTestProfileContent(), "Unpublished");
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isProfile());
+	AbstractDescription desc = response.getDescription();
+	assertEquals("Unpublished", desc.getDescription());
+	assertEquals(1, getUserProfiles().size());
+	assertEquals(0, getPublicProfiles().size());
+	form = createFormData(RegistryTestHelper.getTestProfileContent("publishedName"), "Published");
+	response = getAuthenticatedResource(getResource().path("/registry/profiles/" + desc.getId() + "/publish")).type(
+		MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+
+	assertEquals(0, getUserProfiles().size());
+	List<ProfileDescription> profiles = getPublicProfiles();
+	assertEquals(1, profiles.size());
+	ProfileDescription profileDescription = profiles.get(0);
+	assertNotNull(profileDescription.getId());
+	assertEquals(desc.getId(), profileDescription.getId());
+	assertEquals("http://localhost:9998/registry/profiles/" + desc.getId(), profileDescription.getHref());
+	assertEquals("Published", profileDescription.getDescription());
+	CMDComponentSpec spec = getPublicSpec(profileDescription);
+	assertEquals("publishedName", spec.getCMDComponent().get(0).getName());
+    }
+
+    private CMDComponentSpec getPublicSpec(AbstractDescription desc) {
+	if (desc.isProfile()) {
+	    return getResource().path("/registry/profiles/" + desc.getId()).get(CMDComponentSpec.class);
+	} else {
+	    return getResource().path("/registry/components/" + desc.getId()).get(CMDComponentSpec.class);
+	}
+    }
+
+    @Test
+    public void testPublishComponent() throws Exception {
+	assertEquals(0, getUserComponents().size());
+	assertEquals(0, getPublicComponents().size());
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getComponentTestContent(), "Unpublished");
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertFalse(response.isProfile());
+	AbstractDescription desc = response.getDescription();
+	assertEquals("Unpublished", desc.getDescription());
+	assertEquals(1, getUserComponents().size());
+	assertEquals(0, getPublicComponents().size());
+	form = createFormData(RegistryTestHelper.getComponentTestContent("publishedName"), "Published");
+	response = getAuthenticatedResource(getResource().path("/registry/components/" + desc.getId() + "/publish")).type(
+		MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+
+	assertEquals(0, getUserComponents().size());
+	List<ComponentDescription> components = getPublicComponents();
+	assertEquals(1, components.size());
+	ComponentDescription componentDescription = components.get(0);
+	assertNotNull(componentDescription.getId());
+	assertEquals(desc.getId(), componentDescription.getId());
+	assertEquals("http://localhost:9998/registry/components/" + desc.getId(), componentDescription.getHref());
+	assertEquals("Published", componentDescription.getDescription());
+	CMDComponentSpec spec = getPublicSpec(componentDescription);
+	assertEquals("publishedName", spec.getCMDComponent().get(0).getName());
+    }
+
+    @Test
+    public void testRegisterUserspaceProfile() throws Exception {
+	List<ProfileDescription> profiles = getUserProfiles();
+	assertEquals("user registered profiles", 0, profiles.size());
+	assertEquals("public registered profiles", 0, getPublicProfiles().size());
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getTestProfileContent());
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	ProfileDescription profileDesc = (ProfileDescription) response.getDescription();
+	assertNotNull(profileDesc);
+	assertEquals("Test1", profileDesc.getName());
+	assertEquals("My Test", profileDesc.getDescription());
+	assertEquals(expectedUserId("JUnit@test.com"), profileDesc.getUserId());
+	assertEquals("Database test user", profileDesc.getCreatorName());
+	assertTrue(profileDesc.getId().startsWith(ComponentRegistry.REGISTRY_ID + "p_"));
+	assertNotNull(profileDesc.getRegistrationDate());
+	assertEquals("http://localhost:9998/registry/profiles/" + profileDesc.getId() + "?userspace=true", profileDesc.getHref());
+
+	profiles = getUserProfiles();
+	assertEquals(1, profiles.size());
+	assertEquals(0, getPublicProfiles().size());
+
+	//Try to post unauthenticated
+	ClientResponse cResponse = getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true").type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(401, cResponse.getStatus());
+
+	// Try get from public registry
+	cResponse = getResource().path("/registry/profiles/" + profileDesc.getId()).accept(MediaType.APPLICATION_XML).get(
+		ClientResponse.class);
+	// Should return 204 = no content
+	assertEquals(204, cResponse.getStatus());
+	CMDComponentSpec spec = getAuthenticatedResource(
+		getResource().path("/registry/profiles/" + profileDesc.getId()).queryParam(USERSPACE_PARAM, "true")).accept(
+		MediaType.APPLICATION_XML).get(CMDComponentSpec.class);
+	assertNotNull(spec);
+
+	cResponse = getResource().path("/registry/profiles/" + profileDesc.getId() + "/xsd").accept(MediaType.TEXT_XML).get(
+		ClientResponse.class);
+	assertEquals(200, cResponse.getStatus());
+	String profile = cResponse.getEntity(String.class);
+	assertTrue(profile.length() > 0);
+
+	profile = getAuthenticatedResource(getResource().path("/registry/profiles/" + profileDesc.getId() + "/xml")).accept(
+		MediaType.TEXT_XML).get(String.class);
+	assertTrue(profile.length() > 0);
+
+	cResponse = getAuthenticatedResource(
+		getResource().path("/registry/profiles/" + profileDesc.getId()).queryParam(USERSPACE_PARAM, "true")).delete(
+		ClientResponse.class);
+	assertEquals(200, cResponse.getStatus());
+
+	profiles = getUserProfiles();
+	assertEquals(0, profiles.size());
+    }
+
+    private List<ProfileDescription> getPublicProfiles() {
+	return getAuthenticatedResource("/registry/profiles").accept(MediaType.APPLICATION_XML).get(PROFILE_LIST_GENERICTYPE);
+    }
+
+    private List<ProfileDescription> getUserProfiles() {
+	return getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).accept(
+		MediaType.APPLICATION_XML).get(PROFILE_LIST_GENERICTYPE);
+    }
+
+    private FormDataMultiPart createFormData(Object content) {
+	return createFormData(content, "My Test");
+    }
+
+    private FormDataMultiPart createFormData(Object content, String description) {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, content, MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "Test1");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, description);
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "My domain");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "TestGroup");
+	return form;
+    }
+
+    @Test
+    public void testRegisterWithUserComponents() throws Exception {
+	ComponentRegistry userRegistry = componentRegistryFactory.getComponentRegistry(true, DummyPrincipal.DUMMY_CREDENTIALS);
+	String content = "";
+	content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"XXX\" CardinalityMin=\"1\" CardinalityMax=\"10\">\n";
+	content += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+	ComponentDescription compDesc1 = RegistryTestHelper.addComponent(userRegistry, "XXX1", content);
+
+	content = "";
+	content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"YYY\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+	content += "        <CMD_Component ComponentId=\"" + compDesc1.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+	content += "        </CMD_Component>\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+	FormDataMultiPart form = createFormData(content);
+	RegisterResponse response = getAuthenticatedResource("/registry/components").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertFalse(response.isRegistered());
+	assertEquals(1, response.getErrors().size());
+	assertEquals("referenced component cannot be found in the published components: " + compDesc1.getName() + " (" + compDesc1.getId()
+		+ ")", response.getErrors().get(0));
+
+	response = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(
+		MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isRegistered());
+	ComponentDescription comp2 = (ComponentDescription) response.getDescription();
+
+	content = "";
+	content += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header/>\n";
+	content += "    <CMD_Component name=\"ZZZ\" CardinalityMin=\"1\" CardinalityMax=\"unbounded\">\n";
+	content += "        <CMD_Component ComponentId=\"" + comp2.getId() + "\" CardinalityMin=\"0\" CardinalityMax=\"99\">\n";
+	content += "        </CMD_Component>\n";
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+
+	form = createFormData(content);
+	response = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertFalse(response.isRegistered());
+	assertEquals(1, response.getErrors().size());
+	assertEquals("referenced component cannot be found in the published components: " + comp2.getName() + " (" + comp2.getId() + ")",
+		response.getErrors().get(0));
+
+	response = getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).type(
+		MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isRegistered());
+    }
+
+    @Test
+    public void testRegisterUserspaceComponent() throws Exception {
+	List<ComponentDescription> components = getUserComponents();
+	assertEquals("user registered components", 0, components.size());
+	assertEquals("public registered components", 0, getPublicComponents().size());
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getComponentTestContent());
+
+	RegisterResponse response = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(RegisterResponse.class, form);
+	assertTrue(response.isRegistered());
+	assertFalse(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	ComponentDescription desc = (ComponentDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("Test1", desc.getName());
+	assertEquals("My Test", desc.getDescription());
+	assertEquals(expectedUserId("JUnit@test.com"), desc.getUserId());
+	assertEquals("Database test user", desc.getCreatorName());
+	assertEquals("TestGroup", desc.getGroupName());
+	assertTrue(desc.getId().startsWith(ComponentRegistry.REGISTRY_ID + "c_"));
+	assertNotNull(desc.getRegistrationDate());
+	String url = getResource().getUriBuilder().build().toString();
+	assertEquals(url + "registry/components/" + desc.getId() + "?userspace=true", desc.getHref());
+
+	components = getUserComponents();
+	assertEquals(1, components.size());
+	assertEquals(0, getPublicComponents().size());
+
+	//Try to post unauthenticated
+	ClientResponse cResponse = getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true").type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(401, cResponse.getStatus());
+
+	// Try to get from public registry
+	cResponse = getResource().path("/registry/components/" + desc.getId()).accept(MediaType.APPLICATION_XML).get(
+		ClientResponse.class);
+	// Should return 204 = no content
+	assertEquals(204, cResponse.getStatus());
+	CMDComponentSpec spec = getUserComponent(desc);
+	assertNotNull(spec);
+
+	cResponse = getResource().path("/registry/components/" + desc.getId() + "/xsd").accept(MediaType.TEXT_XML).get(ClientResponse.class);
+	assertEquals(200, cResponse.getStatus());
+	String result = cResponse.getEntity(String.class);
+	assertTrue(result.length() > 0);
+
+	result = getAuthenticatedResource(getResource().path("/registry/components/" + desc.getId() + "/xml")).accept(MediaType.TEXT_XML).get(String.class);
+	assertTrue(result.length() > 0);
+
+	cResponse = getAuthenticatedResource(getResource().path("/registry/components/" + desc.getId()).queryParam(USERSPACE_PARAM, "true")).delete(ClientResponse.class);
+	assertEquals(200, cResponse.getStatus());
+
+	components = getUserComponents();
+	assertEquals(0, components.size());
+    }
+
+    @Test
+    public void testCreateComponentWithRecursion() throws Exception {
+	// Create new componet
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getComponentTestContent());
+	ClientResponse cResponse = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	RegisterResponse response = cResponse.getEntity(RegisterResponse.class);
+	assertTrue(response.isRegistered());
+	ComponentDescription desc = (ComponentDescription) response.getDescription();
+
+	// Re-define with self-recursion
+	String compContent = "";
+	compContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	compContent += "\n";
+	compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	compContent += "    xsi:noNamespaceSchemaLocation=\"../../general-component-schema.xsd\">\n";
+	compContent += "    \n";
+	compContent += "    <Header/>\n";
+	compContent += "    \n";
+	compContent += "    <CMD_Component name=\"Nested\" CardinalityMin=\"1\" CardinalityMax=\"1\">\n";
+	compContent += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+	compContent += "        <CMD_Component ComponentId=\"" + desc.getId() + "\" name=\"Recursive\" CardinalityMin=\"1\" CardinalityMax=\"1\" />\n";
+	compContent += "    </CMD_Component>\n";
+	compContent += "\n";
+	compContent += "</CMD_ComponentSpec>\n";
+
+	// Update component
+	form = createFormData(RegistryTestHelper.getComponentContent(compContent), "UPDATE DESCRIPTION!");
+	cResponse = getAuthenticatedResource(
+		getResource().path("/registry/components/" + desc.getId() + "/update").queryParam(USERSPACE_PARAM, "true")).type(
+		MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	response = cResponse.getEntity(RegisterResponse.class);
+	assertFalse("Recursive definition should fail", response.isRegistered());
+	assertEquals("There should be an error message for the recursion", 1, response.getErrors().size());
+	assertTrue("There error message should specify the point of recursion", response.getErrors().get(0).contains("already contains " + desc.getId()));
+
+    }
+
+    @Test
+    public void testUpdateComponent() throws Exception {
+	List<ComponentDescription> components = getUserComponents();
+	assertEquals("user registered components", 0, components.size());
+	assertEquals("public registered components", 0, getPublicComponents().size());
+
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getComponentTestContent());
+	ClientResponse cResponse = getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	RegisterResponse response = cResponse.getEntity(RegisterResponse.class);
+	assertTrue(response.isRegistered());
+	assertFalse(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	ComponentDescription desc = (ComponentDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("Test1", desc.getName());
+	assertEquals("My Test", desc.getDescription());
+	Date firstDate = AbstractDescription.getDate(desc.getRegistrationDate());
+	CMDComponentSpec spec = getUserComponent(desc);
+	assertNotNull(spec);
+	assertEquals("Access", spec.getCMDComponent().get(0).getName());
+	components = getUserComponents();
+	assertEquals(1, components.size());
+	assertEquals(0, getPublicComponents().size());
+
+	//Now update
+	form = createFormData(RegistryTestHelper.getComponentTestContent("TESTNAME"), "UPDATE DESCRIPTION!");
+	cResponse = getAuthenticatedResource(
+		getResource().path("/registry/components/" + desc.getId() + "/update").queryParam(USERSPACE_PARAM, "true")).type(
+		MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	response = cResponse.getEntity(RegisterResponse.class);
+	assertTrue(response.isRegistered());
+	assertFalse(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	desc = (ComponentDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("Test1", desc.getName());
+	assertEquals("UPDATE DESCRIPTION!", desc.getDescription());
+	Date secondDate = AbstractDescription.getDate(desc.getRegistrationDate());
+	assertTrue(firstDate.before(secondDate) || firstDate.equals(secondDate));
+
+	spec = getUserComponent(desc);
+	assertNotNull(spec);
+	assertEquals("TESTNAME", spec.getCMDComponent().get(0).getName());
+	components = getUserComponents();
+	assertEquals(1, components.size());
+	assertEquals(0, getPublicComponents().size());
+    }
+
+    @Test
+    public void testUpdateProfile() throws Exception {
+	List<ProfileDescription> profiles = getUserProfiles();
+	assertEquals(0, profiles.size());
+	assertEquals(0, getPublicProfiles().size());
+
+	FormDataMultiPart form = createFormData(RegistryTestHelper.getTestProfileContent());
+	ClientResponse cResponse = getAuthenticatedResource(getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, "true")).type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	RegisterResponse response = cResponse.getEntity(RegisterResponse.class);
+	assertTrue(response.isRegistered());
+	assertTrue(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	ProfileDescription desc = (ProfileDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("Test1", desc.getName());
+	assertEquals("My Test", desc.getDescription());
+	assertEquals("TestGroup", desc.getGroupName());
+	Date firstDate = AbstractDescription.getDate(desc.getRegistrationDate());
+	CMDComponentSpec spec = getUserProfile(desc);
+	assertNotNull(spec);
+	assertEquals("Actor", spec.getCMDComponent().get(0).getName());
+	profiles = getUserProfiles();
+	assertEquals(1, profiles.size());
+	assertEquals(0, getPublicComponents().size());
+
+	//Now update
+	form = createFormData(RegistryTestHelper.getTestProfileContent("TESTNAME"), "UPDATE DESCRIPTION!");
+	cResponse = getAuthenticatedResource(
+		getResource().path("/registry/profiles/" + desc.getId() + "/update").queryParam(USERSPACE_PARAM, "true")).type(
+		MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, form);
+	assertEquals(ClientResponse.Status.OK.getStatusCode(), cResponse.getStatus());
+	response = cResponse.getEntity(RegisterResponse.class);
+	assertTrue(response.isRegistered());
+	assertTrue(response.isProfile());
+	assertTrue(response.isInUserSpace());
+	desc = (ProfileDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("Test1", desc.getName());
+	assertEquals("UPDATE DESCRIPTION!", desc.getDescription());
+	Date secondDate = AbstractDescription.getDate(desc.getRegistrationDate());
+	assertTrue(firstDate.before(secondDate) || firstDate.equals(secondDate));
+
+	spec = getUserProfile(desc);
+	assertNotNull(spec);
+	assertEquals("TESTNAME", spec.getCMDComponent().get(0).getName());
+	profiles = getUserProfiles();
+	assertEquals(1, profiles.size());
+	assertEquals(0, getPublicComponents().size());
+    }
+
+    private CMDComponentSpec getUserComponent(ComponentDescription desc) {
+	return getAuthenticatedResource(getResource().path("/registry/components/" + desc.getId()).queryParam(USERSPACE_PARAM, "true")).accept(MediaType.APPLICATION_XML).get(CMDComponentSpec.class);
+    }
+
+    private CMDComponentSpec getUserProfile(ProfileDescription desc) {
+	return getAuthenticatedResource(getResource().path("/registry/profiles/" + desc.getId()).queryParam(USERSPACE_PARAM, "true")).accept(MediaType.APPLICATION_XML).get(CMDComponentSpec.class);
+    }
+
+    private List<ComponentDescription> getPublicComponents() {
+	return getAuthenticatedResource("/registry/components").accept(MediaType.APPLICATION_XML).get(COMPONENT_LIST_GENERICTYPE);
+    }
+
+    private List<ComponentDescription> getUserComponents() {
+	return getAuthenticatedResource(getResource().path("/registry/components").queryParam(USERSPACE_PARAM, "true")).accept(
+		MediaType.APPLICATION_XML).get(COMPONENT_LIST_GENERICTYPE);
+    }
+
+    @Test
+    public void testRegisterComponent() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getComponentTestContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "ComponentTest1");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, "My Test Component");
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "TestDomain");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "TestGroup");
+	RegisterResponse response = getAuthenticatedResource("/registry/components").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertTrue(response.isRegistered());
+	assertFalse(response.isProfile());
+	assertFalse(response.isInUserSpace());
+	ComponentDescription desc = (ComponentDescription) response.getDescription();
+	assertNotNull(desc);
+	assertEquals("ComponentTest1", desc.getName());
+	assertEquals("My Test Component", desc.getDescription());
+	assertEquals(expectedUserId("JUnit@test.com"), desc.getUserId());
+	assertEquals("Database test user", desc.getCreatorName());
+	assertEquals("TestGroup", desc.getGroupName());
+	assertEquals("TestDomain", desc.getDomainName());
+	assertTrue(desc.getId().startsWith(ComponentRegistry.REGISTRY_ID + "c_"));
+	assertNotNull(desc.getRegistrationDate());
+	String url = getResource().getUriBuilder().build().toString();
+	assertEquals(url + "registry/components/" + desc.getId(), desc.getHref());
+    }
+
+    @Test
+    public void testRegisterComment() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getCommentTestContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	fillUp();
+	CommentResponse response = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile1/comments").type(MediaType.MULTIPART_FORM_DATA).post(
+		CommentResponse.class, form);
+	assertTrue(response.isRegistered());
+	assertFalse(response.isInUserSpace());
+	Comment comment = response.getComment();
+	assertNotNull(comment);
+	assertEquals("Actual", comment.getComment());
+	assertEquals("Database test user", comment.getUserName());
+	Assert.hasText(comment.getCommentDate());
+	Assert.hasText(comment.getId());
+
+	// User id should not be serialized!
+	assertEquals(null, comment.getUserId());
+    }
+
+    @Test
+    public void testRegisterCommentToNonExistent() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getCommentTestContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	fillUp();
+	ClientResponse cResponse = getAuthenticatedResource("/registry/profiles/clarin.eu:cr1:profile99/comments").type(MediaType.MULTIPART_FORM_DATA).post(
+		ClientResponse.class, form);
+	assertEquals(500, cResponse.getStatus());
+    }
+
+    @Test
+    public void testRegisterCommentUnauthenticated() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getCommentTestContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	fillUp();
+	ClientResponse cResponse = getResource().path("/registry/profiles/clarin.eu:cr1:profile1/comments").type(MediaType.MULTIPART_FORM_DATA).post(
+		ClientResponse.class, form);
+	assertEquals(401, cResponse.getStatus());
+    }
+
+    @Test
+    public void testRegisterProfileInvalidData() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	String notAValidProfile = "<CMD_ComponentSpec> </CMD_ComponentSpec>";
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, new ByteArrayInputStream(notAValidProfile.getBytes()),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "ProfileTest1");
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "Domain");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "Group");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, "My Test Profile");
+	RegisterResponse postResponse = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertTrue(postResponse.isProfile());
+	assertFalse(postResponse.isRegistered());
+	assertEquals(1, postResponse.getErrors().size());
+	assertTrue(postResponse.getErrors().get(0).contains("isProfile"));
+    }
+
+    /**
+     * Two elements on the same level with the same name violates schematron rule, and should fail validation
+     * @throws Exception 
+     */
+    @Test
+    public void testRegisterInvalidProfile() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component name=\"ProfileTest1\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	profileContent += "        <CMD_Element name=\"Age\">\n";
+	profileContent += "            <ValueScheme>\n";
+	profileContent += "                <pattern>[23][0-9]</pattern>\n";
+	profileContent += "            </ValueScheme>\n";
+	profileContent += "        </CMD_Element>\n";
+	profileContent += "        <CMD_Element name=\"Age\">\n";
+	profileContent += "            <ValueScheme>\n";
+	profileContent += "                <pattern>[23][0-9]</pattern>\n";
+	profileContent += "            </ValueScheme>\n";
+	profileContent += "        </CMD_Element>\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getComponentContent(profileContent),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "ProfileTest1");
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "TestDomain");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, "My Test Profile");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "My Test Group");
+	RegisterResponse response = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertFalse("Subsequent elements should not be allowed to have the same name", response.isRegistered());
+	assertTrue(response.getErrors().get(0).contains(MDValidator.PARSE_ERROR));
+    }
+
+    @Test
+    public void testRegisterProfileInvalidDescriptionAndContent() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	profileContent += "<CMD_ComponentSpec> \n"; //No isProfile attribute
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component name=\"Actor\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	profileContent += "        <AttributeList>\n";
+	profileContent += "            <Attribute>\n";
+	profileContent += "                <Name>Name</Name>\n";
+	profileContent += "                <Type>string</Type>\n";
+	profileContent += "            </Attribute>\n";
+	profileContent += "        </AttributeList>\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+	form.field("data", new ByteArrayInputStream(profileContent.getBytes()), MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field("name", "");//Empty name so invalid
+	form.field("description", "My Test Profile");
+	RegisterResponse response = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertFalse(response.isRegistered());
+	assertEquals(2, response.getErrors().size());
+	assertNotNull(response.getErrors().get(0));
+	assertEquals(MDValidator.PARSE_ERROR, response.getErrors().get(1).substring(0, MDValidator.PARSE_ERROR.length()));
+    }
+
+    @Test
+    public void testRegisterComponentAsProfile() throws Exception {
+	FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, RegistryTestHelper.getComponentTestContent(),
+		MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, "t");
+	form.field(ComponentRegistryRestService.DOMAIN_FORM_FIELD, "domain");
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, "My Test");
+	form.field(ComponentRegistryRestService.GROUP_FORM_FIELD, "My Group");
+	RegisterResponse response = getAuthenticatedResource("/registry/profiles").type(MediaType.MULTIPART_FORM_DATA).post(
+		RegisterResponse.class, form);
+	assertFalse(response.isRegistered());
+	assertTrue(response.isProfile());
+	assertEquals(1, response.getErrors().size());
+	assertEquals(MDValidator.MISMATCH_ERROR, response.getErrors().get(0));
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTestCase.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTestCase.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ComponentRegistryRestServiceTestCase.java	(revision 1843)
@@ -0,0 +1,84 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.util.List;
+
+import javax.ws.rs.core.HttpHeaders;
+
+
+import clarin.cmdi.componentregistry.impl.database.UserDao;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.RegistryUser;
+
+import com.sun.jersey.api.client.GenericType;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.WebResource.Builder;
+import com.sun.jersey.api.core.ClassNamesResourceConfig;
+import com.sun.jersey.core.util.Base64;
+import com.sun.jersey.multipart.impl.FormDataMultiPartDispatchProvider;
+import com.sun.jersey.spi.container.servlet.WebComponent;
+import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
+import com.sun.jersey.test.framework.AppDescriptor;
+import com.sun.jersey.test.framework.JerseyTest;
+import com.sun.jersey.test.framework.WebAppDescriptor;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.request.RequestContextListener;
+
+public abstract class ComponentRegistryRestServiceTestCase extends JerseyTest {
+    //CommandLine test e.g.:  curl -i -H "Accept:application/json" -X GET  http://localhost:8080/ComponentRegistry/rest/registry/profiles
+
+    protected final static GenericType<List<ProfileDescription>> PROFILE_LIST_GENERICTYPE = new GenericType<List<ProfileDescription>>() {
+    };
+    protected final static GenericType<List<ComponentDescription>> COMPONENT_LIST_GENERICTYPE = new GenericType<List<ComponentDescription>>() {
+    };
+    protected final static GenericType<List<Comment>> COMMENT_LIST_GENERICTYPE = new GenericType<List<Comment>>() {
+    };
+
+    @Autowired
+    private UserDao userDao;
+
+    
+    protected abstract String getApplicationContextFile();
+
+    @Override
+    protected AppDescriptor configure() {
+        WebAppDescriptor.Builder builder = new WebAppDescriptor.Builder()
+                .contextParam("contextConfigLocation", getApplicationContextFile())
+                .servletClass(SpringServlet.class)
+                .initParam(WebComponent.RESOURCE_CONFIG_CLASS,ClassNamesResourceConfig.class.getName())
+                .initParam(ClassNamesResourceConfig.PROPERTY_CLASSNAMES,FormDataMultiPartDispatchProvider.class.getName() + ";" + ComponentRegistryRestService.class.getName())
+                .addFilter(DummySecurityFilter.class, "DummySecurityFilter")
+                .requestListenerClass(RequestContextListener.class)
+                .contextListenerClass(ContextLoaderListener.class) 
+                ;
+        return builder.build();
+    }
+
+    protected WebResource getResource() {
+        return resource();
+    }
+
+    protected Builder getAuthenticatedResource(String path) {
+        return getAuthenticatedResource(getResource().path(path));
+    }
+
+    protected Builder getAuthenticatedResource(WebResource resource) {
+        return resource.header(HttpHeaders.AUTHORIZATION, "Basic "
+                + new String(Base64.encode(DummyPrincipal.DUMMY_PRINCIPAL.getName() + ":dummy")));
+    }
+    
+    protected void createUserRecord() {
+	RegistryUser user = new RegistryUser();
+	user.setName("Database test user");
+	user.setPrincipalName(DummyPrincipal.DUMMY_PRINCIPAL.getName());
+	userDao.insertUser(user);
+    }
+    
+    protected UserDao getUserDao() {
+	return userDao;
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ConcurrentRestServiceTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ConcurrentRestServiceTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/ConcurrentRestServiceTest.java	(revision 1843)
@@ -0,0 +1,175 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase;
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import static clarin.cmdi.componentregistry.rest.ComponentRegistryRestService.USERSPACE_PARAM;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import clarin.cmdi.componentregistry.model.RegisterResponse;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.multipart.FormDataMultiPart;
+import java.util.Collections;
+import java.util.Comparator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "/applicationContext.xml" })
+public class ConcurrentRestServiceTest extends ComponentRegistryRestServiceTestCase {
+
+    private final static Logger LOG = LoggerFactory.getLogger(ConcurrentRestServiceTest.class);
+    private int NR_OF_PROFILES = 50;
+    private int NR_OF_COMPONENTS = 50;
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+	createUserRecord();
+    }
+
+    @Override
+    protected String getApplicationContextFile() {
+	return "classpath:applicationContext.xml";
+    }
+    
+    @Test
+    public void testConcurrentRegisterProfile() throws Exception {
+	List<String> errors = new ArrayList();
+	List<Thread> ts = new ArrayList<Thread>();
+
+	registerProfiles(ts, NR_OF_PROFILES, errors, "false");
+	registerProfiles(ts, NR_OF_PROFILES, errors, "true");
+
+	registerComponents(ts, NR_OF_COMPONENTS, errors, "false");
+	registerComponents(ts, NR_OF_COMPONENTS, errors, "true");
+	runAllThreads(ts);
+	if (errors.size() > 0) {
+	    System.out.println(Arrays.toString(errors.toArray()));
+	    fail();
+	}
+	assertProfiles(NR_OF_PROFILES, "false");
+	assertProfiles(NR_OF_PROFILES, "true");
+
+	assertComponents(NR_OF_COMPONENTS, "false");
+	assertComponents(NR_OF_COMPONENTS, "true");
+    }
+
+    private void assertProfiles(int nrOfProfiles, String userSpace) {
+	List<ProfileDescription> response = getAuthenticatedResource(
+		getResource().path("/registry/profiles").queryParam(USERSPACE_PARAM, userSpace)).
+		accept(MediaType.APPLICATION_XML).get(
+		PROFILE_LIST_GENERICTYPE);
+	Collections.sort(response, descriptionComparator);
+	assertEquals("half should be deleted", nrOfProfiles / 2, response.size());
+	for (int i = 0; i < nrOfProfiles / 2; i++) {
+	    ProfileDescription desc = response.get(i);
+	    assertEquals("Test Profile" + (i * 2 + 1000), desc.getName());
+	    assertEquals("Test Profile" + (i * 2 + 1000) + " Description", desc.getDescription());
+	}
+    }
+    private Comparator<AbstractDescription> descriptionComparator = new Comparator<AbstractDescription>() {
+
+	@Override
+	public int compare(AbstractDescription o1, AbstractDescription o2) {
+	    return o1.getName().compareTo(o2.getName());
+	}
+    };
+
+    private void assertComponents(int nrOfComponents, String userSpace) {
+	List<ComponentDescription> cResponse = getAuthenticatedResource(
+		getResource().path("/registry/components").queryParam(USERSPACE_PARAM, userSpace)).
+		accept(MediaType.APPLICATION_XML).get(
+		COMPONENT_LIST_GENERICTYPE);
+	Collections.sort(cResponse, descriptionComparator);
+	assertEquals("half should be deleted", nrOfComponents / 2, cResponse.size());
+	for (int i = 0; i < nrOfComponents / 2; i++) {
+	    ComponentDescription desc = cResponse.get(i);
+	    assertEquals("Test Component" + (i * 2 + 1000), desc.getName());
+	    assertEquals("Test Component" + (i * 2 + 1000) + " Description", desc.getDescription());
+	}
+    }
+
+    private void runAllThreads(List<Thread> ts) throws InterruptedException {
+	for (Thread thread : ts) {
+	    thread.start();
+	    thread.join(10);
+	}
+	for (Thread thread : ts) {
+	    thread.join(); //Wait till all are finished
+	}
+    }
+
+    private void registerProfiles(List<Thread> ts, int size, final List<String> errors, String userSpace) throws InterruptedException {
+	for (int i = 0; i < size; i++) {
+	    final boolean shouldDelete = (i % 2) == 1;
+	    Thread thread = createThread("/registry/profiles/", userSpace, "Test Profile" + (i + 1000), shouldDelete, RegistryTestHelper.getTestProfileContent(), errors);
+	    ts.add(thread);
+	}
+    }
+
+    private void registerComponents(List<Thread> ts, int size, final List<String> errors, String userSpace) throws InterruptedException {
+	for (int i = 0; i < size; i++) {
+	    final boolean shouldDelete = (i % 2) == 1;
+	    Thread thread = createThread("/registry/components/", userSpace, "Test Component" + (i + 1000), shouldDelete,
+		    RegistryTestHelper.getComponentTestContent(), errors);
+	    ts.add(thread);
+	}
+    }
+
+    private Thread createThread(final String path, final String userSpace, final String name, final boolean alsoDelete,
+	    InputStream content, final List<String> errors) throws InterruptedException {
+	final FormDataMultiPart form = new FormDataMultiPart();
+	form.field(ComponentRegistryRestService.DATA_FORM_FIELD, content, MediaType.APPLICATION_OCTET_STREAM_TYPE);
+	form.field(ComponentRegistryRestService.NAME_FORM_FIELD, name);
+	form.field(ComponentRegistryRestService.DESCRIPTION_FORM_FIELD, name + " Description");
+	Thread t = new Thread(new Runnable() {
+
+	    @Override
+	    public void run() {
+		//                System.out.println("THREAD STARTED"+Thread.currentThread().getName());
+		RegisterResponse registerResponse = getAuthenticatedResource(
+			getResource().path(path).queryParam(USERSPACE_PARAM, userSpace)).
+			type(MediaType.MULTIPART_FORM_DATA).post(
+			RegisterResponse.class, form);
+		if (!registerResponse.isRegistered()) {
+		    errors.add("Failed to register " + Arrays.toString(registerResponse.getErrors().toArray()));
+		}
+		LOG.debug(">>>>>>>>>>>>>>>> [Thread " + hashCode() + "] REGISTERING DESCRIPTION " + name + " " + registerResponse.getDescription().getId() + (Boolean.valueOf(userSpace) ? " userspace" : "") + (alsoDelete ? " alsoDelete" : ""));
+		if (alsoDelete) {
+		    LOG.debug(">>>>>>>>>>>>>>>> [Thread " + hashCode() + "] DELETING DESCRIPTION " + name + " " + registerResponse.getDescription().getId() + (Boolean.valueOf(userSpace) ? " userspace " : "") + (alsoDelete ? " alsoDelete" : ""));
+		    ClientResponse response = getAuthenticatedResource(
+			    getResource().path(path + registerResponse.getDescription().getId()).queryParam(USERSPACE_PARAM, userSpace)).
+			    delete(ClientResponse.class);
+		    if (response.getStatus() != 200) {
+			errors.add("Failed to delete " + registerResponse.getDescription());
+		    }
+		}
+		//                System.out.println("THREAD FINISHED"+Thread.currentThread().getName());
+	    }
+	});
+	return t;
+
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DescriptionValidatorTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DescriptionValidatorTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DescriptionValidatorTest.java	(revision 1843)
@@ -0,0 +1,36 @@
+package clarin.cmdi.componentregistry.rest;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import clarin.cmdi.componentregistry.model.AbstractDescription;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+
+public class DescriptionValidatorTest {
+
+    @Test
+    public void testValidate() {
+        AbstractDescription desc = ComponentDescription.createNewDescription();
+        DescriptionValidator validator = new DescriptionValidator(desc);
+        assertFalse(validator.validate());
+
+        desc.setName("n");
+        validator = new DescriptionValidator(desc);
+        assertFalse(validator.validate());
+
+        desc.setCreatorName("n");
+        validator = new DescriptionValidator(desc);
+        assertFalse(validator.validate());
+
+        desc.setDescription("a");
+        validator = new DescriptionValidator(desc);
+        assertTrue(validator.validate());
+
+        desc.setDomainName("a"); //Not forced atm.
+        validator = new DescriptionValidator(desc);
+        assertTrue(validator.validate());
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummyPrincipal.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummyPrincipal.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummyPrincipal.java	(revision 1843)
@@ -0,0 +1,32 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.security.Principal;
+
+import clarin.cmdi.componentregistry.UserCredentials;
+
+public final class DummyPrincipal implements Principal {
+
+    public static final DummyPrincipal DUMMY_ADMIN_PRINCIPAL = new DummyPrincipal("JUnit.Admin@test.com");
+    public static final DummyPrincipal DUMMY_PRINCIPAL = new DummyPrincipal("JUnit@test.com");
+    public static final UserCredentials DUMMY_CREDENTIALS = new UserCredentials(DUMMY_PRINCIPAL) {
+
+	@Override
+	public String getDisplayName() {
+	    return "J.Unit";
+	}
+    };
+    private final String username;
+
+    public DummyPrincipal(String username) {
+	this.username = username;
+    }
+
+    @Override
+    public String getName() {
+	return username;
+    }
+
+    public UserCredentials getCredentials() {
+	return new UserCredentials(this);
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummySecurityFilter.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummySecurityFilter.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/DummySecurityFilter.java	(revision 1843)
@@ -0,0 +1,98 @@
+package clarin.cmdi.componentregistry.rest;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.naming.AuthenticationException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.ws.rs.core.HttpHeaders;
+
+import com.sun.jersey.api.container.MappableContainerException;
+import com.sun.jersey.core.util.Base64;
+
+/**
+ * Dummy security filter, very handy for unit testing.
+ * 
+ */
+public class DummySecurityFilter implements Filter {
+
+    private final List<String> ALLOWED_USERS = Arrays.asList(DummyPrincipal.DUMMY_PRINCIPAL.getName());
+
+    /**
+     * Dummy validation for unit tests
+     * @param username
+     * @param password
+     * @return
+     */
+    private boolean isValid(String username, String password) {
+        return ALLOWED_USERS.contains(username);
+    }
+
+    @Override
+    public void destroy() {
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        Principal principalResult = null;
+        HttpServletRequest req = (HttpServletRequest) request;
+        String authentication = req.getHeader(HttpHeaders.AUTHORIZATION);
+        if (authentication != null) { //if no authentication then do nothing
+            if (!authentication.startsWith("Basic ")) {
+                throw new MappableContainerException(new AuthenticationException("Only HTTP Basic authentication is supported"));
+            }
+            authentication = authentication.substring("Basic ".length());
+            String base64Decode = new String(Base64.decode(authentication.getBytes()));
+            String[] values = base64Decode.split(":");
+            if (values.length < 2) {
+                throw new MappableContainerException(new AuthenticationException("Invalid syntax for username and password"));
+            }
+            final String username = values[0];
+            String password = values[1];
+            if ((username == null) || (password == null)) {
+                throw new MappableContainerException(new AuthenticationException("Missing username or password"));
+            }
+            if (!isValid(username, password)) {
+                throw new MappableContainerException(new AuthenticationException("Invalid user/password"));
+            }
+            principalResult = new DummyPrincipal(username);
+        }
+
+        final Principal principal = principalResult;
+        HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(req) {
+
+            public boolean isUserInRole(String role) {
+                return true;
+            }
+
+            public boolean isSecure() {
+                return false;
+            }
+
+            public Principal getUserPrincipal() {
+                return principal;
+            }
+
+            @Override
+            public String getAuthType() {
+                return HttpServletRequest.BASIC_AUTH;
+            }
+        };
+        chain.doFilter(wrapper, response);
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+
+    }
+
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/MDValidatorTest.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/MDValidatorTest.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/MDValidatorTest.java	(revision 1843)
@@ -0,0 +1,225 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.ComponentRegistryFactory;
+import clarin.cmdi.componentregistry.impl.database.ComponentRegistryTestDatabase;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {"/applicationContext.xml"})
+public class MDValidatorTest {
+
+    @Autowired
+    private ComponentRegistryFactory componentRegistryFactory;
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+    private ComponentRegistry publicRegistry;
+
+    @Before
+    public void init() {
+	ComponentRegistryTestDatabase.resetAndCreateAllTables(jdbcTemplate);
+	publicRegistry = componentRegistryFactory.getPublicRegistry();
+    }
+
+    @Test
+    public void testValidateSucces() {
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component name=\"Actor\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	profileContent += "        <CMD_Element name=\"Age\">\n";
+	profileContent += "            <ValueScheme>\n";
+	profileContent += "                <pattern>[23][0-9]</pattern>\n";
+	profileContent += "            </ValueScheme>\n";
+	profileContent += "        </CMD_Element>\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+	InputStream input = new ByteArrayInputStream(profileContent.getBytes());
+
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	MDValidator validator = new MDValidator(input, desc, publicRegistry, null, publicRegistry);
+	assertTrue(validator.validate());
+    }
+
+    @Test
+    public void testValidateIllegalComponentAttributeName() {
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component name=\"Actor\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	profileContent += "	   <AttributeList>\n";
+	profileContent += "		<Attribute>\n";
+	profileContent += "		    <Name>myattribute</Name>\n"; // this should be allowed
+	profileContent += "		    <Type>string</Type>\n";
+	profileContent += "		</Attribute>\n";
+	profileContent += "		<Attribute>\n";
+	profileContent += "		    <Name>ref</Name>\n"; // this should NOT be allowed
+	profileContent += "		    <Type>string</Type>\n";
+	profileContent += "		</Attribute>\n";
+	profileContent += "		<Attribute>\n";
+	profileContent += "		    <Name>ComponentId</Name>\n"; // neither should this
+	profileContent += "		    <Type>string</Type>\n";
+	profileContent += "		</Attribute>\n";
+	profileContent += "	   </AttributeList>\n";
+	profileContent += "        <CMD_Element name=\"Age\">\n";
+	profileContent += "		<AttributeList>\n";
+	profileContent += "		    <Attribute>\n";
+	profileContent += "			<Name>ref</Name>\n"; // allowed here, only forbidden on components
+	profileContent += "			<Type>string</Type>\n";
+	profileContent += "		    </Attribute>\n";
+	profileContent += "		    <Attribute>\n";
+	profileContent += "			<Name>ComponentId</Name>\n"; // allowed here, only forbidden on components
+	profileContent += "			<Type>string</Type>\n";
+	profileContent += "		    </Attribute>\n";
+	profileContent += "		</AttributeList>\n";
+	profileContent += "            <ValueScheme>\n";
+	profileContent += "                <pattern>[23][0-9]</pattern>\n";
+	profileContent += "            </ValueScheme>\n";
+	profileContent += "        </CMD_Element>\n";
+	profileContent += "    </CMD_Component>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+	InputStream input = new ByteArrayInputStream(profileContent.getBytes());
+
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	MDValidator validator = new MDValidator(input, desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(4, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.PARSE_ERROR));
+	assertTrue(validator.getErrorMessages().get(1).startsWith(MDValidator.PARSE_ERROR));
+    }
+
+    @Test
+    public void testValidateNoComponentId() throws Exception {
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	profileContent += "    <Header />\n";
+	profileContent += "    <CMD_Component filename=\"component-actor.xml\"/>\n";
+	profileContent += "</CMD_ComponentSpec>\n";
+	InputStream input = new ByteArrayInputStream(profileContent.getBytes());
+
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	MDValidator validator = new MDValidator(input, desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+    }
+
+    @Test
+    public void testValidateComponentIdNotRegistered() throws Exception {
+	String id1 = "component1";
+	String id2 = "component2";
+
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">";
+	profileContent += "    <Header />";
+	profileContent += "    <CMD_Component name=\"Test\">";
+	profileContent += "	<CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + id1 + "\"/>"; //id not registered
+	profileContent += "	<CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + id2 + "\"/>"; //id not registered
+	profileContent += "    </CMD_Component>";
+	profileContent += "</CMD_ComponentSpec>";
+
+	// Ids not registered will return two errors. One for each id
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	MDValidator validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(2, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+	assertTrue(validator.getErrorMessages().get(1).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+
+	// id1 will be added and therefore only id2 is not registered
+	RegistryTestHelper.addComponent(publicRegistry, id1);
+	validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(1, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+
+	// id2 is added, no more errors shoud be return
+	RegistryTestHelper.addComponent(publicRegistry, id2);
+	validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertTrue("component is registered should be valid now", validator.validate());
+	assertEquals(0, validator.getErrorMessages().size());
+    }
+
+    @Test
+    public void testValidateUserRegistry() throws Exception {
+	String id1 = "component1";
+	String id2 = "component2";
+	ComponentRegistry userRegistry = componentRegistryFactory.getComponentRegistry(true, DummyPrincipal.DUMMY_CREDENTIALS);
+
+	String profileContent = "";
+	profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+	profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
+	profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">";
+	profileContent += "    <Header />";
+	profileContent += "    <CMD_Component name=\"Test\">";
+	profileContent += "	<CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + id1 + "\"/>"; //id not registered
+	profileContent += "	<CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + id2 + "\"/>"; //id not registered
+	profileContent += "    </CMD_Component>";
+	profileContent += "</CMD_ComponentSpec>";
+
+	ProfileDescription desc = ProfileDescription.createNewDescription();
+	MDValidator validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, userRegistry, userRegistry, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(2, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_REGISTERED_ERROR));
+	assertTrue(validator.getErrorMessages().get(1).startsWith(MDValidator.COMPONENT_NOT_REGISTERED_ERROR));
+
+	RegistryTestHelper.addComponent(userRegistry, id1);
+	RegistryTestHelper.addComponent(publicRegistry, id2);
+	validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(1, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+
+	validator = new MDValidator(new ByteArrayInputStream(profileContent.getBytes()), desc, userRegistry, userRegistry, publicRegistry);
+	assertTrue(validator.validate());
+	assertEquals(0, validator.getErrorMessages().size());
+    }
+
+    @Test
+    public void testValidateNestedComponents() throws Exception {
+	String id1 = "component1";
+
+	String content = "";
+	content += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+	content += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+	content += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+	content += "    <Header />\n";
+	content += "    <CMD_Component name=\"Actor\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+	content += "        <CMD_Element name=\"Name\" ValueScheme=\"string\" />\n";
+	content += "      <CMD_Component ComponentId=\"" + ComponentRegistry.REGISTRY_ID + id1 + "\"/>\n"; //id not registered
+	content += "    </CMD_Component>\n";
+	content += "</CMD_ComponentSpec>\n";
+
+	ComponentDescription desc = ComponentDescription.createNewDescription();
+	MDValidator validator = new MDValidator(new ByteArrayInputStream(content.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertFalse(validator.validate());
+	assertEquals(1, validator.getErrorMessages().size());
+	assertTrue(validator.getErrorMessages().get(0).startsWith(MDValidator.COMPONENT_NOT_PUBLICLY_REGISTERED_ERROR));
+
+	RegistryTestHelper.addComponent(publicRegistry, id1);
+	validator = new MDValidator(new ByteArrayInputStream(content.getBytes()), desc, publicRegistry, null, publicRegistry);
+	assertTrue(validator.validate());
+	assertEquals(0, validator.getErrorMessages().size());
+
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/RegistryTestHelper.java
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/RegistryTestHelper.java	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/java/clarin/cmdi/componentregistry/rest/RegistryTestHelper.java	(revision 1843)
@@ -0,0 +1,245 @@
+package clarin.cmdi.componentregistry.rest;
+
+import clarin.cmdi.componentregistry.ComponentRegistryException;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.text.ParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.bind.JAXBException;
+
+import clarin.cmdi.componentregistry.ComponentRegistry;
+import clarin.cmdi.componentregistry.MDMarshaller;
+import clarin.cmdi.componentregistry.components.CMDComponentSpec;
+import clarin.cmdi.componentregistry.model.Comment;
+import clarin.cmdi.componentregistry.model.ComponentDescription;
+import clarin.cmdi.componentregistry.model.ProfileDescription;
+
+/**
+ * Static helper methods to be used in tests
+ * 
+ */
+public final class RegistryTestHelper {
+
+    private RegistryTestHelper() {
+    }
+
+    public static ComponentDescription addComponent(ComponentRegistry testRegistry, String id) throws ParseException, JAXBException {
+        return addComponent(testRegistry, id, getComponentTestContent());
+    }
+
+    public static ComponentDescription addComponent(ComponentRegistry testRegistry, String id, String content) throws ParseException,
+            JAXBException, UnsupportedEncodingException {
+        return addComponent(testRegistry, id, new ByteArrayInputStream(content.getBytes("UTF-8")));
+    }
+
+    private static ComponentDescription addComponent(ComponentRegistry testRegistry, String id, InputStream content) throws ParseException,
+            JAXBException {
+        ComponentDescription desc = ComponentDescription.createNewDescription();
+        desc.setCreatorName(DummyPrincipal.DUMMY_CREDENTIALS.getDisplayName());
+        desc.setUserId(DummyPrincipal.DUMMY_CREDENTIALS.getPrincipalName());
+        desc.setName(id);
+        desc.setDescription("Test Description");
+        desc.setId(ComponentRegistry.REGISTRY_ID + id);
+        desc.setHref("link:" + ComponentRegistry.REGISTRY_ID + id);
+        CMDComponentSpec spec = MDMarshaller.unmarshal(CMDComponentSpec.class, content, MDMarshaller.getCMDComponentSchema());
+        testRegistry.register(desc, spec);
+        return desc;
+    }
+
+    public static int updateComponent(ComponentRegistry testRegistry, ComponentDescription description, String content) throws JAXBException {
+        return testRegistry.update(description, getComponentFromString(content), DummyPrincipal.DUMMY_CREDENTIALS.getPrincipal(), true);
+    }
+
+    public static String getProfileTestContentString() {
+        return getProfileTestContentString("Actor");
+    }
+
+    private static String getProfileTestContentString(String name) {
+        String profileContent = "";
+        profileContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+        profileContent += "<CMD_ComponentSpec isProfile=\"true\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+        profileContent += "    xsi:noNamespaceSchemaLocation=\"general-component-schema.xsd\">\n";
+        profileContent += "    <Header />\n";
+        profileContent += "    <CMD_Component name=\"" + name + "\" CardinalityMin=\"0\" CardinalityMax=\"unbounded\">\n";
+        profileContent += "        <AttributeList>\n";
+        profileContent += "            <Attribute>\n";
+        profileContent += "                <Name>Name</Name>\n";
+        profileContent += "                <Type>string</Type>\n";
+        profileContent += "            </Attribute>\n";
+        profileContent += "        </AttributeList>\n";
+        profileContent += "        <CMD_Element name=\"Age\">\n";
+        profileContent += "            <ValueScheme>\n";
+        profileContent += "                <pattern>[23][0-9]</pattern>\n";
+        profileContent += "            </ValueScheme>\n";
+        profileContent += "        </CMD_Element>\n";
+        profileContent += "    </CMD_Component>\n";
+        profileContent += "</CMD_ComponentSpec>\n";
+        return profileContent;
+    }
+
+    public static InputStream getTestProfileContent() {
+        return getTestProfileContent("Actor");
+    }
+
+    public static InputStream getTestProfileContent(String name) {
+        return new ByteArrayInputStream(getProfileTestContentString(name).getBytes());
+    }
+
+    public static ProfileDescription addProfile(ComponentRegistry testRegistry, String id) throws ParseException, JAXBException {
+        return addProfile(testRegistry, id, RegistryTestHelper.getTestProfileContent());
+    }
+
+    public static ProfileDescription addProfile(ComponentRegistry testRegistry, String id, String content) throws ParseException,
+            JAXBException {
+        return addProfile(testRegistry, id, new ByteArrayInputStream(content.getBytes()));
+    }
+
+    private static ProfileDescription addProfile(ComponentRegistry testRegistry, String id, InputStream content) throws ParseException,
+            JAXBException {
+        ProfileDescription desc = ProfileDescription.createNewDescription();
+        desc.setCreatorName(DummyPrincipal.DUMMY_CREDENTIALS.getDisplayName());
+        desc.setUserId(DummyPrincipal.DUMMY_CREDENTIALS.getPrincipalName());
+        desc.setName(id);
+        desc.setDescription("Test Description");
+        desc.setId(ComponentRegistry.REGISTRY_ID + id);
+        desc.setHref("link:" + ComponentRegistry.REGISTRY_ID + id);
+        CMDComponentSpec spec = MDMarshaller.unmarshal(CMDComponentSpec.class, content, MDMarshaller.getCMDComponentSchema());
+        testRegistry.register(desc, spec);
+        return desc;
+    }
+
+    public static CMDComponentSpec getTestProfile() throws JAXBException {
+        return MDMarshaller.unmarshal(CMDComponentSpec.class, getTestProfileContent(), MDMarshaller.getCMDComponentSchema());
+    }
+
+    public static String getComponentTestContentString() {
+        return getComponentTestContentString("Access");
+    }
+
+    public static InputStream getComponentTestContent() {
+        return getComponentTestContent("Access");
+    }
+
+    public static String getComponentTestContentString(String componentName) {
+        String compContent = "";
+        compContent += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+        compContent += "\n";
+        compContent += "<CMD_ComponentSpec isProfile=\"false\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
+        compContent += "    xsi:noNamespaceSchemaLocation=\"../../general-component-schema.xsd\">\n";
+        compContent += "    \n";
+        compContent += "    <Header/>\n";
+        compContent += "    \n";
+        compContent += "    <CMD_Component name=\"" + componentName + "\" CardinalityMin=\"1\" CardinalityMax=\"1\">\n";
+        compContent += "        <CMD_Element name=\"Availability\" ValueScheme=\"string\" />\n";
+        compContent += "        <CMD_Element name=\"Date\">\n";
+        compContent += "            <ValueScheme>\n";
+        compContent += "                <!-- matching dates of the pattern yyyy-mm-dd (ISO 8601); this only matches dates from the years 1000 through 2999 and does allow some invalid dates (e.g. February, the 30th) -->\n";
+        compContent += "                <pattern>(1|2)\\d{3}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])</pattern>                \n";
+        compContent += "            </ValueScheme>\n";
+        compContent += "        </CMD_Element>\n";
+        compContent += "        <CMD_Element name=\"Owner\" ValueScheme=\"string\" />\n";
+        compContent += "        <CMD_Element name=\"Publisher\" ValueScheme=\"string\" />\n";
+        compContent += "    </CMD_Component>\n";
+        compContent += "\n";
+        compContent += "</CMD_ComponentSpec>\n";
+        return compContent;
+    }
+
+    public static CMDComponentSpec getComponentFromString(String contentString) throws JAXBException {
+        return MDMarshaller.unmarshal(CMDComponentSpec.class, getComponentContent(contentString), MDMarshaller.getCMDComponentSchema());
+    }
+
+    public static InputStream getComponentContent(String content) {
+        return new ByteArrayInputStream(content.getBytes());
+    }
+
+    public static InputStream getComponentTestContent(String componentName) {
+        return getComponentContent(getComponentTestContentString(componentName));
+    }
+
+    public static CMDComponentSpec getTestComponent() throws JAXBException {
+        return MDMarshaller.unmarshal(CMDComponentSpec.class, getComponentTestContent(), MDMarshaller.getCMDComponentSchema());
+    }
+
+    public static CMDComponentSpec getTestComponent(String name) throws JAXBException {
+        return MDMarshaller.unmarshal(CMDComponentSpec.class, getComponentTestContent(name), MDMarshaller.getCMDComponentSchema());
+    }
+
+    public static String getXml(CMDComponentSpec componentSpec) throws JAXBException, UnsupportedEncodingException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        MDMarshaller.marshal(componentSpec, os);
+        String xml = os.toString();
+        try {
+            os.close();
+        } catch (IOException ex) {
+        }
+        return xml;
+    }
+
+    public static Comment addComment(ComponentRegistry testRegistry, String id, String descriptionId, String principal) throws ParseException, JAXBException, ComponentRegistryException {
+        return addComment(testRegistry, RegistryTestHelper.getTestCommentContent(id, descriptionId), principal);
+    }
+
+    private static Comment addComment(ComponentRegistry testRegistry, InputStream content, String principal) throws ParseException,
+            JAXBException, 
+            ComponentRegistryException {
+        Comment spec = MDMarshaller.unmarshal(Comment.class, content, null);
+        testRegistry.registerComment(spec, principal);
+        return spec;
+    }
+
+    public static String getCommentTestContentStringForProfile(String commentName, String profileId) {
+        String comContent = "";
+        comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        comContent += "    <comments>" + commentName + "</comments>\n";
+        comContent += "    <commentDate>" + Comment.createNewDate() + "</commentDate>\n";
+        comContent += "    <profileDescriptionId>" + profileId + "</profileDescriptionId>\n";
+        comContent += "    <userName>J. Unit</userName>\n";
+        comContent += "</comment>\n";
+        return comContent;
+    }
+
+    public static String getCommentTestContentStringForComponent(String commentName, String componentId) {
+        String comContent = "";
+        comContent += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
+        comContent += "<comment xmlns:ns2=\"http://www.w3.org/1999/xlink\">\n";
+        comContent += "    <comments>" + commentName + "</comments>\n";
+        comContent += "    <commentDate>" + Comment.createNewDate() + "</commentDate>\n";
+        comContent += "     <componentDescriptionId>" + componentId + "</componentDescriptionId>";
+        comContent += "    <userName>J. Unit</userName>\n";
+        comContent += "</comment>\n";
+        return comContent;
+    }
+
+    public static InputStream getTestCommentContent(String content, String descriptionId) {
+        if (descriptionId.contains("profile")) {
+            return new ByteArrayInputStream(getCommentTestContentStringForProfile(content, descriptionId).getBytes());
+        } else {
+            return new ByteArrayInputStream(getCommentTestContentStringForComponent(content, descriptionId).getBytes());
+        }
+    }
+
+    public static String getCommentTestContent(String commentId, String descriptionId) {
+        return getCommentTestContentStringForProfile(commentId, descriptionId);
+    }
+
+    public static InputStream getCommentTestContent() {
+        return getTestCommentContent("Actual", "clarin.eu:cr1:profile1");
+    }
+
+    /**
+     * Testing a big xsd string is a bit hard, so doing a best effort by checking the xs:element which represent the nested components used
+     * in a profile/component
+     */
+    public static boolean hasComponent(String xsd, String name, String min, String max) {
+        Pattern pattern = Pattern.compile("<xs:element name=\"" + name + "\" minOccurs=\"" + min + "\" maxOccurs=\"" + max + "\">");
+        Matcher matcher = pattern.matcher(xsd);
+        return matcher.find() && !matcher.find(); //find only one
+    }
+}
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/applicationContext.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/applicationContext.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/applicationContext.xml	(revision 1843)
@@ -0,0 +1,14 @@
+<?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:context="http://www.springframework.org/schema/context"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                           http://www.springframework.org/schema/context
+                           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+
+    <context:annotation-config />
+
+    <import resource="spring-config/component-registry.xml"/>
+    <import resource="spring-config/database-impl.xml"/>
+    
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/log4j.properties
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/log4j.properties	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/log4j.properties	(revision 1843)
@@ -0,0 +1,12 @@
+log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.Stdout.layout.conversionPattern=%d %p [%c{1}#%M:%L] - %m%n
+
+log4j.rootLogger=INFO,Stdout
+
+log4j.logger.org.apache.wicket=INFO
+log4j.logger.org.apache.wicket.protocol.http.HttpSessionStore=INFO
+log4j.logger.org.apache.wicket.version=INFO
+log4j.logger.org.apache.wicket.RequestCycle=INFO
+
+
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/component-registry.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/component-registry.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/component-registry.xml	(revision 1843)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+    <bean id="configuration" class="clarin.cmdi.componentregistry.Configuration" factory-method="getInstance">
+	<property name="adminUsersList" value="JUnit.Admin@test.com" />
+
+<!--	<property name="generalComponentSchema" value="http://www.clarin.eu/cmd/general-component-schema.xsd" />-->
+	<property name="generalComponentSchema" value="http://lux16.mpi.nl/general-component-schema.xsd" />	
+<!--	<property name="componentSpecSchemaLocation" value="http://www.clarin.eu/cmd http://www.clarin.eu/cmd/general-component-schema.xsd" />-->
+	<property name="componentSpecSchemaLocation" value="http://www.clarin.eu/cmd http://lux16.mpi.nl/general-component-schema.xsd" />
+
+	<property name="component2SchemaXsl" value="http://www.clarin.eu/cmd/xslt/comp2schema-v2/comp2schema.xsl"/>
+
+	<property name="isocatRestUrl" value="http://www.isocat.org/rest/" />
+    <!-- Extra attribute keys that are passed in a shibboleth authenticated request principal.
+         You need to configure the shhaa.xml file to enable the extra attributes.
+     -->
+	<property name="displayNameShibbolethKeys">
+	    <list>
+		<value>displayName</value>
+		<value>commonName</value>
+	    </list>
+	</property>
+    </bean>
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/database-impl.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/database-impl.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/database-impl.xml	(revision 1843)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+    
+<!--    <import resource="datasource-jdbc.xml"/>-->
+    <import resource="datasource-hsqldb.xml"/>
+    <import resource="persistence.xml"/>
+
+
+    <bean id="componentsCache" class="clarin.cmdi.componentregistry.impl.database.CMDComponentSpecCache" />
+    <bean id="profilesCache" class="clarin.cmdi.componentregistry.impl.database.CMDComponentSpecCache" />
+
+    <!-- Prototype bean for component registry (service) -->
+    <bean id="componentRegistry" class="clarin.cmdi.componentregistry.impl.database.ComponentRegistryDbImpl"  scope="prototype"></bean>
+
+    <!-- Factory that will create component registries for us (and autowire them), to be used by actual ComponentRegistryFactory -->
+    <bean id="componentRegistryBeanFactory"
+            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
+        <property name="serviceLocatorInterface" value="clarin.cmdi.componentregistry.impl.database.ComponentRegistryBeanFactory"/>
+    </bean>
+
+    <!-- Component registry factory that will be used by rest service to get user and public registries -->
+    <bean id="componentRegistryFactory" class="clarin.cmdi.componentregistry.impl.database.ComponentRegistryFactoryDbImpl"></bean>
+  
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-hsqldb.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-hsqldb.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-hsqldb.xml	(revision 1843)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
+        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
+        <property name="url" value="jdbc:hsqldb:mem:component_registry;sql.syntax_pgs=true"/>
+        <property name="username" value="sa"/>
+        <property name="password" value=""/>
+    </bean>
+
+    <bean id="jdbcTemplate"
+        class="org.springframework.jdbc.core.JdbcTemplate">
+        <property name="dataSource" ref="dataSource"/>
+    </bean>
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-jdbc.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-jdbc.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/datasource-jdbc.xml	(revision 1843)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+<!--    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
+        <property name="driverClassName" value="${jdbc.driverClassName}"/>
+        <property name="url" value="${jdbc.url}"/>
+        <property name="username" value="${jdbc.username}"/>
+        <property name="password" value="${jdbc.password}"/>
+    </bean>-->
+    
+    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
+	<property name="driverClassName" value="org.postgresql.Driver"/>
+	<property name="url" value="jdbc:postgresql:component_registry"/>
+	<property name="username" value="component_registry"/>
+	<property name="password" value="component_registry"/>
+    </bean>
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/persistence.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/persistence.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/ComponentRegistry/src/test/resources/spring-config/persistence.xml	(revision 1843)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
+       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+">
+    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+
+    <bean id="txDefinition" class="org.springframework.transaction.support.DefaultTransactionDefinition"></bean>
+
+    <bean id="profileDescriptionDao" class="clarin.cmdi.componentregistry.impl.database.ProfileDescriptionDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    <bean id="componentDescriptionDao" class="clarin.cmdi.componentregistry.impl.database.ComponentDescriptionDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    <bean id="userDao" class="clarin.cmdi.componentregistry.impl.database.UserDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+        <bean id="commentsDao" class="clarin.cmdi.componentregistry.impl.database.CommentsDao">
+	<property name="dataSource" ref="dataSource"/>
+    </bean>
+
+</beans>
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/README
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/README	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/README	(revision 1843)
@@ -0,0 +1,11 @@
+CLARIN COMPONENT REGISTRY
+=========================
+
+This project contains two modules:
+
+- 'ComponentRegistry', a Java project that implements the Component Registry
+  REST service, administration pages and a web container for a client UI.
+- 'ComponentBrowserGui', a Flex project that implements a client for the
+  Component Registry REST service.
+
+For more information, see ComponentRegistry/README.
Index: /ComponentRegistry/tags/ComponentRegistry-1.11.0/pom.xml
===================================================================
--- /ComponentRegistry/tags/ComponentRegistry-1.11.0/pom.xml	(revision 1843)
+++ /ComponentRegistry/tags/ComponentRegistry-1.11.0/pom.xml	(revision 1843)
@@ -0,0 +1,71 @@
+<?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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>clarin.cmdi</groupId>
+  <artifactId>componentRegistry.parent</artifactId>
+  <name>componentRegistry_parent</name>
+  <packaging>pom</packaging>
+  <version>1.0</version>
+  <description>Parent pom for ComponentRegistry, see www.clarin.eu/cmdi.</description>
+  <modules>
+    <module>ComponentBrowserGui</module>
+    <module>ComponentRegistry</module>
+    <module>CMDValidate</module>
+  </modules>
+
+  <scm>
+     <developerConnection>scm:svn:http://svn.clarin.eu/ComponentRegistry/trunk</developerConnection>
+  </scm>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <ComponentBrowserGui.version>1.11.0</ComponentBrowserGui.version>
+    <ComponentRegistry.version>1.11.0</ComponentRegistry.version>
+  </properties>
+  
+  <repositories>
+<repository>
+<id>cmdi.clarin.repository</id>
+<name>Clarin Repository</name>
+<url>http://catalog.clarin.eu/ds/nexus/content/groups/public/</url> 
+</repository> 
+ </repositories>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-report-plugin</artifactId>
+        <version>2.7.2</version>
+        <configuration>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-javadoc-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>javancss-maven-plugin</artifactId>
+      </plugin>
+	  <plugin>
+		<groupId>org.codehaus.mojo</groupId>
+		<artifactId>cobertura-maven-plugin</artifactId>
+		<version>2.5.1</version>
+	    <configuration>
+          <formats>
+          	<format>xml</format>
+          </formats>
+		</configuration>
+	  </plugin>
+    </plugins>
+
+  </reporting>
+</project>
+
Index: /ComponentRegistry/trunk/pom.xml
===================================================================
--- /ComponentRegistry/trunk/pom.xml	(revision 1842)
+++ /ComponentRegistry/trunk/pom.xml	(revision 1843)
@@ -22,6 +22,6 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <ComponentBrowserGui.version>1.11.0-SNAPSHOT</ComponentBrowserGui.version>
-    <ComponentRegistry.version>1.11.0-SNAPSHOT</ComponentRegistry.version>
+    <ComponentBrowserGui.version>1.12.0-SNAPSHOT</ComponentBrowserGui.version>
+    <ComponentRegistry.version>1.12.0-SNAPSHOT</ComponentRegistry.version>
   </properties>
   
