Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.md5
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.md5	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.md5	(revision 5326)
@@ -0,0 +1,1 @@
+b7254ab06d249d7de96cd581e7c3e6fb
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.sha1
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.sha1	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.jar.sha1	(revision 5326)
@@ -0,0 +1,1 @@
+528ddde0273c406cff6b95210b5729e9aa9694a2
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom	(revision 5326)
@@ -0,0 +1,9 @@
+<?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>
+  <groupId>xerces</groupId>
+  <artifactId>xercesImpl-patched</artifactId>
+  <version>2.11.0</version>
+  <description>POM was created from install:install-file</description>
+</project>
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.md5
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.md5	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.md5	(revision 5326)
@@ -0,0 +1,1 @@
+2cdacbe6efb9acd371ddc60a7972a4f7
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.sha1
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.sha1	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/2.11.0/xercesImpl-patched-2.11.0.pom.sha1	(revision 5326)
@@ -0,0 +1,1 @@
+3de028d22bd042913988bba0b66a01c56d0de98c
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml	(revision 5326)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>xerces</groupId>
+  <artifactId>xercesImpl-patched</artifactId>
+  <versioning>
+    <release>2.11.0</release>
+    <versions>
+      <version>2.11.0</version>
+    </versions>
+    <lastUpdated>20140407180824</lastUpdated>
+  </versioning>
+</metadata>
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.md5
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.md5	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.md5	(revision 5326)
@@ -0,0 +1,1 @@
+d2bbebbf1b1241e28dcb5bda620494f1
Index: CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.sha1
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.sha1	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/lib/xerces/xercesImpl-patched/maven-metadata-local.xml.sha1	(revision 5326)
@@ -0,0 +1,1 @@
+69484c27d7b2c8a5e6f2545ed79e7b61586cfc7f
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPlugin.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPlugin.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPlugin.java	(revision 5326)
@@ -0,0 +1,11 @@
+package eu.clarin.cmdi.validator;
+
+import net.sf.saxon.s9api.XdmNode;
+
+
+public interface CMDIValidationPlugin {
+
+    public void validate(XdmNode document, CMDIValidatorResultImpl result)
+            throws CMDIValidatorException;
+
+}
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPluginFactory.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPluginFactory.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidationPluginFactory.java	(revision 5326)
@@ -0,0 +1,11 @@
+package eu.clarin.cmdi.validator;
+
+import net.sf.saxon.s9api.Processor;
+
+
+public interface CMDIValidationPluginFactory {
+
+    public CMDIValidationPlugin newInstance(Processor processor)
+            throws CMDIValidatorInitException;
+
+}
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java	(revision 5326)
@@ -0,0 +1,525 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.dom.DOMSource;
+
+import net.sf.saxon.s9api.Axis;
+import net.sf.saxon.s9api.DocumentBuilder;
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.QName;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.WhitespaceStrippingPolicy;
+import net.sf.saxon.s9api.XPathCompiler;
+import net.sf.saxon.s9api.XPathExecutable;
+import net.sf.saxon.s9api.XPathSelector;
+import net.sf.saxon.s9api.XdmDestination;
+import net.sf.saxon.s9api.XdmItem;
+import net.sf.saxon.s9api.XdmNode;
+import net.sf.saxon.s9api.XdmSequenceIterator;
+import net.sf.saxon.s9api.XsltExecutable;
+import net.sf.saxon.s9api.XsltTransformer;
+
+import org.apache.xerces.impl.xs.XMLSchemaLoader;
+import org.apache.xerces.impl.xs.XSDDescription;
+import org.apache.xerces.parsers.DOMParser;
+import org.apache.xerces.parsers.XML11Configuration;
+import org.apache.xerces.util.SymbolTable;
+import org.apache.xerces.xni.XMLResourceIdentifier;
+import org.apache.xerces.xni.XNIException;
+import org.apache.xerces.xni.grammars.Grammar;
+import org.apache.xerces.xni.grammars.XMLGrammarDescription;
+import org.apache.xerces.xni.grammars.XMLGrammarPool;
+import org.apache.xerces.xni.parser.XMLEntityResolver;
+import org.apache.xerces.xni.parser.XMLErrorHandler;
+import org.apache.xerces.xni.parser.XMLInputSource;
+import org.apache.xerces.xni.parser.XMLParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import eu.clarin.cmdi.validator.CMDIValidatorResult.Severity;
+import eu.clarin.cmdi.validator.utils.LRUCache;
+
+
+public final class CMDIValidator {
+    private static final Logger logger =
+            LoggerFactory.getLogger(CMDIValidator.class);
+    private static final String XML_SCHEMA_LOCATION =
+            "http://www.w3.org/2001/xml.xsd";
+    private static final String XML_SCHEMA_GRAMMAR_TYPE =
+            "http://www.w3.org/2001/XMLSchema";
+    private static final String GRAMMAR_POOL =
+            "http://apache.org/xml/properties/internal/grammar-pool";
+    private static final String NAMESPACES_FEATURE_ID =
+            "http://xml.org/sax/features/namespaces";
+    private static final String VALIDATION_FEATURE_ID =
+            "http://xml.org/sax/features/validation";
+    private static final String SCHEMA_VALIDATION_FEATURE_ID =
+            "http://apache.org/xml/features/validation/schema";
+    private static final String SCHEMA_FULL_CHECKING_FEATURE_ID =
+            "http://apache.org/xml/features/validation/schema-full-checking";
+    private static final String HONOUR_ALL_SCHEMA_LOCATIONS_ID =
+            "http://apache.org/xml/features/honour-all-schemaLocations";
+    private static final int INITAL_SYMBOL_TABLE_SIZE = 16141;
+    private static final String SVRL_NAMESPACE_URI = "http://purl.oclc.org/dsdl/svrl";
+    private static final String SVRL_NAMESPACE_PREFIX = "svrl";
+    private static final QName SVRL_TEXT =
+            new QName(SVRL_NAMESPACE_URI, "text");
+    private static final QName SVRL_FAILED_ASSERT =
+            new QName(SVRL_NAMESPACE_URI, "failed-assert");
+    private final Processor processor;
+    private final XPathExecutable xpath1;
+    private final XPathExecutable xpath2;
+    private final XsltTransformer schematronValidator;
+    private final XML11Configuration config;
+    private final DocumentBuilder builder;
+    private final List<CMDIValidationPlugin> plugins;
+    private final CMDIValidatorResultImpl result;
+
+
+    CMDIValidator(final Processor processor,
+            final SchemaLoader schemaLoader,
+            XsltExecutable schematronExecutable,
+            List<CMDIValidationPlugin> plugins)
+            throws CMDIValidatorInitException {
+        if (processor == null) {
+            throw new NullPointerException("processor == null");
+        }
+        this.processor = processor;
+        if (schematronExecutable != null) {
+            try {
+                final XPathCompiler compiler = processor.newXPathCompiler();
+                compiler.declareNamespace(SVRL_NAMESPACE_PREFIX, SVRL_NAMESPACE_URI);
+                this.xpath1 = compiler.compile("//(svrl:failed-assert|svrl:successful-report)");
+                this.xpath2 = compiler.compile("preceding-sibling::svrl:fired-rule/@role");
+                this.schematronValidator = schematronExecutable.load();
+            } catch (SaxonApiException e) {
+                throw new CMDIValidatorInitException(
+                        "error initializing validator", e);
+            }
+        } else {
+            this.xpath1              = null;
+            this.xpath2              = null;
+            this.schematronValidator = null;
+        }
+
+        try {
+            /*
+             * initialize Xerces
+             */
+            XMLEntityResolver resolver = new XMLEntityResolver() {
+                @Override
+                public XMLInputSource resolveEntity(
+                        XMLResourceIdentifier identifier) throws XNIException,
+                        IOException {
+                    final String uri = identifier.getExpandedSystemId();
+                    if (uri == null) {
+                        throw new IOException("bad schema location for namespace '" +
+                                        identifier.getNamespace() + "': " +
+                                        identifier.getLiteralSystemId());
+                    }
+                    InputStream stream = schemaLoader.loadSchemaFile(
+                            identifier.getNamespace(), uri);
+                    return new XMLInputSource(null, null, null, stream, null);
+                }
+            };
+
+            SymbolTable symbols = new SymbolTable(INITAL_SYMBOL_TABLE_SIZE);
+            ShadowCacheXMLGrammarPool pool = new ShadowCacheXMLGrammarPool(8);
+
+            XMLSchemaLoader xsdLoader = new XMLSchemaLoader(symbols);
+            xsdLoader.setParameter(GRAMMAR_POOL, pool);
+            xsdLoader.setEntityResolver(resolver);
+            xsdLoader.setErrorHandler(new XMLErrorHandler() {
+                @Override
+                public void warning(String domain, String key,
+                        XMLParseException e) throws XNIException {
+                    /* ignore warnings */
+                }
+
+                @Override
+                public void error(String domain, String key, XMLParseException e)
+                        throws XNIException {
+                    throw e;
+                }
+
+                @Override
+                public void fatalError(String domain, String key,
+                        XMLParseException e) throws XNIException {
+                    throw e;
+                }
+            });
+
+            InputStream stream = null;
+            try {
+                stream = schemaLoader.loadSchemaFile(XMLConstants.XML_NS_URI,
+                        XML_SCHEMA_LOCATION);
+                Grammar grammar = xsdLoader.loadGrammar(
+                        new XMLInputSource(XMLConstants.XML_NS_URI,
+                                XML_SCHEMA_LOCATION, null, stream, null));
+                if (grammar != null) {
+                    pool.cacheGrammars(XML_SCHEMA_GRAMMAR_TYPE,
+                            new Grammar[] { grammar });
+                }
+                pool.lockPool();
+            } finally {
+                if (stream != null) {
+                    stream.close();
+                }
+            }
+
+            config = new XML11Configuration(symbols, pool);
+            config.setFeature(NAMESPACES_FEATURE_ID, true);
+            config.setFeature(VALIDATION_FEATURE_ID, true);
+            config.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true);
+            config.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true);
+            config.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, true);
+            config.setEntityResolver(resolver);
+            config.setErrorHandler(new XMLErrorHandler() {
+                @Override
+                public void warning(String domain, String key,
+                        XMLParseException e) throws XNIException {
+                    reportWarning(e.getLineNumber(), e.getColumnNumber(),
+                            e.getMessage(), e);
+                }
+
+                @Override
+                public void error(String domain, String key, XMLParseException e)
+                        throws XNIException {
+                    reportError(e.getLineNumber(), e.getColumnNumber(),
+                            e.getMessage(), e);
+                    throw e;
+                }
+
+                @Override
+                public void fatalError(String domain, String key,
+                        XMLParseException e) throws XNIException {
+                    reportError(e.getLineNumber(), e.getColumnNumber(),
+                            e.getMessage(), e);
+                    throw e;
+                }
+            });
+
+            /*
+             * initialize Saxon document builder
+             */
+            this.builder = this.processor.newDocumentBuilder();
+            this.builder.setWhitespaceStrippingPolicy(
+                    WhitespaceStrippingPolicy.IGNORABLE);
+
+            /*
+             * initialize plugins
+             */
+            if ((plugins != null) && !plugins.isEmpty()) {
+                this.plugins = plugins;
+            } else {
+                this.plugins = null;
+            }
+
+            /*
+             * initialize other stuff
+             */
+            this.result =  new CMDIValidatorResultImpl();
+        } catch (IOException e) {
+            throw new CMDIValidatorInitException("initialization failed", e);
+        }
+    }
+
+
+    public void validate(InputStream stream, File file,
+            CMDIValidatorJobHandler handler) throws CMDIValidatorException {
+        if (stream == null) {
+            throw new NullPointerException("stream == null");
+        }
+
+        try {
+            result.setFile(file);
+
+            /*
+             * step 1: parse document and perform schema validation
+             */
+            final XdmNode document = parseInstance(stream);
+
+            if (document != null) {
+                /*
+                 * step 2: perform Schematron validation
+                 */
+                if (schematronValidator != null) {
+                    validateSchematron(document);
+                }
+
+                /*
+                 * step 3: run plugins, if any
+                 */
+                if (plugins != null) {
+                    for (CMDIValidationPlugin plugin : plugins) {
+                        plugin.validate(document, result);
+                    }
+                }
+            } else {
+                logger.debug("parseInstance() returned no result");
+            }
+        } catch (CMDIValidatorException e) {
+            throw e;
+        } finally {
+            if (handler != null) {
+                if (result.isHighestSeverity(Severity.ERROR)) {
+                    handler.onValidationFailure(result);
+                } else {
+                    handler.onValidationSuccess(result);
+                }
+            }
+            result.reset();
+        }
+    }
+
+
+    private XdmNode parseInstance(InputStream stream)
+            throws CMDIValidatorException {
+        try {
+            final DOMParser parser = new DOMParser(config);
+            try {
+                parser.parse(new InputSource(stream));
+                stream.close();
+
+                final Document dom = parser.getDocument();
+                if (dom == null) {
+                    throw new CMDIValidatorException(
+                            "parser returned no return result");
+                }
+                return builder.build(new DOMSource(dom));
+            } finally {
+                parser.reset();
+            }
+        } catch (XNIException e) {
+            throw new CMDIValidatorException(e.getMessage(), e);
+        } catch (SaxonApiException e) {
+            throw new CMDIValidatorException(e.getMessage(), e);
+        } catch (SAXException e) {
+            throw new CMDIValidatorException(e.getMessage(), e);
+        } catch (IOException e) {
+            throw new CMDIValidatorException(e.getMessage(), e);
+        } finally {
+            /* make sure, steam is closed */
+            try {
+                stream.close();
+            } catch (IOException e) {
+                /* IGNORE */
+            }
+        }
+    }
+
+
+    private void validateSchematron(XdmNode document)
+            throws CMDIValidatorException {
+        try {
+            logger.debug("performing schematron validation ...");
+            schematronValidator.setSource(document.asSource());
+            final XdmDestination destination = new XdmDestination();
+            schematronValidator.setDestination(destination);
+            schematronValidator.transform();
+
+
+            XPathSelector selector = xpath1.load();
+            selector.setContextItem(destination.getXdmNode());
+            for (XdmItem item : selector) {
+                final XdmNode node = (XdmNode) item;
+                final XdmNode text = getFirstChild(node, SVRL_TEXT);
+                String msg = (text != null) ? text.getStringValue().trim() : null;
+                if (SVRL_FAILED_ASSERT.equals(node.getNodeName())) {
+                    XPathSelector selector2 = xpath2.load();
+                    String role = null;
+                    selector2.setContextItem(node);
+                    XdmItem evaluateSingle = selector2.evaluateSingle();
+                    if (evaluateSingle != null) {
+                        role = evaluateSingle.getStringValue().trim();
+                    }
+                    if ("warning".equalsIgnoreCase(role)) {
+                        result.reportWarning(-1, -1, msg);
+                    } else {
+                        result.reportError(-1, -1, msg);
+                    }
+                } else {
+                    result.reportInfo(-1, -1, msg);
+                }
+            }
+        } catch (SaxonApiException e) {
+            throw new CMDIValidatorException(
+                    "error performing schematron validation", e);
+        }
+    }
+
+
+    private static XdmNode getFirstChild(XdmNode parent, QName name) {
+        XdmSequenceIterator i = parent.axisIterator(Axis.CHILD, name);
+        if (i.hasNext()) {
+            return (XdmNode) i.next();
+        } else {
+            return null;
+        }
+    }
+
+
+    private void reportWarning(int line, int col, String message, Throwable cause) {
+        logger.debug("reporting warning: [{}:{}]: {}", line, col, message);
+        if (result != null) {
+            result.reportWarning(line, col, message, cause);
+        }
+    }
+
+
+    private void reportError(int line, int col, String message, Throwable cause) {
+        logger.debug("reporting error: [{}:{}]: {}", line, col, message);
+        if (result != null) {
+            result.reportError(line, col, message, cause);
+        }
+    }
+
+
+    private static class ShadowCacheXMLGrammarPool implements XMLGrammarPool {
+        private final Set<Grammar> cache =
+                new LinkedHashSet<Grammar>();
+        private final Map<String, Grammar> shadowCache;
+        private boolean locked = false;
+
+
+        private ShadowCacheXMLGrammarPool(int shadowCacheSize) {
+            this.shadowCache = new LRUCache<String, Grammar>(shadowCacheSize);
+        }
+
+
+        @Override
+        public Grammar[] retrieveInitialGrammarSet(String grammarType) {
+            if (XML_SCHEMA_GRAMMAR_TYPE.equals(grammarType) &&
+                    !cache.isEmpty()) {
+                final Grammar[] result = new Grammar[cache.size()];
+                return cache.toArray(result);
+            } else {
+                return null;
+            }
+        }
+
+
+        @Override
+        public Grammar retrieveGrammar(XMLGrammarDescription d) {
+            logger.debug("search for grammar: {} / {} / {} / {}",
+                    d.getNamespace(),
+                    d.getLiteralSystemId(),
+                    d.getExpandedSystemId(),
+                    d.getBaseSystemId());
+            if ((d.getNamespace() == null) || !(d instanceof XSDDescription)) {
+                logger.debug("-> miss (invalid arguments supplied by caller)");
+                return null;
+            }
+
+            final XSDDescription desc = (XSDDescription) d;
+            final String namespace = desc.getNamespace();
+            Grammar result = findGrammerFromCache(desc);
+            if (result != null) {
+                logger.debug("-> match from cache: {} -> {} / {}",
+                        namespace,
+                        desc.getNamespace(),
+                        desc.getLiteralSystemId());
+                return result;
+            }
+
+            String locationHint = null;
+            if (desc.getLocationHints() != null) {
+                String[] h = desc.getLocationHints();
+                if (h.length > 0) {
+                    locationHint = h[0];
+                }
+                logger.debug("-> hint: {}", locationHint);
+            } else if (desc.getLiteralSystemId() != null) {
+                locationHint = desc.getLiteralSystemId();
+            }
+
+            if (locationHint != null) {
+                Grammar grammar = shadowCache.get(locationHint);
+                if (grammar != null) {
+                    logger.debug("-> match from shadow cache: {} -> {}",
+                            grammar.getGrammarDescription().getNamespace(),
+                            locationHint);
+                    return grammar;
+                }
+            }
+            logger.debug("-> miss");
+            return null;
+        }
+
+
+        @Override
+        public void lockPool() {
+            locked = true;
+        }
+
+
+        @Override
+        public void unlockPool() {
+            locked = false;
+        }
+
+
+        @Override
+        public void clear() {
+            if (!locked) {
+                cache.clear();
+            }
+        }
+
+
+        @Override
+        public void cacheGrammars(String grammarType, Grammar[] grammars) {
+            if (XML_SCHEMA_GRAMMAR_TYPE.equals(grammarType) &&
+                    (grammars != null) &&
+                    (grammars.length > 0)) {
+                for (Grammar grammar : grammars) {
+                    final XMLGrammarDescription gd =
+                            grammar.getGrammarDescription();
+                    if (findGrammerFromCache(gd) == null) {
+                        if (!locked) {
+                            logger.debug("cached grammar: {} / {}",
+                                    gd.getNamespace(),
+                                    gd.getLiteralSystemId());
+                            cache.add(grammar);
+                        } else {
+                            final String literalSystemId =
+                                        gd.getLiteralSystemId();
+                            if (!shadowCache.containsKey(literalSystemId)) {
+                                logger.debug("shadow cached grammar: {} / {}",
+                                        gd.getNamespace(),
+                                        gd.getLiteralSystemId());
+                                shadowCache.put(literalSystemId, grammar);
+                            }
+                        }
+                    }
+                } // for
+            }
+        }
+
+
+        private Grammar findGrammerFromCache(XMLGrammarDescription desc) {
+            if (!cache.isEmpty()) {
+                for (Grammar grammar : cache) {
+                    final XMLGrammarDescription gd =
+                            grammar.getGrammarDescription();
+                    if (gd.getNamespace().equals(desc.getNamespace())) {
+                        return grammar;
+                    }
+                }
+            }
+            return null;
+        }
+    }  // class ShadowCacheGrammarPool
+
+} // class CMDIValidator
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorEngine.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorEngine.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorEngine.java	(revision 5326)
@@ -0,0 +1,225 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.java.truevfs.access.TFile;
+import net.java.truevfs.access.TFileInputStream;
+
+
+public class CMDIValidatorEngine {
+    private static final Logger logger =
+            LoggerFactory.getLogger(CMDIValidatorEngine.class);
+    private final CMDIValidatorFactory validatorFactory;
+    private final int threadCount;
+    private boolean running = false;
+    private ThreadGroup workers;
+    private ExecutorService executor;
+    private JobList jobList;
+
+
+    public CMDIValidatorEngine(CMDIValidatorFactory validatorFactory,
+            int threadCount) {
+        if (validatorFactory == null) {
+            throw new NullPointerException("validatorFactory == null");
+        }
+        this.validatorFactory = validatorFactory;
+        this.threadCount      = threadCount;
+    }
+
+
+    public CMDIValidatorEngine(CMDIValidatorFactory validatorFactory) {
+        this(validatorFactory, Runtime.getRuntime().availableProcessors());
+    }
+
+
+    public synchronized void start() throws CMDIValidatorInitException {
+        if (running) {
+            throw new IllegalStateException("engine already started");
+        }
+        logger.debug("start validation engine");
+
+        jobList = new JobList();
+
+        workers = new ThreadGroup("Validation-Workers");
+        final ThreadFactory threadFactory = new ThreadFactory() {
+            private int id = 0;
+            @Override
+            public Thread newThread(Runnable target) {
+                final String name = String.format("worker-%02x", id++);
+                return new Thread(workers, target, name);
+            }
+        };
+        final CountDownLatch goLatch = new CountDownLatch(1);
+        executor = Executors.newFixedThreadPool(threadCount, threadFactory);
+        for (int i = 0; i < threadCount; i++) {
+            final CMDIValidator validator = validatorFactory.newValidator();
+            final Worker worker = new Worker(jobList, validator, goLatch);
+            executor.submit(worker);
+        }
+        goLatch.countDown();
+        running = true;
+    }
+
+
+    public synchronized void shutdown() {
+        logger.debug("shutdown validation engine");
+        executor.shutdownNow();
+        try {
+            executor.awaitTermination(5000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+        }
+    }
+
+
+    public void submit(CMDIValidatorJob job) {
+        if (job == null) {
+            throw new NullPointerException("job == null");
+        }
+        if (!running) {
+            throw new IllegalStateException("engine not started");
+        }
+        jobList.put(job);
+    }
+
+
+    private static void validateFile(final CMDIValidator validator,
+            final CMDIValidatorJob job, final TFile file) {
+        try {
+            TFileInputStream stream = new TFileInputStream(file);
+            try {
+                logger.debug("validating file '{}' ({} bytes)",
+                        file, file.length());
+                validator.validate(stream, file, job.getHandler());
+            } catch (CMDIValidatorException e) {
+                logger.debug("validation of file '{}' failed", file, e);
+            } finally {
+                stream.close();
+            }
+        } catch (IOException e) {
+            logger.error("error reading file '{}': {}",
+                    file, e.getMessage());
+        }
+    }
+
+
+    private static final class JobList {
+        private static final class Holder {
+            private CMDIValidatorJob job;
+            private TFile file;
+
+            private void clear() {
+                job  = null;
+                file = null;
+            }
+        }
+        private final List<CMDIValidatorJob> jobs =
+                    new ArrayList<CMDIValidatorJob>();
+        private int idx = 0;
+
+
+        private void put(CMDIValidatorJob job) {
+            synchronized (jobs) {
+                jobs.add(job);
+
+                /* let the waiting herd stampede ... */
+                jobs.notifyAll();
+            } // synchronized (jobs)
+        }
+
+
+        private void get(JobList.Holder holder)
+                throws InterruptedException {
+            holder.clear();
+
+            for (;;) {
+                synchronized (jobs) {
+                    if (!jobs.isEmpty()) {
+                        holder.job  = jobs.get(idx++);
+                        holder.file = holder.job.getFileForProcessing(jobs);
+                        if (idx >= jobs.size()) {
+                            idx = 0;
+                        }
+                        if (holder.file != null) {
+                            break;
+                        } else {
+                            holder.clear();
+                        }
+                    }
+
+                    /* no cookie for me, wait for someone to fill the jar ... */
+                    jobs.wait();
+                } // synchronized (jobs)
+            } // for
+        }
+
+
+        private void remove(CMDIValidatorJob job) {
+            synchronized (jobs) {
+                jobs.remove(job);
+                if (idx >= jobs.size()) {
+                    idx = 0;
+                }
+            } // synchronized (jobs)
+        }
+    } // inner class JobList
+
+
+    private static final class Worker implements Runnable {
+        private final CountDownLatch goLatch;
+        private final JobList jobList;
+        private final CMDIValidator validator;
+
+
+        private Worker(JobList jobList, CMDIValidator validator,
+                CountDownLatch goLatch) {
+            this.jobList   = jobList;
+            this.validator = validator;
+            this.goLatch   = goLatch;
+        }
+
+
+        @Override
+        public void run() {
+            try {
+                final JobList.Holder holder = new JobList.Holder();
+
+                // wait for start signal
+                goLatch.await();
+
+                // loop for work ...
+                for (;;) {
+                    if (Thread.currentThread().isInterrupted()) {
+                        break;
+                    }
+                    jobList.get(holder);
+
+                    final CMDIValidatorJob job = holder.job;
+                    final TFile file           = holder.file;
+                    try {
+                        validateFile(validator, job, file);
+                    } finally {
+                        if (job.returnFileFromProcessing(file)) {
+                            jobList.remove(job);
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                /* IGNORE */
+            } catch (Throwable e) {
+                logger.error("unexpected error in worker thread: {}",
+                        e.getMessage(), e);
+            }
+        }
+    }
+
+} // class CMDIValidatorExecutor
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorException.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorException.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorException.java	(revision 5326)
@@ -0,0 +1,13 @@
+package eu.clarin.cmdi.validator;
+
+@SuppressWarnings("serial")
+public class CMDIValidatorException extends Exception {
+    public CMDIValidatorException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public CMDIValidatorException(String message) {
+        super(message);
+    }
+} // class CMDIValidatorException
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorFactory.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorFactory.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorFactory.java	(revision 5326)
@@ -0,0 +1,221 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.stream.StreamSource;
+
+import net.sf.saxon.s9api.DocumentBuilder;
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XdmDestination;
+import net.sf.saxon.s9api.XdmNode;
+import net.sf.saxon.s9api.XsltCompiler;
+import net.sf.saxon.s9api.XsltExecutable;
+import net.sf.saxon.s9api.XsltTransformer;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class CMDIValidatorFactory {
+    private static final String SCHEMATATRON_STAGE_1 =
+            "/schematron/iso_dsdl_include.xsl";
+    private static final String SCHEMATATRON_STAGE_2 =
+            "/schematron/iso_abstract_expand.xsl";
+    private static final String SCHEMATATRON_STAGE_3 =
+            "/schematron/iso_svrl_for_xslt2.xsl";
+    private static final String DEFAULT_SCHEMATRON_SCHEMA =
+            "/default.sch";
+    private static final Logger logger =
+            LoggerFactory.getLogger(CMDIValidatorFactory.class);
+    private final Processor processor;
+    private final SchemaLoader schemaLoader;
+    private final XsltExecutable schematronValidator;
+    private final List<CMDIValidationPluginFactory> pluginFactories;
+
+    private CMDIValidatorFactory(File cacheDirectory,
+            File schematronSchemaFile, boolean disableSchematron,
+            List<CMDIValidationPluginFactory> pluginFactories)
+            throws CMDIValidatorInitException {
+        /*
+         * initialize custom schema loader
+         */
+        logger.debug("initializing schema loader ...");
+        if (cacheDirectory == null) {
+            if (SystemUtils.IS_OS_WINDOWS &&
+                    (SystemUtils.JAVA_IO_TMPDIR != null)) {
+                cacheDirectory = new File(SystemUtils.JAVA_IO_TMPDIR,
+                        "cmdi-validator");
+            } else if (SystemUtils.IS_OS_UNIX &&
+                    (SystemUtils.USER_HOME != null)) {
+                cacheDirectory = new File(SystemUtils.USER_HOME,
+                        ".cmdi-validator");
+            }
+            if (cacheDirectory != null) {
+                if (!cacheDirectory.exists()) {
+                    if (!cacheDirectory.mkdir()) {
+                        throw new CMDIValidatorInitException(
+                                "cannot create cache directory: " +
+                                        cacheDirectory);
+                    }
+                }
+            } else {
+                if (SystemUtils.JAVA_IO_TMPDIR == null) {
+                    throw new CMDIValidatorInitException(
+                            "cannot determine temporary directory");
+                }
+                cacheDirectory = new File(SystemUtils.JAVA_IO_TMPDIR);
+            }
+        } else {
+            if (!cacheDirectory.isDirectory()) {
+                throw new CMDIValidatorInitException(
+                        "supplied cache dircetory '" +
+                                cacheDirectory.getAbsolutePath() +
+                                "' is not a directory");
+            }
+            if (!cacheDirectory.canWrite()) {
+                throw new CMDIValidatorInitException("cache dircetory '" +
+                        cacheDirectory.getAbsolutePath() + "' is not writable");
+            }
+        }
+        schemaLoader = new SchemaLoader(cacheDirectory,
+                SchemaLoader.DISABLE_CACHE_AGING);
+
+        /*
+         * initialize Saxon processor
+         */
+        logger.debug("initializing Saxon ...");
+        this.processor = new Processor(true);
+
+        /*
+         * initialize Schematron validator
+         */
+        if (!disableSchematron) {
+            logger.debug("initializing Schematron validator ...");
+
+            URL schema = null;
+            if (schematronSchemaFile != null) {
+                if (!schematronSchemaFile.exists()) {
+                    throw new CMDIValidatorInitException("file '" +
+                            schematronSchemaFile.getAbsolutePath() +
+                            "' does not exist");
+                }
+                if (!schematronSchemaFile.isFile()) {
+                    throw new CMDIValidatorInitException("file '" +
+                            schematronSchemaFile.getAbsolutePath() +
+                            "' is not a regular file");
+                }
+                if (!schematronSchemaFile.canRead()) {
+                    throw new CMDIValidatorInitException("file '" +
+                            schematronSchemaFile.getAbsolutePath() +
+                            "' cannot be read");
+                }
+                try {
+                    schema = schematronSchemaFile.toURI().toURL();
+                } catch (MalformedURLException e) {
+                    throw new CMDIValidatorInitException("internal error", e);
+                }
+            } else {
+                schema = this.getClass().getResource(DEFAULT_SCHEMATRON_SCHEMA);
+                if (schema == null) {
+                    throw new CMDIValidatorInitException(
+                            "cannot locate bundled Schematron schema: " +
+                                    DEFAULT_SCHEMATRON_SCHEMA);
+                }
+            }
+            final XsltCompiler compiler = processor.newXsltCompiler();
+            XsltTransformer stage1 =
+                    loadStylesheet(compiler, SCHEMATATRON_STAGE_1);
+            XsltTransformer stage2 =
+                    loadStylesheet(compiler, SCHEMATATRON_STAGE_2);
+            XsltTransformer stage3 =
+                    loadStylesheet(compiler, SCHEMATATRON_STAGE_3);
+            try {
+                XdmDestination destination = new XdmDestination();
+                stage1.setSource(new StreamSource(schema.toExternalForm()));
+                stage1.setDestination(stage2);
+                stage2.setDestination(stage3);
+                stage3.setDestination(destination);
+                stage1.transform();
+                schematronValidator =
+                        compiler.compile(destination.getXdmNode().asSource());
+                logger.debug("Schematron validator successfully initializied");
+            } catch (SaxonApiException e) {
+                throw new CMDIValidatorInitException(
+                        "error compiling schematron rules", e);
+            }
+        } else {
+            logger.debug("disabling Schematron validator");
+            this.schematronValidator = null;
+        }
+
+        /*
+         * store pluginFactories
+         */
+        if ((pluginFactories != null) && !pluginFactories.isEmpty()) {
+            this.pluginFactories = pluginFactories;
+        } else {
+            this.pluginFactories = null;
+        }
+    }
+
+
+    public CMDIValidator newValidator() throws CMDIValidatorInitException {
+        List<CMDIValidationPlugin> plugins = null;
+        if (pluginFactories != null) {
+            plugins = new ArrayList<CMDIValidationPlugin>(pluginFactories.size());
+            for (CMDIValidationPluginFactory pluginFactory : pluginFactories) {
+                plugins.add(pluginFactory.newInstance(processor));
+            }
+        }
+
+        return new CMDIValidator(processor, schemaLoader,
+                schematronValidator, plugins);
+    }
+
+
+    public static CMDIValidatorFactory newInstance(File cacheDircetory,
+            File schematronSchemaFile,
+            boolean disableSchematron,
+            List<CMDIValidationPluginFactory> pluginFactories)
+            throws CMDIValidatorInitException {
+        return new CMDIValidatorFactory(cacheDircetory,
+                schematronSchemaFile,
+                disableSchematron,
+                pluginFactories);
+    }
+
+
+    public static CMDIValidatorFactory newInstance()
+            throws CMDIValidatorInitException {
+        return new CMDIValidatorFactory(null, null, false, null);
+    }
+
+
+    private XsltTransformer loadStylesheet(XsltCompiler compiler, String name)
+            throws CMDIValidatorInitException {
+        try {
+            logger.debug("loading stylesheet '{}'", name);
+            final URL uri = this.getClass().getResource(name);
+            if (uri != null) {
+                DocumentBuilder builder = processor.newDocumentBuilder();
+                XdmNode source =
+                        builder.build(new StreamSource(uri.toExternalForm()));
+                XsltExecutable stylesheet = compiler.compile(source.asSource());
+                return stylesheet.load();
+            } else {
+                throw new CMDIValidatorInitException("cannot find resource '" +
+                        name + "'");
+            }
+        } catch (SaxonApiException e) {
+            throw new CMDIValidatorInitException(
+                    "error loading schematron stylesheet '" + name + "'", e);
+        }
+    }
+
+} // class CMDIValidatorFactory
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorInitException.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorInitException.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorInitException.java	(revision 5326)
@@ -0,0 +1,15 @@
+package eu.clarin.cmdi.validator;
+
+@SuppressWarnings("serial")
+public class CMDIValidatorInitException extends Exception {
+
+    public CMDIValidatorInitException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+
+    public CMDIValidatorInitException(String message) {
+        super(message);
+    }
+
+} // class CMDIValidatorInitException
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJob.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJob.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJob.java	(revision 5326)
@@ -0,0 +1,190 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.FileFilter;
+import java.util.LinkedList;
+import java.util.List;
+
+import net.java.truevfs.access.TFile;
+
+
+public class CMDIValidatorJob {
+    private final CMDIValidatorJobHandler handler;
+    private final FileEnumerator fileEnumerator;
+    private int filesInProcessing = 0;
+    private boolean canceled = false;
+
+
+    public CMDIValidatorJob(TFile root, FileFilter filter,
+            CMDIValidatorJobHandler handler) {
+        if (root == null) {
+            throw new NullPointerException("root = null");
+        }
+
+        /*
+         * XXX: maybe allow null handler or even a list of handlers?
+         */
+        if (handler == null) {
+            throw new NullPointerException("handler == null");
+        }
+        this.handler = handler;
+        this.fileEnumerator = new FileEnumerator(root, filter);
+        this.handler.onJobStarted();
+    }
+
+
+    public CMDIValidatorJob(TFile root, CMDIValidatorJobHandler handler) {
+        this(root, null, handler);
+    }
+
+
+    public void cancel() {
+        synchronized (this) {
+            if (canceled) {
+                throw new IllegalStateException("already canceled");
+            }
+            canceled = true;
+            fileEnumerator.flush();
+            try {
+                this.wait();
+            } catch (InterruptedException e) {
+                /* IGNORE */
+            }
+        }
+    }
+
+
+    final CMDIValidatorJobHandler getHandler() {
+        return handler;
+    }
+
+
+    final TFile getFileForProcessing(List<CMDIValidatorJob> jobList) {
+        synchronized (this) {
+            TFile file = null;
+            if (!canceled) {
+                file = fileEnumerator.nextFile();
+                if (file != null) {
+                    filesInProcessing++;
+                }
+            }
+
+            if (fileEnumerator.isEmpty() || (file == null)) {
+                jobList.remove(this);
+                if (filesInProcessing == 0) {
+                    signalDone();
+                }
+            }
+            return file;
+        } // synchronized (this)
+    }
+
+
+    final boolean returnFileFromProcessing(TFile file) {
+        synchronized (this) {
+            filesInProcessing--;
+            if (filesInProcessing < 0) {
+                throw new IllegalStateException("filesInProcessing < 0");
+            }
+            if (fileEnumerator.isEmpty() && (filesInProcessing == 0)) {
+                signalDone();
+                return true;
+            }
+        } // synchronized (this)
+        return false;
+    }
+
+
+    private void signalDone() {
+        handler.onJobFinished(canceled);
+        if (canceled) {
+            this.notifyAll();
+        }
+    }
+
+
+    private final static class FileEnumerator {
+        private final class FileList {
+            private final TFile[] fileList;
+            private int idx = 0;
+
+
+            private FileList(TFile[] fileList) {
+                this.fileList = fileList;
+            }
+
+
+            private TFile nextFile() {
+                while (idx < fileList.length) {
+                    final TFile file = fileList[idx++];
+                    if (file.isDirectory()) {
+                        return file;
+                    }
+                    if ((filter != null) && !filter.accept(file)) {
+                        continue;
+                    }
+                    return file;
+                } // while
+                return null;
+            }
+
+            private int size() {
+                return (fileList.length - idx);
+            }
+        }
+        private final FileFilter filter;
+        private final LinkedList<FileList> stack =
+                new LinkedList<FileList>();
+
+
+        private FileEnumerator(TFile root, FileFilter filter) {
+            if (root == null) {
+                throw new NullPointerException("root == null");
+            }
+            if (!root.isDirectory()) {
+                throw new IllegalArgumentException("root is not a directory");
+            }
+            this.filter = filter;
+            pushDirectory(root);
+        }
+
+
+        private boolean isEmpty() {
+            return stack.isEmpty();
+        }
+
+
+        private TFile nextFile() {
+            for (;;) {
+                if (stack.isEmpty()) {
+                    break;
+                }
+                final FileList list = stack.peek();
+                final TFile file = list.nextFile();
+                if ((list.size() == 0) || (file == null)) {
+                    stack.pop();
+                    if (file == null) {
+                        continue;
+                    }
+                }
+                if (file.isDirectory()) {
+                    pushDirectory(file);
+                    continue;
+                }
+                return file;
+            }
+            return null;
+        }
+
+        private void flush() {
+            stack.clear();
+        }
+
+        private void pushDirectory(TFile directory) {
+            final TFile[] files = directory.listFiles();
+            if ((files != null) && (files.length > 0)) {
+                stack.push(new FileList(files));
+            }
+        }
+    }
+
+} // class CMDIValidatorJob
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandler.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandler.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandler.java	(revision 5326)
@@ -0,0 +1,16 @@
+package eu.clarin.cmdi.validator;
+
+
+public interface CMDIValidatorJobHandler {
+    public void onJobStarted();
+
+
+    public void onJobFinished(boolean wasCanceled);
+
+
+    public void onValidationSuccess(CMDIValidatorResult result);
+
+
+    public void onValidationFailure(CMDIValidatorResult result);
+
+} // interface CMDIValidatorJobHandler
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandlerAdapter.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandlerAdapter.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorJobHandlerAdapter.java	(revision 5326)
@@ -0,0 +1,25 @@
+package eu.clarin.cmdi.validator;
+
+
+public class CMDIValidatorJobHandlerAdapter implements CMDIValidatorJobHandler {
+
+    @Override
+    public void onJobStarted() {
+    }
+
+
+    @Override
+    public void onJobFinished(boolean wasCanceled) {
+    }
+
+        
+    @Override
+    public void onValidationSuccess(CMDIValidatorResult result) {
+    }
+
+
+    @Override
+    public void onValidationFailure(CMDIValidatorResult result) {
+    }
+
+} // class CMDIValidatorJobHandlerAdapter
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java	(revision 5326)
@@ -0,0 +1,71 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.util.List;
+
+
+public interface CMDIValidatorResult {
+    public enum Severity {
+        INFO {
+            @Override
+            public String getShortcut() {
+                return "I";
+            }
+        },
+        WARNING {
+            @Override
+            public String getShortcut() {
+                return "W";
+            }
+        },
+        ERROR {
+            @Override
+            public String getShortcut() {
+                return "E";
+            }
+        };
+
+        public abstract String getShortcut();
+    } // enum Severity
+
+    public interface Message {
+        public Severity getSeverity();
+
+
+        public int getLineNumber();
+
+
+        public int getColumnNumber();
+
+
+        public String getMessage();
+
+
+        public Throwable getCause();
+    } // interface Message
+
+
+    public File getFile();
+
+
+    public Severity getHighestSeverity();
+
+
+    public boolean isHighestSeverity(Severity severity);
+
+
+    public List<Message> getMessages();
+
+
+    public Message getFirstMessage();
+
+
+    public Message getFirstMessage(Severity severity);
+
+
+    public int getMessageCount();
+
+
+    public int getMessageCount(Severity severity);
+
+} // CMDIValidatorResult
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResultImpl.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResultImpl.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResultImpl.java	(revision 5326)
@@ -0,0 +1,204 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public final class CMDIValidatorResultImpl implements CMDIValidatorResult {
+    private static class MessageImpl implements CMDIValidatorResult.Message {
+        private Severity severity;
+        private int line;
+        private int col;
+        private String message;
+        private Throwable cause;
+
+
+        private MessageImpl(Severity severity, int line, int col, String message,
+                Throwable cause) {
+            this.severity = severity;
+            this.line = line;
+            this.col = col;
+            this.message = message;
+        }
+
+
+        @Override
+        public Severity getSeverity() {
+            return severity;
+        }
+
+
+        @Override
+        public int getLineNumber() {
+            return line;
+        }
+
+
+        @Override
+        public int getColumnNumber() {
+            return col;
+        }
+
+
+        @Override
+        public String getMessage() {
+            return message;
+        }
+
+
+        @Override
+        public Throwable getCause() {
+            return cause;
+        }
+    }
+    private final List<Message> entries = new LinkedList<Message>();
+    private File file;
+    private Severity highestSeverity;
+
+
+    CMDIValidatorResultImpl() {
+        reset();
+    }
+
+
+    @Override
+    public File getFile() {
+        return file;
+    }
+
+
+    @Override
+    public Severity getHighestSeverity() {
+        return highestSeverity;
+    }
+
+
+    @Override
+    public boolean isHighestSeverity(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+        return this.highestSeverity.equals(severity);
+    }
+
+
+    public boolean isEmpty() {
+        return entries.isEmpty();
+    }
+
+
+    @Override
+    public List<Message> getMessages() {
+        if (entries.isEmpty()) {
+            return Collections.emptyList();
+        } else {
+            return Collections.unmodifiableList(entries);
+        }
+    }
+
+
+    @Override
+    public Message getFirstMessage() {
+        return entries.isEmpty() ? null : entries.get(0);
+    }
+
+
+    @Override
+    public Message getFirstMessage(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+
+        if (!entries.isEmpty()) {
+            for (Message msg : entries) {
+                if (severity.equals(msg.getSeverity())) {
+                    return msg;
+                }
+            }
+        }
+        return null;
+    }
+
+
+    @Override
+    public int getMessageCount() {
+        return entries.size();
+    }
+
+
+    @Override
+    public int getMessageCount(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+
+        int count = 0;
+        if (!entries.isEmpty()) {
+            for (Message msg : entries) {
+                if (severity.equals(msg.getSeverity())) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+
+    public void reportInfo(int line, int col, String message) {
+        reportInfo(line, col, message, null);
+    }
+
+
+    public void reportInfo(int line, int col, String message, Throwable cause) {
+        entries.add(new MessageImpl(Severity.INFO, line, col, message, cause));
+    }
+
+
+    public void reportWarning(int line, int col, String message) {
+        reportWarning(line, col, message, null);
+    }
+
+
+    public void reportWarning(int line, int col, String message, Throwable cause) {
+        switch (highestSeverity) {
+        case WARNING:
+            /* FALL-THROUGH */
+        case ERROR:
+            break;
+        default:
+            highestSeverity = Severity.WARNING;
+        }
+        entries.add(new MessageImpl(Severity.WARNING, line, col, message, cause));
+    }
+
+
+    public void reportError(int line, int col, String message) {
+        reportError(line, col, message, null);
+    }
+
+
+    public void reportError(int line, int col, String message, Throwable cause) {
+        switch (highestSeverity) {
+        case ERROR:
+            break;
+        default:
+            highestSeverity = Severity.ERROR;
+        }
+        entries.add(new MessageImpl(Severity.ERROR, line, col, message, cause));
+    }
+
+
+    void setFile(File file) {
+        this.file = file;
+    }
+
+
+    void reset() {
+        this.entries.clear();
+        this.file = null;
+        this.highestSeverity = Severity.INFO;
+    }
+
+} // class CMDIValidatorMessages
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/SchemaLoader.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/SchemaLoader.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/SchemaLoader.java	(revision 5326)
@@ -0,0 +1,214 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import javax.xml.XMLConstants;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.utils.HttpClientUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class SchemaLoader {
+    static final long DISABLE_CACHE_AGING = -1;
+    private static final Logger logger =
+            LoggerFactory.getLogger(SchemaLoader.class);
+    private static final String XML_XSD_RESSOURCE = "/xml.xsd";
+    private final File cacheDirectory;
+    private final long maxCacheAge;
+    private final HttpClient httpClient;
+
+
+    SchemaLoader(File cacheDirectory, long maxCacheAge) {
+        if (cacheDirectory == null) {
+            throw new NullPointerException("cacheDirectory == null");
+        }
+        if (maxCacheAge < -1) {
+            throw new IllegalArgumentException("maxCacheAge < -1");
+        }
+        this.cacheDirectory = cacheDirectory;
+        this.maxCacheAge = maxCacheAge;
+        this.httpClient = new DefaultHttpClient();
+
+        final HttpParams params = this.httpClient.getParams();
+        params.setParameter(CoreProtocolPNames.USER_AGENT,
+                this.getClass().getPackage().getName() + "/0.0.1");
+        params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, Boolean.TRUE);
+        params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
+        params.setIntParameter(ClientPNames.MAX_REDIRECTS, 16);
+    }
+
+
+    public synchronized InputStream loadSchemaFile(String targetNamespace,
+            String schemaLocation) throws IOException {
+        if (targetNamespace == null) {
+            throw new NullPointerException("targetNamespace == null");
+        }
+        if (schemaLocation == null) {
+            throw new NullPointerException("schemaLocation == null");
+        }
+
+        logger.debug("loading schema: targetNamespace={}, location={}",
+                targetNamespace, schemaLocation);
+        InputStream stream = null;
+        if (XMLConstants.XML_NS_URI.equalsIgnoreCase(targetNamespace)) {
+            stream = this.getClass().getResourceAsStream(XML_XSD_RESSOURCE);
+            if (stream != null) {
+                logger.debug("using bundled schema for '{}'", schemaLocation);
+                return stream;
+            }
+            logger.warn("unable to load bundled schema for '{}', " +
+                    "falling back to download.", schemaLocation);
+        }
+
+        final String key = stripBadChars(schemaLocation);
+
+        // fall back to file cache ...
+        final File cacheFile = makeCacheFile(key);
+        if (cacheFile.exists()) {
+            final long age =
+                    System.currentTimeMillis() - cacheFile.lastModified();
+            if ((maxCacheAge != DISABLE_CACHE_AGING) && (age > maxCacheAge)) {
+                logger.debug("-> cached file '{}' expired", cacheFile);
+                cacheFile.delete();
+            } else {
+                logger.debug("-> from file cache");
+                return new FileInputStream(cacheFile);
+            }
+        }
+
+        try {
+            logger.debug("-> downloading schema from '{}'", schemaLocation);
+            final URI uri = new URI(schemaLocation);
+            final HttpResponse response = executeRequest(uri);
+            final HttpEntity entity = response.getEntity();
+            if (entity == null) {
+                throw new IOException("the request returned no message body");
+            }
+
+            try {
+                final InputStream in = entity.getContent();
+
+                final FileOutputStream out =
+                        new FileOutputStream(cacheFile);
+                int read;
+                final byte[] buffer = new byte[4096];
+                while ((read = in.read(buffer)) != -1) {
+                    out.write(buffer, 0, read);
+                }
+                out.close();
+
+                return new FileInputStream(cacheFile);
+            } catch (IllegalStateException e) {
+                throw new IOException("error reading response", e);
+            } catch (IOException e) {
+                /* delete broken cache file */
+                if (cacheFile != null) {
+                    cacheFile.delete();
+                }
+                throw e;
+            } finally {
+                /* make sure to release allocated resources */
+                HttpClientUtils.closeQuietly(response);
+            }
+        } catch (URISyntaxException e) {
+            throw new IOException("schemaLocation uri is invalid: " +
+                    schemaLocation, e);
+        }
+    }
+
+
+    private File makeCacheFile(String key) {
+        return new File(cacheDirectory, key + ".xsd");
+    }
+
+
+    private static String stripBadChars(String uri) {
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < uri.length(); i++) {
+            final char c = uri.charAt(i);
+            switch (c) {
+            case ':':
+                /* FALL-THROUGH */
+            case '/':
+                /* FALL-THROUGH */
+            case '?':
+                /* FALL-THROUGH */
+            case '&':
+                /* FALL-THROUGH */
+            case '=':
+                /* FALL-THROUGH */
+            case '.':
+                /* FALL-THROUGH */
+            case ';':
+                /* FALL-THROUGH */
+            case '"':
+                /* FALL-THROUGH */
+            case '\'':
+                /* FALL-THROUGH */
+            case '\\':
+                sb.append('_');
+                break;
+            default:
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+
+    private HttpResponse executeRequest(URI uri) throws IOException {
+        HttpGet request = null;
+        HttpResponse response = null;
+        try {
+            logger.debug("submitting HTTP request: {}", uri.toString());
+            request = new HttpGet(uri);
+            response = httpClient.execute(request);
+            StatusLine status = response.getStatusLine();
+            if (status.getStatusCode() != HttpStatus.SC_OK) {
+                if (status.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
+                    throw new IOException("not found: " + uri);
+                } else {
+                    throw new IOException("unexpected status: " +
+                            status.getStatusCode());
+                }
+            }
+            return response;
+        } catch (IOException e) {
+            /*
+             * if an error occurred, make sure we are freeing up the resources
+             * we've used
+             */
+            if (response != null) {
+                try {
+                    EntityUtils.consume(response.getEntity());
+                } catch (IOException ex) {
+                    /* IGNORE */
+                }
+
+                /* make sure to release allocated resources */
+                HttpClientUtils.closeQuietly(response);
+            }
+            if (request != null) {
+                request.abort();
+            }
+            throw e;
+        }
+    }
+
+} // class SchemaLoader
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/plugins/CheckPidPluginFactory.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/plugins/CheckPidPluginFactory.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/plugins/CheckPidPluginFactory.java	(revision 5326)
@@ -0,0 +1,214 @@
+package eu.clarin.cmdi.validator.plugins;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpHead;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.client.utils.HttpClientUtils;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.sf.saxon.s9api.Processor;
+import net.sf.saxon.s9api.SaxonApiException;
+import net.sf.saxon.s9api.XPathCompiler;
+import net.sf.saxon.s9api.XPathExecutable;
+import net.sf.saxon.s9api.XPathSelector;
+import net.sf.saxon.s9api.XdmItem;
+import net.sf.saxon.s9api.XdmNode;
+import eu.clarin.cmdi.validator.CMDIValidationPlugin;
+import eu.clarin.cmdi.validator.CMDIValidationPluginFactory;
+import eu.clarin.cmdi.validator.CMDIValidatorException;
+import eu.clarin.cmdi.validator.CMDIValidatorInitException;
+import eu.clarin.cmdi.validator.CMDIValidatorResultImpl;
+import eu.clarin.cmdi.validator.utils.LRUCache;
+
+
+public class CheckPidPluginFactory implements CMDIValidationPluginFactory {
+    private static final String XPATH = "//*:ResourceProxy[*:ResourceType/text() = 'Resource' or *:ResourceType/text() = 'Metadata']/*:ResourceRef/text()";
+    private static final String HDL_SCHEME = "hdl";
+    private static final String HDL_PROXY_HTTP = "http";
+    private static final String HDL_PROXY_HTTPS = "https";
+    private static final String HDL_PROXY_HOST = "hdl.handle.net";
+    private static final String URN_SCHEME = "urn";
+    private static final Logger logger =
+            LoggerFactory.getLogger(CheckPidPlugin.class);
+
+
+    @Override
+    public CMDIValidationPlugin newInstance(final Processor processor)
+            throws CMDIValidatorInitException {
+        return new CheckPidPlugin(processor);
+    }
+
+    public class CheckPidPlugin implements CMDIValidationPlugin {
+        private final HttpClient httpClient;
+        private final XPathExecutable xpath;
+        private final LRUCache<URI, Integer> cache =
+                new LRUCache<URI, Integer>(4*4096);
+
+        private CheckPidPlugin(final Processor processor)
+                throws CMDIValidatorInitException {
+            this.httpClient = new DefaultHttpClient();
+
+            final HttpParams params = this.httpClient.getParams();
+            params.setParameter(CoreProtocolPNames.USER_AGENT,
+                    CheckPidPlugin.class.getPackage().getName() + "/0.0.1");
+            params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, Boolean.TRUE);
+            params.setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);
+            params.setIntParameter(ClientPNames.MAX_REDIRECTS, 16);
+
+            try {
+                final XPathCompiler compiler = processor.newXPathCompiler();
+                this.xpath = compiler.compile(XPATH);
+            } catch (SaxonApiException e) {
+                throw new CMDIValidatorInitException(
+                        "error initializing validation plugin", e);
+            }
+
+        }
+
+
+        @Override
+        public void validate(XdmNode document, CMDIValidatorResultImpl result)
+                throws CMDIValidatorException {
+            try {
+                XPathSelector selector = xpath.load();
+                selector.setContextItem(document);
+                for (XdmItem item : selector) {
+                    String handle = item.getStringValue();
+                    if (handle != null) {
+                        handle = handle.trim();
+                        if (handle.isEmpty()) {
+                            handle = null;
+                        }
+                    }
+
+                    if (handle != null) {
+                        checkHandle(handle, result);
+                    } else {
+                        result.reportError(-1, -1,
+                                "invalid handle (<ResourceRef> was empty)");
+                    }
+                }
+            } catch (SaxonApiException e) {
+                throw new CMDIValidatorException("failed to check handles", e);
+            }
+        }
+
+
+        private void checkHandle(String handle, CMDIValidatorResultImpl result)
+                throws CMDIValidatorException {
+            try {
+                URI uri = new URI(handle);
+                if (HDL_SCHEME.equalsIgnoreCase(uri.getScheme())) {
+                    String path = uri.getSchemeSpecificPart();
+                    if (!path.startsWith("/")) {
+                        path = "/" + path;
+                    }
+                    try {
+                        checkHandle2(new URI(HDL_PROXY_HTTP, HDL_PROXY_HOST,
+                                path, null), result);
+                    } catch (URISyntaxException e) {
+                        throw new CMDIValidatorException(
+                                "created an invalid URI", e);
+                    }
+                } else if (URN_SCHEME.equals(uri.getScheme())) {
+                    result.reportInfo(-1, -1, "PID '" + handle +
+                            "' skipped, because URN resolving is not supported");
+                } else if (HDL_PROXY_HTTP.equalsIgnoreCase(uri.getScheme()) ||
+                        HDL_PROXY_HTTPS.equalsIgnoreCase(uri.getScheme())) {
+                    if (HDL_PROXY_HOST.equalsIgnoreCase(uri.getHost())) {
+                        checkHandle2(uri, result);
+                    } else {
+                        result.reportError(-1, -1,
+                                "PID '" + handle +
+                                "' contains an unexpected host part in the URI: " +
+                                uri.getHost());
+                    }
+                } else {
+                    result.reportError(-1, -1,
+                            "PID '" + handle +
+                            "' contains an unexpected schema part in the URI: " +
+                            uri.getScheme());
+                }
+            } catch (URISyntaxException e) {
+                result.reportError(-1, -1, "PID '" + handle +
+                        "' is not a well-formed URI: " + e.getMessage());
+            }
+        }
+
+
+        private void checkHandle2(URI uri, CMDIValidatorResultImpl result)
+                throws CMDIValidatorException {
+            Integer code = cache.get(uri);
+            if (code == null) {
+                code = checkHandle3(uri, result);
+                // cache result
+                cache.put(uri, code);
+            }
+
+            switch (code) {
+            case HttpStatus.SC_OK:
+                /* no special message in this case */
+                break;
+            case HttpStatus.SC_UNAUTHORIZED:
+                /* FALL-THROUGH */
+            case HttpStatus.SC_FORBIDDEN:
+                result.reportInfo(-1, -1, "PID '" + uri +
+                        "' resolved to an access protected resource (" +
+                        code + ")");
+                break;
+            case HttpStatus.SC_NOT_FOUND:
+                result.reportError(-1, -1, "PID '" + uri +
+                        "' resolved to an non-existing resource (" +
+                        code + ")");
+                break;
+            default:
+                result.reportError(-1, -1, "PID '" + uri +
+                        "' resolved with an unexpected result (" +
+                        code + ")");
+                break;
+            }
+        }
+
+
+        private int checkHandle3(URI uri, CMDIValidatorResultImpl result)
+                throws CMDIValidatorException {
+            HttpHead request = null;
+            HttpResponse response = null;
+            try {
+                request = new HttpHead(uri);
+                response = httpClient.execute(request);
+
+                final StatusLine status = response.getStatusLine();
+                logger.debug("checked handle: file={}, uri={}, status={}",
+                        result.getFile(), uri, status.getStatusCode());
+                return status.getStatusCode();
+            } catch (IOException e) {
+                throw new CMDIValidatorException("error performing handle check", e);
+            } finally {
+                if (response != null) {
+                    try {
+                        EntityUtils.consume(response.getEntity());
+                    } catch (IOException ex) {
+                        /* IGNORE */
+                    }
+
+                    /* make sure to release allocated resources */
+                    HttpClientUtils.closeQuietly(response);
+                }
+            }
+        }
+    }
+
+} // class CheckHandlePluginFactory
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/utils/LRUCache.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/utils/LRUCache.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/utils/LRUCache.java	(revision 5326)
@@ -0,0 +1,23 @@
+package eu.clarin.cmdi.validator.utils;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+@SuppressWarnings("serial")
+public class LRUCache<A, B> extends LinkedHashMap<A, B> {
+    private final int maxEntries;
+
+
+    public LRUCache(final int maxEntries) {
+        super(maxEntries + 1, 1.0f, true);
+        this.maxEntries = maxEntries;
+    }
+
+
+    @Override
+    protected boolean removeEldestEntry(final Map.Entry<A, B> eldest) {
+        return super.size() > maxEntries;
+    }
+
+} // class LRUCache
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/default.sch
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/default.sch	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/default.sch	(revision 5326)
@@ -0,0 +1,19 @@
+<schema xmlns="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
+    <ns uri="http://www.clarin.eu/cmd/" prefix="cmd"/>
+    
+    <pattern>
+        <rule context="cmd:Header" role="warning">
+            <assert test="string-length(cmd:MdProfile/text()) &gt; 0">
+                A CMDI instance should contain a non-empty &lt;cmd:MdProfile&gt; element in &lt;cmd:Header&gt;.
+            </assert>
+        </rule>   
+    </pattern>
+
+    <!--
+    <pattern>
+        <rule context="cmd:Header" role="information">
+            <report test="cmd:MdSelfLink">MdSelfLink "<value-of select="cmd:MdSelfLink"/>".</report>
+        </rule>
+    </pattern>
+    -->
+</schema>
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromRNG-2.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromRNG-2.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromRNG-2.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromXSD-2.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromXSD-2.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/ExtractSchFromXSD-2.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_abstract_expand.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_abstract_expand.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_abstract_expand.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_dsdl_include.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_dsdl_include.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_dsdl_include.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_message_xslt2.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_message_xslt2.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_message_xslt2.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_schematron_skeleton_for_saxon.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_svrl_for_xslt2.xsl
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_svrl_for_xslt2.xsl	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/iso_svrl_for_xslt2.xsl	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/readme.txt
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/readme.txt	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/readme.txt	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-cs.xhtml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-cs.xhtml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-cs.xhtml	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-de.xhtml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-de.xhtml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-de.xhtml	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-en.xhtml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-en.xhtml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-en.xhtml	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-fr.xhtml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-fr.xhtml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-fr.xhtml	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-nl.xhtml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-nl.xhtml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/sch-messages-nl.xhtml	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/schematron-skeleton-api.htm
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/schematron-skeleton-api.htm	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/schematron/schematron-skeleton-api.htm	(revision 5326)
@@ -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: CMDIValidator/trunk/cmdi-validator-core/src/main/resources/xml.xsd
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/resources/xml.xsd	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/resources/xml.xsd	(revision 5326)
@@ -0,0 +1,287 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+  xmlns   ="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+    <h1>About the XML namespace</h1>
+
+    <div class="bodytext">
+     <p>
+      This schema document describes the XML namespace, in a form
+      suitable for import by other schema documents.
+     </p>
+     <p>
+      See <a href="http://www.w3.org/XML/1998/namespace.html">
+      http://www.w3.org/XML/1998/namespace.html</a> and
+      <a href="http://www.w3.org/TR/REC-xml">
+      http://www.w3.org/TR/REC-xml</a> for information 
+      about this namespace.
+     </p>
+     <p>
+      Note that local names in this namespace are intended to be
+      defined only by the World Wide Web Consortium or its subgroups.
+      The names currently defined in this namespace are listed below.
+      They should not be used with conflicting semantics by any Working
+      Group, specification, or document instance.
+     </p>
+     <p>   
+      See further below in this document for more information about <a
+      href="#usage">how to refer to this schema document from your own
+      XSD schema documents</a> and about <a href="#nsversioning">the
+      namespace-versioning policy governing this schema document</a>.
+     </p>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>lang (as an attribute name)</h3>
+      <p>
+       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.</p>
+     
+    </div>
+    <div>
+     <h4>Notes</h4>
+     <p>
+      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.  
+     </p>
+     <p>
+      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+      and the IANA language subtag registry at
+      <a href="http://www.iana.org/assignments/language-subtag-registry">
+       http://www.iana.org/assignments/language-subtag-registry</a>
+      for further information.
+     </p>
+     <p>
+      The union allows for the 'un-declaration' of xml:lang with
+      the empty string.
+     </p>
+    </div>
+   </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:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>space (as an attribute name)</h3>
+      <p>
+       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.</p>
+     
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <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>
+    <div>
+     
+      <h3>base (as an attribute name)</h3>
+      <p>
+       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.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>id (as an attribute name)</h3> 
+      <p>
+       denotes an attribute whose value
+       should be interpreted as if declared to be of type ID.
+       This name is reserved by virtue of its definition in the
+       xml:id specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </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:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+   
+    <h3>Father (in any context at all)</h3> 
+
+    <div class="bodytext">
+     <p>
+      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:
+     </p>
+     <blockquote>
+       <p>
+	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".
+       </p>
+     </blockquote>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div xml:id="usage" id="usage">
+    <h2><a name="usage">About this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      This schema defines attributes and an attribute group suitable
+      for use by schemas wishing to allow <code>xml:base</code>,
+      <code>xml:lang</code>, <code>xml:space</code> or
+      <code>xml:id</code> attributes on elements they define.
+     </p>
+     <p>
+      To enable this, such a schema must import this schema for
+      the XML namespace, e.g. as follows:
+     </p>
+     <pre>
+          &lt;schema . . .>
+           . . .
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     </pre>
+     <p>
+      or
+     </p>
+     <pre>
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     </pre>
+     <p>
+      Subsequently, qualified reference to any of the attributes or the
+      group defined below will have the desired effect, e.g.
+     </p>
+     <pre>
+          &lt;type . . .>
+           . . .
+           &lt;attributeGroup ref="xml:specialAttrs"/>
+     </pre>
+     <p>
+      will define a type which will schema-validate an instance element
+      with any of those attributes.
+     </p>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div id="nsversioning" xml:id="nsversioning">
+    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+    <div class="bodytext">
+     <p>
+      In keeping with the XML Schema WG's standard versioning
+      policy, this schema document will persist at
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a>.
+     </p>
+     <p>
+      At the date of issue it can also be found at
+      <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd</a>.
+     </p>
+     <p>
+      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 <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd 
+      </a> 
+      will change accordingly; the version at 
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd 
+      </a> 
+      will not change.
+     </p>
+     <p>
+      Previous dated (and unchanging) versions of this schema 
+      document are at:
+     </p>
+     <ul>
+      <li><a href="http://www.w3.org/2009/01/xml.xsd">
+	http://www.w3.org/2009/01/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2007/08/xml.xsd">
+	http://www.w3.org/2007/08/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2004/10/xml.xsd">
+	http://www.w3.org/2004/10/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2001/03/xml.xsd">
+	http://www.w3.org/2001/03/xml.xsd</a></li>
+     </ul>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
+
Index: CMDIValidator/trunk/cmdi-validator-core/xerces.patch
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/xerces.patch	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-core/xerces.patch	(revision 5326)
@@ -0,0 +1,33 @@
+Index: src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
+===================================================================
+--- src/org/apache/xerces/impl/xs/XMLSchemaValidator.java   (revision 1584342)
++++ src/org/apache/xerces/impl/xs/XMLSchemaValidator.java   (working copy)
+@@ -1345,8 +1345,11 @@
+ 
+         fIdConstraint = false;
+         //reset XSDDescription
++        fXSDDescription.reset();
+         fLocationPairs.clear();
+         fExpandedLocationPairs.clear();
++        fUnparsedLocations.clear();
++        fGrammarBucket.reset();
+ 
+         // cleanup id table
+         fValidationState.resetIDTables();
+@@ -2693,6 +2696,16 @@
+                 }
+             }
+ 
++            /*
++             * XXX: evil hack to revisit grammar pool with location information
++             */
++            if (grammar == null) {
++                grammar = (SchemaGrammar) fGrammarPool.retrieveGrammar(fXSDDescription);
++                if (grammar != null) {
++                    fXSDDescription.fLocationHints = null;
++                }
++            }
++
+             if (grammar == null || fXSDDescription.fLocationHints != null) {
+                 boolean toParseSchema = true;
+                 if (grammar != null) {
Index: CMDIValidator/trunk/cmdi-validator-tool/src/main/assembly/bin.xml
===================================================================
--- CMDIValidator/trunk/cmdi-validator-tool/src/main/assembly/bin.xml	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-tool/src/main/assembly/bin.xml	(revision 5326)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>bin</id>
+    <formats>
+        <format>tar.gz</format>
+        <!--
+        <format>zip</format>
+        -->
+    </formats>
+    <baseDirectory>${project.artifactId}</baseDirectory>
+    <files>
+        <file>
+            <source>src/main/bin/cmdi-validator.sh</source>
+            <outputDirectory>bin</outputDirectory>
+            <destName>cmdi-validator</destName>
+            <fileMode>755</fileMode>
+            <lineEnding>unix</lineEnding>
+        </file>
+    </files>
+    <fileSets>
+        <!-- hack to create empty "endorsed" directory -->
+        <fileSet>
+            <directory>src/main/bin/</directory>
+            <outputDirectory>lib/endorsed</outputDirectory>
+            <directoryMode>0755</directoryMode>
+            <excludes>
+                <exclude>*</exclude>
+            </excludes>
+        </fileSet>
+    </fileSets>
+    <dependencySets>
+        <dependencySet>
+            <useProjectArtifact>true</useProjectArtifact>
+            <useTransitiveDependencies>true</useTransitiveDependencies>
+            <outputDirectory>lib</outputDirectory>
+            <directoryMode>0755</directoryMode>
+            <fileMode>0644</fileMode>
+            <excludes>
+                <exclude>*:sources</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+</assembly>
Index: CMDIValidator/trunk/cmdi-validator-tool/src/main/bin/cmdi-validator.sh
===================================================================
--- CMDIValidator/trunk/cmdi-validator-tool/src/main/bin/cmdi-validator.sh	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-tool/src/main/bin/cmdi-validator.sh	(revision 5326)
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+PRG=`readlink -f $0`
+DIRNAME=`dirname ${PRG}`
+DIRNAME=`readlink -f "${DIRNAME}/../lib/"`
+
+CP=""
+for JAR in ${DIRNAME}/*.jar; do
+    JAR=`readlink -f ${JAR}`
+    if [ -z "${CP}" ]; then
+        CP="${JAR}"
+    else 
+        CP="${CP}":"${JAR}"
+    fi
+done
+
+if [ ! -z "${SAXON_HOME}" ]; then
+    for JAR in ${SAXON_HOME}/*.jar; do
+        JAR=`readlink -f ${JAR}`
+        CP="${JAR}":"${CP}"
+    done
+fi
+
+if [ -d ${DIRNAME}/endorsed ]; then
+    for JAR in ${DIRNAME}/endorsed/*.jar; do
+        JAR=`readlink -f ${JAR}`
+        CP="${JAR}":"${CP}"
+    done
+fi
+
+VM_OPTS=""
+if java -version 2>&1 | grep -q -i '64-bit'; then
+  VM_OPTS="-d64 $VM_OPTS"
+fi
+exec java ${VM_OPTS} -cp "${CP}" eu.clarin.cmdi.validator.tool.CMDIValidatorTool "$@"
Index: CMDIValidator/trunk/cmdi-validator-tool/src/main/java/eu/clarin/cmdi/validator/tool/CMDIValidatorTool.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-tool/src/main/java/eu/clarin/cmdi/validator/tool/CMDIValidatorTool.java	(revision 5326)
+++ CMDIValidator/trunk/cmdi-validator-tool/src/main/java/eu/clarin/cmdi/validator/tool/CMDIValidatorTool.java	(revision 5326)
@@ -0,0 +1,583 @@
+package eu.clarin.cmdi.validator.tool;
+
+import humanize.Humanize;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import net.java.truevfs.access.TFile;
+import net.java.truevfs.access.TVFS;
+import net.java.truevfs.kernel.spec.FsSyncException;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import eu.clarin.cmdi.validator.CMDIValidationPluginFactory;
+import eu.clarin.cmdi.validator.CMDIValidator;
+import eu.clarin.cmdi.validator.CMDIValidatorEngine;
+import eu.clarin.cmdi.validator.CMDIValidatorFactory;
+import eu.clarin.cmdi.validator.CMDIValidatorInitException;
+import eu.clarin.cmdi.validator.CMDIValidatorJob;
+import eu.clarin.cmdi.validator.CMDIValidatorJobHandlerAdapter;
+import eu.clarin.cmdi.validator.CMDIValidatorResult;
+import eu.clarin.cmdi.validator.CMDIValidatorResult.Message;
+import eu.clarin.cmdi.validator.CMDIValidatorResult.Severity;
+import eu.clarin.cmdi.validator.plugins.CheckPidPluginFactory;
+
+
+public class CMDIValidatorTool {
+    private static final String PRG_NAME                = "cmdi-validator";
+    private static final long DEFAULT_PROGRESS_INTERVAL = 15000;
+    private static final Locale LOCALE                  = Locale.ENGLISH;
+    private static final char OPT_DEBUG                 = 'd';
+    private static final char OPT_QUIET                 = 'q';
+    private static final char OPT_VERBOSE               = 'v';
+    private static final char OPT_NO_PROGRESS           = 'P';
+    private static final char OPT_THREAD_COUNT          = 't';
+    private static final char OPT_NO_THREADS            = 'T';
+    private static final char OPT_NO_ESTIMATE           = 'E';
+    private static final char OPT_SCHEMA_CACHE_DIR      = 'c';
+    private static final char OPT_NO_SCHEMATRON         = 'S';
+    private static final char OPT_SCHEMATRON_FILE       = 's';
+    private static final char OPT_CHECK_PIDS            = 'p';
+    private static final Logger logger =
+            LoggerFactory.getLogger(CMDIValidatorTool.class);
+    private static final org.apache.log4j.ConsoleAppender appender;
+
+
+    public static void main(String[] args) {
+        /*
+         * application defaults
+         */
+        boolean debugging         = false;
+        boolean quiet             = false;
+        boolean verbose           = false;
+        int threadCount           = Runtime.getRuntime().availableProcessors();
+        boolean estimate          = true;
+        long progressInterval     = DEFAULT_PROGRESS_INTERVAL;
+        File schemaCacheDir       = null;
+        boolean disableSchematron = false;
+        File schematronFile       = null;
+        boolean checkPids         = false;
+
+        /*
+         * setup command line parser
+         */
+        final Options options = createCommandLineOptions();
+        try {
+            final CommandLineParser parser = new GnuParser();
+            final CommandLine line = parser.parse(options, args);
+            // check incompatible combinations
+            if (line.hasOption(OPT_THREAD_COUNT) && line.hasOption(OPT_NO_THREADS)) {
+                throw new ParseException("The -t and -T options are mutually exclusive");
+            }
+            if (line.hasOption(OPT_DEBUG) && line.hasOption(OPT_QUIET)) {
+                throw new ParseException("The -d and -q switches are mutually exclusive");
+            }
+            if (line.hasOption(OPT_VERBOSE) && line.hasOption(OPT_QUIET)) {
+                throw new ParseException("The -v and -q switches are mutually exclusive");
+            }
+            if (line.hasOption(OPT_NO_SCHEMATRON) && line.hasOption(OPT_SCHEMATRON_FILE)) {
+                throw new ParseException("The -s and -T options are mutually exclusive");
+            }
+            // extract options
+            if (line.hasOption(OPT_DEBUG)) {
+                debugging = true;
+            }
+            if (line.hasOption(OPT_QUIET)) {
+                quiet = true;
+            }
+            if (line.hasOption(OPT_VERBOSE)) {
+                verbose = true;
+            }
+            if (line.hasOption(OPT_NO_PROGRESS) || quiet) {
+                progressInterval = -1;
+            }
+            if (line.hasOption(OPT_THREAD_COUNT)) {
+                try {
+                    threadCount = Integer.parseInt(
+                            line.getOptionValue(OPT_THREAD_COUNT));
+                    if (threadCount < 1) {
+                        throw new ParseException(
+                                "thread count must be larger then 0");
+                    }
+                } catch (NumberFormatException e) {
+                    throw new ParseException("invalid number");
+                }
+            }
+            if (line.hasOption(OPT_NO_THREADS)) {
+                threadCount = 1;
+            }
+            if (line.hasOption(OPT_NO_ESTIMATE) || (progressInterval < 0)) {
+                estimate = false;
+            }
+            if (line.hasOption(OPT_SCHEMA_CACHE_DIR)) {
+                String dir = line.getOptionValue(OPT_SCHEMA_CACHE_DIR);
+                if ((dir == null) || dir.isEmpty()) {
+                    throw new ParseException("invalid argument for -" +
+                            OPT_SCHEMA_CACHE_DIR);
+                }
+                schemaCacheDir = new File(dir);
+            }
+            if (line.hasOption(OPT_NO_SCHEMATRON)) {
+                disableSchematron = true;
+            }
+            if (line.hasOption(OPT_SCHEMATRON_FILE)) {
+                String name = line.getOptionValue(OPT_SCHEMATRON_FILE);
+                if ((name == null) || name.isEmpty()) {
+                    throw new ParseException("invalid argument for -" +
+                            OPT_SCHEMATRON_FILE);
+                }
+                schematronFile = new File(name);
+            }
+            if (line.hasOption(OPT_CHECK_PIDS)) {
+                checkPids = true;
+            }
+
+            final String[] remaining = line.getArgs();
+            if ((remaining == null) || (remaining.length == 0)) {
+                throw new ParseException("require <DIRECTORY> or <FILE> as " +
+                        "additional command line parameter");
+            }
+
+            final org.apache.log4j.Logger log =
+                    org.apache.log4j.Logger.getLogger(
+                            CMDIValidator.class.getPackage().getName());
+            if (debugging) {
+                appender.setLayout(
+                        new org.apache.log4j.PatternLayout("[%p] %t: %m%n"));
+                log.setLevel(org.apache.log4j.Level.DEBUG);
+            } else {
+                if (quiet) {
+                    log.setLevel(org.apache.log4j.Level.ERROR);
+                } else {
+                    log.setLevel(org.apache.log4j.Level.INFO);
+                }
+            }
+
+            TFile archive = null;
+            try {
+                /*
+                 * initialize CMDIValidatorFactory
+                 */
+                if (schemaCacheDir != null) {
+                    logger.info("using schema cache directory: {}", schemaCacheDir);
+                }
+                if (schematronFile != null) {
+                    logger.info("using Schematron schema from file: {}", schematronFile);
+                }
+
+                List<CMDIValidationPluginFactory> pluginFactories =
+                        new ArrayList<CMDIValidationPluginFactory>();
+                if (checkPids) {
+                    logger.info("performing PID checking");
+                    pluginFactories.add(new CheckPidPluginFactory());
+                }
+
+                final CMDIValidatorFactory factory =
+                        CMDIValidatorFactory.newInstance(schemaCacheDir,
+                                schematronFile,
+                                disableSchematron,
+                                pluginFactories);
+
+                /*
+                 * process archive
+                 */
+                archive = new TFile(remaining[0]);
+
+                if (archive.exists()) {
+                    if (archive.isArchive()) {
+                        logger.info("reading archive '{}'", archive);
+                    } else {
+                        logger.info("reading directory '{}'", archive);
+                    }
+
+                    int totalFileCount = -1;
+                    if (estimate && logger.isInfoEnabled()) {
+                        logger.debug("counting files ...");
+                        totalFileCount = countFiles(archive);
+                    }
+
+                    if (threadCount > 1) {
+                      logger.debug("using {} threads", threadCount);
+                    }
+
+                    final CMDIValidatorEngine engine =
+                            new CMDIValidatorEngine(factory, threadCount);
+                    final JobHandler handler = new JobHandler(verbose);
+                    final CMDIValidatorJob job =
+                            new CMDIValidatorJob(archive, handler);
+                    try {
+                        engine.start();
+                        logger.debug("submitting batch validation job ...");
+                        engine.submit(job);
+
+                        /*
+                         * Wait until validation is done and report about
+                         * progress every now and then ...
+                         */
+                        for (;;) {
+                            try {
+                                if (handler.await(progressInterval)) {
+                                    break;
+                                }
+                            } catch (InterruptedException e) {
+                                /* IGNORE */
+                            }
+                            if ((progressInterval > 0) && logger.isInfoEnabled()) {
+                                final long now = System.currentTimeMillis();
+                                int fps    = -1;
+                                long bps   = -1;
+                                int count  = 0;
+                                long delta = -1;
+                                synchronized (handler) {
+                                    delta = (now - handler.getTimeStarted()) / 1000;
+                                    if (delta > 0) {
+                                        fps = (int) (handler.getTotalFileCount() / delta);
+                                        bps = (handler.getTotalBytes() / delta);
+                                    }
+                                    count = handler.getTotalFileCount();
+                                } // synchronized (result)
+                                if (totalFileCount > 0) {
+                                    float complete = (count / (float)  totalFileCount) * 100f;
+                                    logger.info("processed {} files ({}%) in {} ({} files/second, {}/second) ...",
+                                            count,
+                                            String.format(LOCALE, "%.2f", complete),
+                                            Humanize.duration(delta, LOCALE),
+                                            ((fps != -1) ? fps : "N/A"),
+                                            ((bps != -1) ? Humanize.binaryPrefix(bps, LOCALE) : "N/A MB"));
+                                } else {
+                                    logger.info("processed {} files in {} ({} files/second, {}/second) ...",
+                                            count,
+                                            Humanize.duration(delta, LOCALE),
+                                            ((fps != -1) ? fps : "N/A"),
+                                            ((bps != -1) ? Humanize.binaryPrefix(bps, LOCALE) : "N/A MB"));
+                                }
+                            }
+                        } // for (;;)
+                    } finally {
+                        engine.shutdown();
+                    }
+
+                    int fps = -1;
+                    long bps = -1;
+                    if (handler.getTimeElapsed() > 0) {
+                        fps = (int) (handler.getTotalFileCount() / handler.getTimeElapsed());
+                        bps = handler.getTotalBytes() / handler.getTimeElapsed();
+                    }
+
+                    logger.info("time elapsed: {}, validation result: {}% failure rate (files: {} total, {} passed, {} failed; {} total, {} files/second, {}/second)",
+                            Humanize.duration(handler.getTimeElapsed(), LOCALE),
+                            String.format(LOCALE, "%.2f", handler.getFailureRate() * 100f),
+                            handler.getTotalFileCount(),
+                            handler.getValidFileCount(),
+                            handler.getInvalidFileCount(),
+                            Humanize.binaryPrefix(handler.getTotalBytes(), LOCALE),
+                            ((fps != -1) ? fps : "N/A"),
+                            ((bps != -1) ? Humanize.binaryPrefix(bps, LOCALE) : "N/A MB"));
+                    logger.debug("... done");
+                } else {
+                    logger.error("not found: {}", archive);
+                }
+            } finally {
+                if (archive != null) {
+                    try {
+                        TVFS.umount(archive);
+                    } catch (FsSyncException e) {
+                        logger.error("error unmounting archive", e);
+                    }
+                }
+            }
+        } catch (CMDIValidatorInitException e) {
+            logger.error("error initializing validator: {}", e.getMessage());
+            if (debugging) {
+                logger.error(e.getMessage(), e);
+            }
+            System.exit(2);
+        } catch (ParseException e) {
+            PrintWriter writer = new PrintWriter(System.err);
+            if (e.getMessage() != null) {
+                writer.print("ERROR: ");
+                writer.println(e.getMessage());
+            }
+            HelpFormatter formatter = new HelpFormatter();
+            formatter.printHelp(writer, HelpFormatter.DEFAULT_WIDTH, PRG_NAME,
+                    null, options, HelpFormatter.DEFAULT_LEFT_PAD,
+                    HelpFormatter.DEFAULT_DESC_PAD, null, true);
+            writer.flush();
+            writer.close();
+            System.exit(64); /* EX_USAGE */
+        }
+    }
+
+
+    @SuppressWarnings("static-access")
+    private static Options createCommandLineOptions() {
+        final Options options = new Options();
+        OptionGroup g1 = new OptionGroup();
+        g1.addOption(OptionBuilder
+                .withDescription("enable debugging output")
+                .withLongOpt("debug")
+                .create(OPT_DEBUG));
+        g1.addOption(OptionBuilder
+                .withDescription("be quiet")
+                .withLongOpt("quiet")
+                .create(OPT_QUIET));
+        options.addOptionGroup(g1);
+        options.addOption(OptionBuilder
+                .withDescription("be verbose")
+                .withLongOpt("verbose")
+                .create(OPT_VERBOSE));
+        options.addOption(OptionBuilder
+                .withDescription("no progress reporting")
+                .withLongOpt("no-progress")
+                .create(OPT_NO_PROGRESS));
+        OptionGroup g2 = new OptionGroup();
+        g2.addOption(OptionBuilder
+                .withDescription("number of validator threads")
+                .hasArg()
+                .withArgName("COUNT")
+                .withLongOpt("threads")
+                .create(OPT_THREAD_COUNT));
+        g2.addOption(OptionBuilder
+                .withDescription("disable threading")
+                .withLongOpt("no-threads")
+                .create(OPT_NO_THREADS));
+        options.addOptionGroup(g2);
+        options.addOption(OptionBuilder
+            .withDescription("disable gathering of total file count for progress reporting")
+            .withLongOpt("no-estimate")
+            .create(OPT_NO_ESTIMATE));
+        options.addOption(OptionBuilder
+                .withDescription("schema caching directory")
+                .hasArg()
+                .withArgName("DIRECTORY")
+                .withLongOpt("schema-cache-dir")
+                .create(OPT_SCHEMA_CACHE_DIR));
+        OptionGroup g3 = new OptionGroup();
+        g3.addOption(OptionBuilder
+                .withDescription("disable Schematron validator")
+                .withLongOpt("no-schematron")
+                .create(OPT_NO_SCHEMATRON));
+        g3.addOption(OptionBuilder
+                .withDescription("load Schematron schema from file")
+                .hasArg()
+                .withArgName("FILE")
+                .withLongOpt("schematron-file")
+                .create(OPT_SCHEMATRON_FILE));
+        options.addOptionGroup(g3);
+        options.addOption(OptionBuilder
+                .withDescription("check if persistent identifiers resolve correctly")
+                .withLongOpt("check-pids")
+                .create(OPT_CHECK_PIDS));
+        return options;
+    }
+
+
+    private static final int countFiles(TFile directory) {
+        int count = 0;
+        final TFile[] entries = directory.listFiles();
+        if ((entries != null) && (entries.length > 0)) {
+            for (TFile entry : entries) {
+                if (entry.isDirectory()) {
+                    count += countFiles(entry);
+                } else {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+
+    private static class JobHandler extends CMDIValidatorJobHandlerAdapter {
+        private final boolean verbose;
+        private long started     = System.currentTimeMillis();
+        private long finished    = -1;
+        private int filesTotal   = 0;
+        private int filesInvalid = 0;
+        private long totalBytes  = 0;
+        private boolean isCompleted = false;
+        private final Object waiter = new Object();
+
+
+        private JobHandler(boolean verbose) {
+            this.verbose = verbose;
+        }
+
+
+        public long getTimeStarted() {
+            return started;
+        }
+
+
+        public long getTimeElapsed() {
+            long duration = (finished != -1)
+                    ? (finished - started)
+                    : (System.currentTimeMillis() - started);
+            return TimeUnit.MILLISECONDS.toSeconds(duration);
+        }
+
+
+        public int getTotalFileCount() {
+            return filesTotal;
+        }
+
+
+        public int getValidFileCount() {
+            return filesTotal - filesInvalid;
+        }
+
+        public int getInvalidFileCount() {
+            return filesInvalid;
+        }
+
+
+        public float getFailureRate() {
+            return (filesTotal > 0)
+                    ? ((float) filesInvalid / (float) filesTotal)
+                    : 0.0f;
+        }
+
+
+        public long getTotalBytes() {
+            return totalBytes;
+        }
+
+
+        public boolean await(long timeout) throws InterruptedException {
+            synchronized (waiter) {
+                if (isCompleted) {
+                    return true;
+                }
+                if (timeout > 0) {
+                    waiter.wait(timeout);
+                } else {
+                    waiter.wait();
+                }
+                return isCompleted;
+            }
+        }
+
+
+        @Override
+        public void onJobFinished(boolean wasCancled) {
+            finished = System.currentTimeMillis();
+            synchronized (waiter) {
+                isCompleted = true;
+                waiter.notifyAll();
+            } // synchronized (waiter)
+            if (wasCancled) {
+                logger.info("processing was canceled ...");
+            }
+        }
+
+
+        @Override
+        public void onValidationSuccess(CMDIValidatorResult result) {
+            final File file = result.getFile();
+            synchronized (this) {
+                filesTotal++;
+                if (file != null) {
+                    totalBytes += file.length();
+                }
+            } // synchronized (this) {
+
+            if (result.isHighestSeverity(Severity.WARNING)) {
+                if (verbose) {
+                    logger.warn("file '{}' is valid (with warnings):", file);
+                    for (Message msg : result.getMessages()) {
+                        if ((msg.getLineNumber() != -1) &&
+                                (msg.getColumnNumber() != -1)) {
+                            logger.warn(" ({}) {} [line={}, column={}]",
+                                    msg.getSeverity().getShortcut(),
+                                    msg.getMessage(),
+                                    msg.getLineNumber(),
+                                    msg.getColumnNumber());
+                        } else {
+                            logger.warn(" ({}) {}",
+                                    msg.getSeverity().getShortcut(),
+                                    msg.getMessage());
+                        }
+                    }
+                } else {
+                    Message msg = result.getFirstMessage(Severity.WARNING);
+                    int count   = result.getMessageCount(Severity.WARNING);
+                    if (count > 1) {
+                        logger.warn("file '{}' is valid (with warnings): {} ({} more warnings)",
+                                file, msg.getMessage(), (count - 1));
+                    } else {
+                        logger.warn("file '{}' is valid (with warnings): {}",
+                                file, msg.getMessage());
+                    }
+                }
+            } else {
+                logger.debug("file '{}' is valid", file, result.getFile());
+            }
+        }
+
+
+        @Override
+        public void onValidationFailure(CMDIValidatorResult result) {
+            final File file = result.getFile();
+            synchronized (this) {
+                filesTotal++;
+                filesInvalid++;
+                if (file != null) {
+                    totalBytes += file.length();
+                }
+            } // synchronized (this)
+
+            if (verbose) {
+            logger.error("file '{}' is invalid:", file);
+                for (Message msg : result.getMessages()) {
+                    if ((msg.getLineNumber() != -1) &&
+                            (msg.getColumnNumber() != -1)) {
+                        logger.error(" ({}) {} [line={}, column={}]",
+                                msg.getSeverity().getShortcut(),
+                                msg.getMessage(),
+                                msg.getLineNumber(),
+                                msg.getColumnNumber());
+                    } else {
+                        logger.error(" ({}) {}",
+                                msg.getSeverity().getShortcut(),
+                                msg.getMessage());
+                    }
+                }
+            } else {
+                Message msg = result.getFirstMessage(Severity.ERROR);
+                int count   = result.getMessageCount(Severity.ERROR);
+                if (count > 1) {
+                    logger.error("file '{}' is invalid: {} ({} more errors)",
+                            file, msg.getMessage(), (count - 1));
+                } else {
+                    logger.error("file '{}' is invalid: {}",
+                            file, msg.getMessage());
+                }
+            }
+        }
+    } // class JobHandler
+
+
+    static {
+        appender = new org.apache.log4j.ConsoleAppender(
+                new org.apache.log4j.PatternLayout("%m%n"),
+                org.apache.log4j.ConsoleAppender.SYSTEM_OUT);
+        org.apache.log4j.BasicConfigurator.configure(appender);
+        org.apache.log4j.Logger logger =
+                org.apache.log4j.Logger.getRootLogger();
+        logger.setLevel(org.apache.log4j.Level.WARN);
+    }
+
+} // class CMDIValidatorTool
Index: CMDIValidator/trunk/pom.xml
===================================================================
--- CMDIValidator/trunk/pom.xml	(revision 5311)
+++ CMDIValidator/trunk/pom.xml	(revision 5326)
@@ -1,224 +1,68 @@
-<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>eu.clarin.cmdi</groupId>
-	<artifactId>cmdi-validator</artifactId>
-	<version>0.0.2-SNAPSHOT</version>
+<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>eu.clarin.cmdi</groupId>
+    <artifactId>cmdi-validator</artifactId>
+    <version>0.0.3-SNAPSHOT</version>
+    <packaging>pom</packaging>
 
-	<properties>
-		<!-- project settings -->
-		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-		<!-- plug-in settings -->
-		<maven.compiler.source>1.6</maven.compiler.source>
-		<maven.compiler.target>1.6</maven.compiler.target>
-		<!-- versions of dependencies -->
-		<slf4j.version>1.7.6</slf4j.version>
-		<truevfs.version>0.10.6</truevfs.version>
-		<truecommons.version>2.3.4</truecommons.version>
-	</properties>
+    <modules>
+        <module>cmdi-validator-core</module>
+        <module>cmdi-validator-tool</module>
+    </modules>
 
-	<dependencies>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-api</artifactId>
-			<version>${slf4j.version}</version>
-		</dependency>
+    <properties>
+        <!-- project settings -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <!-- plug-in settings -->
+        <maven.compiler.source>1.6</maven.compiler.source>
+        <maven.compiler.target>1.6</maven.compiler.target>
+        <!-- versions of common dependencies -->
+        <slf4j.version>1.7.7</slf4j.version>
+    </properties>
 
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-log4j12</artifactId>
-			<version>${slf4j.version}</version>
-		</dependency>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>${slf4j.version}</version>
+            </dependency>
 
-		<dependency>
-			<groupId>org.apache.httpcomponents</groupId>
-			<artifactId>httpclient</artifactId>
-			<version>4.2.5</version>
-		</dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-log4j12</artifactId>
+                <version>${slf4j.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
 
-		<dependency>
-			<groupId>commons-cli</groupId>
-			<artifactId>commons-cli</artifactId>
-			<version>1.2</version>
-		</dependency>
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>2.5.1</version>
+                    <configuration>
+                        <source>${maven.compiler.source}</source>
+                        <target>${maven.compiler.target}</target>
+                    </configuration>
+                </plugin>
 
-        <dependency>
-            <groupId>com.github.mfornos</groupId>
-            <artifactId>humanize-slim</artifactId>
-            <version>1.1.5</version>
-        </dependency>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>2.9</version>
+                </plugin>
 
- 		<dependency>
-			<groupId>xerces</groupId>
-			<artifactId>xercesImpl-patched</artifactId>
-			<version>2.11.0</version>
-		</dependency>
-
-        <!-- required for Xerces (patched version has no proper dependencies) -->
-        <dependency>
-            <groupId>xml-apis</groupId>
-            <artifactId>xml-apis</artifactId>
-            <version>1.4.01</version>
-        </dependency>
-
- 		<dependency>
-			<groupId>net.sf.saxon</groupId>
-			<artifactId>Saxon-HE</artifactId>
-			<version>9.5.1-4</version>
-		</dependency>
-
-		<!-- TrueVFS -->
-		<dependency>
-			<groupId>net.java.truevfs</groupId>
-			<artifactId>truevfs-access</artifactId>
-			<version>${truevfs.version}</version>
-		</dependency>
-
-		<dependency>
-			<groupId>net.java.truevfs</groupId>
-			<artifactId>truevfs-kernel-impl</artifactId>
-			<version>${truevfs.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>net.java.truevfs</groupId>
-			<artifactId>truevfs-ext-logging</artifactId>
-			<version>${truevfs.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>net.java.truevfs</groupId>
-			<artifactId>truevfs-driver-file</artifactId>
-			<version>${truevfs.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>net.java.truevfs</groupId>
-			<artifactId>truevfs-driver-zip</artifactId>
-			<version>${truevfs.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>net.java.truecommons</groupId>
-			<artifactId>truecommons-key-default</artifactId>
-			<version>${truecommons.version}</version>
-			<scope>runtime</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-lang3</artifactId>
-			<version>3.1</version>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-math3</artifactId>
-			<version>3.2</version>
-		</dependency>
-	</dependencies>
-
-	<repositories>
-		<repository>
-			<id>lib</id>
-			<url>file://${basedir}/lib</url>
-		</repository>
-	</repositories>
-
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<version>2.5.1</version>
-				<configuration>
-					<source>${maven.compiler.source}</source>
-					<target>${maven.compiler.target}</target>
-				</configuration>
-			</plugin>
-
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-jar-plugin</artifactId>
-				<version>2.4</version>
-				<configuration>
-					<archive>
-						<manifest>
-							<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-							<mainClass>eu.clarin.cmdi.validator.CMDIValidatorTool</mainClass>
-						</manifest>
-					</archive>
-				</configuration>
-			</plugin>
-
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-assembly-plugin</artifactId>
-				<version>2.4</version>
-				<executions>
-					<execution>
-						<id>assemble-binary</id>
-						<phase>package</phase>
-						<goals>
-							<goal>single</goal>
-						</goals>
-					</execution>
-				</executions>
-				<configuration>
-					<descriptors>
-						<descriptor>src/main/assembly/bin.xml</descriptor>
-					</descriptors>
-				</configuration>
-			</plugin>
-		</plugins>
-
-		<pluginManagement>
-			<plugins>
-				<!-- This plugin's configuration is used to store Eclipse m2e settings 
-					only. It has no influence on the Maven build itself. -->
-				<plugin>
-					<groupId>org.eclipse.m2e</groupId>
-					<artifactId>lifecycle-mapping</artifactId>
-					<version>1.0.0</version>
-					<configuration>
-						<lifecycleMappingMetadata>
-							<pluginExecutions>
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.apache.maven.plugins</groupId>
-										<artifactId>maven-jar-plugin</artifactId>
-										<versionRange>[0.0,)</versionRange>
-										<goals>
-											<goal>jar</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore />
-									</action>
-								</pluginExecution>
-
-								<pluginExecution>
-									<pluginExecutionFilter>
-										<groupId>org.apache.maven.plugins</groupId>
-										<artifactId>maven-assembly-plugin</artifactId>
-										<versionRange>[0.0,)</versionRange>
-										<goals>
-											<goal>single</goal>
-										</goals>
-									</pluginExecutionFilter>
-									<action>
-										<ignore />
-									</action>
-								</pluginExecution>
-							</pluginExecutions>
-						</lifecycleMappingMetadata>
-					</configuration>
-				</plugin>
-			</plugins>
-		</pluginManagement>
-	</build>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>2.2</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
 </project>
Index: CMDIValidator/trunk/xerces.patch
===================================================================
--- CMDIValidator/trunk/xerces.patch	(revision 5311)
+++ 	(revision )
@@ -1,33 +1,0 @@
-Index: src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
-===================================================================
---- src/org/apache/xerces/impl/xs/XMLSchemaValidator.java   (revision 1584342)
-+++ src/org/apache/xerces/impl/xs/XMLSchemaValidator.java   (working copy)
-@@ -1345,8 +1345,11 @@
- 
-         fIdConstraint = false;
-         //reset XSDDescription
-+        fXSDDescription.reset();
-         fLocationPairs.clear();
-         fExpandedLocationPairs.clear();
-+        fUnparsedLocations.clear();
-+        fGrammarBucket.reset();
- 
-         // cleanup id table
-         fValidationState.resetIDTables();
-@@ -2693,6 +2696,16 @@
-                 }
-             }
- 
-+            /*
-+             * XXX: evil hack to revisit grammar pool with location information
-+             */
-+            if (grammar == null) {
-+                grammar = (SchemaGrammar) fGrammarPool.retrieveGrammar(fXSDDescription);
-+                if (grammar != null) {
-+                    fXSDDescription.fLocationHints = null;
-+                }
-+            }
-+
-             if (grammar == null || fXSDDescription.fLocationHints != null) {
-                 boolean toParseSchema = true;
-                 if (grammar != null) {
