/* FullSyntaxBuilder.java -- 
   Copyright (C) 2006  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.validation.relaxng;

import java.io.InputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.relaxng.datatype.DatatypeException;
import org.relaxng.datatype.DatatypeLibrary;
import org.relaxng.datatype.helpers.DatatypeLibraryLoader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import gnu.xml.stream.XMLParser;

/**
 * Parses a RELAX NG XML DOM tree, constructing a compiled internal
 * representation.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class FullSyntaxBuilder
{

  /**
   * Complete vocabulary (elements and attributes) of the full syntax.
   */
  static final Map VOCABULARY = new HashMap();
  static final Set STRIPPED_ATTRIBUTES = new HashSet();
  static final Set PATTERN_ELEMENTS = new HashSet();
  static
  {
    Set elementAttrs = Collections.singleton("name");
    Set dataAttrs = new HashSet();
    dataAttrs.add("type");
    dataAttrs.add("datatypeLibrary");
    Set valueAttrs = new HashSet();
    valueAttrs.add("type");
    valueAttrs.add("datatypeLibrary");
    valueAttrs.add("ns");
    Set externalAttrs = Collections.singleton("href");
    Set startAttrs = Collections.singleton("combine");
    Set defineAttrs = new HashSet();
    defineAttrs.add("name");
    defineAttrs.add("combine");
    Set nsAttrs = Collections.singleton("ns");
    
    VOCABULARY.put("element", elementAttrs);
    VOCABULARY.put("attribute", elementAttrs);
    VOCABULARY.put("group", Collections.EMPTY_SET);
    VOCABULARY.put("interleave", Collections.EMPTY_SET);
    VOCABULARY.put("choice", Collections.EMPTY_SET);
    VOCABULARY.put("optional", Collections.EMPTY_SET);
    VOCABULARY.put("zeroOrMore", Collections.EMPTY_SET);
    VOCABULARY.put("oneOrMore", Collections.EMPTY_SET);
    VOCABULARY.put("list", Collections.EMPTY_SET);
    VOCABULARY.put("mixed", Collections.EMPTY_SET);
    VOCABULARY.put("ref", elementAttrs);
    VOCABULARY.put("parentRef", elementAttrs);
    VOCABULARY.put("empty", Collections.EMPTY_SET);
    VOCABULARY.put("text", Collections.EMPTY_SET);
    VOCABULARY.put("value", valueAttrs);
    VOCABULARY.put("data", dataAttrs);
    VOCABULARY.put("notAllowed", Collections.EMPTY_SET);
    VOCABULARY.put("externalRef", externalAttrs);
    VOCABULARY.put("grammar", Collections.EMPTY_SET);
    VOCABULARY.put("param", elementAttrs);
    VOCABULARY.put("except", Collections.EMPTY_SET);
    VOCABULARY.put("div", Collections.EMPTY_SET);
    VOCABULARY.put("include", externalAttrs);
    VOCABULARY.put("start", startAttrs);
    VOCABULARY.put("define", defineAttrs);
    VOCABULARY.put("name", nsAttrs);
    VOCABULARY.put("anyName", Collections.EMPTY_SET);
    VOCABULARY.put("nsName", nsAttrs);

    STRIPPED_ATTRIBUTES.add("name");
    STRIPPED_ATTRIBUTES.add("type");
    STRIPPED_ATTRIBUTES.add("combine");

    PATTERN_ELEMENTS.add("element");
    PATTERN_ELEMENTS.add("attribute");
    PATTERN_ELEMENTS.add("group");
    PATTERN_ELEMENTS.add("interleave");
    PATTERN_ELEMENTS.add("choice");
    PATTERN_ELEMENTS.add("optional");
    PATTERN_ELEMENTS.add("zeroOrMore");
    PATTERN_ELEMENTS.add("oneOrMore");
    PATTERN_ELEMENTS.add("list");
    PATTERN_ELEMENTS.add("mixed");
    PATTERN_ELEMENTS.add("ref");
    PATTERN_ELEMENTS.add("parentRef");
    PATTERN_ELEMENTS.add("empty");
    PATTERN_ELEMENTS.add("text");
    PATTERN_ELEMENTS.add("value");
    PATTERN_ELEMENTS.add("data");
    PATTERN_ELEMENTS.add("notAllowed");
    PATTERN_ELEMENTS.add("externalRef");
    PATTERN_ELEMENTS.add("grammar");
  }

  private Set urls; // recursion checking
  private int refCount; // creation of ref names
  private Map datatypeLibraries;

  /**
   * Parse the specified document into a grammar.
   */
  synchronized Grammar parse(Document doc)
    throws IOException
  {
    urls = new HashSet();
    refCount = 1;
    
    doc.normalizeDocument(); // Normalize XML document
    transform(doc); // Apply transformation rules to provide simple syntax
    
    // 4.18. grammar element
    Element p = doc.getDocumentElement();
    Element grammar =
      doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "grammar");
    Element start =
      doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "start");
    doc.removeChild(p);
    doc.appendChild(grammar);
    grammar.appendChild(start);
    start.appendChild(p);
    transformGrammar(grammar, p);
    Element define = getNextSiblingElement(start);
    while (define != null)
      {
        Element next = getNextSiblingElement(define);
        String name = define.getAttribute("new-name");
        if (name != null)
          {
            define.setAttribute("name", name);
            define.removeAttribute("new-name");
          }
        else
          grammar.removeChild(define); // unreferenced
        define = next;
      }

    // 4.19. define and ref elements
    Set allDefines = new HashSet(), reachableDefines = new HashSet();
    getDefines(allDefines, grammar, grammar, false);
    getDefines(reachableDefines, grammar, start, true);
    allDefines.removeAll(reachableDefines);
    for (Iterator i = allDefines.iterator(); i.hasNext(); )
      {
        // remove unreachable defines
        Element d = (Element) i.next();
        Node parent = d.getParentNode();
        parent.removeChild(d);
      }
    // replace all elements that are not children of defines by refs to new
    // defines
    Set elements = new HashSet();
    getElements(elements, grammar, grammar);
    for (Iterator i = elements.iterator(); i.hasNext(); )
      {
        Element element = (Element) i.next();
        Node parent = element.getParentNode();
        if (!reachableDefines.contains(parent))
          {
            define =
              doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "define");
            Element ref =
              doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "ref");
            String name = createRefName();
            define.setAttribute("name", name);
            ref.setAttribute("name", name);
            parent.insertBefore(ref, element);
            define.appendChild(element);
            grammar.appendChild(define);
            reachableDefines.add(define);
          }
      }
    // Get defines that don't have element children
    for (Iterator i = reachableDefines.iterator(); i.hasNext(); )
      {
        Element d = (Element) i.next();
        Element child = getFirstChildElement(d);
        if (child != null && "element".equals(child.getLocalName()))
          i.remove();
      }
    // Expand refs that refer to these defines
    expandRefs(reachableDefines, grammar);
    // Remove any defines that don't have element children
    for (Iterator i = reachableDefines.iterator(); i.hasNext(); )
      {
        Element d = (Element) i.next();
        Node parent = d.getParentNode();
        parent.removeChild(d);
      }

    transform2(p); // Apply second stage transformation rules
    
    Grammar ret = parseGrammar(grammar);
    datatypeLibraries = null; // free datatype libraries cache
    return ret;
  }

  private void getDefines(Set defines, Element grammar, Element node,
                          boolean followRefs)
  {
    String elementName = node.getLocalName();
    if ("define".equals(elementName))
      defines.add(node);
    else if ("ref".equals(elementName) && followRefs)
      {
        String rname = node.getAttribute("name");
        Element define = getFirstChildElement(grammar);
        define = getNextSiblingElement(define);
        while (define != null)
          {
            String dname = define.getAttribute("name");
            if (rname.equals(dname))
              {
                getDefines(defines, grammar, node, followRefs);
                break;
              }
            define = getNextSiblingElement(define);
          }
      }
    for (Element child = getFirstChildElement(node); child != null;
         child = getNextSiblingElement(child))
      getDefines(defines, grammar, child, followRefs);
  }

  private void getElements(Set elements, Element grammar, Element node)
  {
    String elementName = node.getLocalName();
    if ("element".equals(elementName))
      elements.add(node);
    for (Element child = getFirstChildElement(node); child != null;
         child = getNextSiblingElement(child))
      getElements(elements, grammar, child);
  }

  private void expandRefs(Set defines, Element node)
    throws GrammarException
  {
    String elementName = node.getLocalName();
    if ("ref".equals(elementName))
      {
        String rname = node.getAttribute("name");
        for (Iterator i = defines.iterator(); i.hasNext(); )
          {
            Element define = (Element) i.next();
            String dname = define.getAttribute("name");
            if (rname.equals(dname))
              {
                Element child = getFirstChildElement(define);
                forbidRefs(child, rname);
                Element refChild = (Element) child.cloneNode(true);
                Node parent = node.getParentNode();
                parent.insertBefore(refChild, node);
                parent.removeChild(node);
                node = refChild;
                break;
              }
          }
      }
    for (Element child = getFirstChildElement(node); child != null;
         child = getNextSiblingElement(child))
      expandRefs(defines, child);
  }

  private void forbidRefs(Element node, String name)
    throws GrammarException
  {
    String elementName = node.getLocalName();
    if ("ref".equals(elementName))
      {
        String rname = node.getAttribute("name");
        if (name.equals(rname))
          throw new GrammarException("cannot expand ref with name '" + name +
                                     "' due to circularity");
      }
    for (Element child = getFirstChildElement(node); child != null;
         child = getNextSiblingElement(child))
      forbidRefs(child, name);
  }

  private void transform(Node node)
    throws IOException
  {
    Node parent = node.getParentNode();
    switch (node.getNodeType())
      {
      case Node.ELEMENT_NODE:
        // 4.1 Annotations
        String elementNs = node.getNamespaceURI();
        String elementName = node.getLocalName();
        if (!XMLConstants.RELAXNG_NS_URI.equals(elementNs) ||
            !VOCABULARY.containsKey(elementName))
          parent.removeChild(node);
        else
          {
            Set allowedAttrs = (Set) VOCABULARY.get(elementName);
            NamedNodeMap attrs = node.getAttributes();
            int len = attrs.getLength();
            for (int i = len - 1; i >= 0; i--)
              {
                Node attr = attrs.item(i);
                String attrNs = attr.getNamespaceURI();
                String attrName = attr.getLocalName();
                if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attrNs))
                  continue; // ignore namespace nodes
                if (!(XMLConstants.RELAXNG_NS_URI.equals(attrNs) ||
                      attrNs == null) ||
                    !allowedAttrs.contains(attrName))
                  attrs.removeNamedItemNS(attrNs, attrName);
                else
                  {
                    // 4.2 Whitespace
                    if (STRIPPED_ATTRIBUTES.contains(attrName))
                      attr.setNodeValue(attr.getNodeValue().trim());
                    // 4.3 datatypeLibrary attribute
                    else if ("datatypeLibrary".equals(attrName))
                      {
                        String dl = attr.getNodeValue();
                        attr.setNodeValue(escapeURL(dl));
                      }
                    // 4.5. href attribute
                    else if ("href".equals(attrName))
                      {
                        String href = attr.getNodeValue();
                        href = XMLParser.absolutize(node.getBaseURI(),
                                                    escapeURL(href));
                        attr.setNodeValue(href);
                      }
                  }
              }
            // 4.3 datatypeLibrary attribute
            if ("data".equals(elementName) || "value".equals(elementName))
              {
                Element element = (Element) node;
                String dl = element.getAttribute("datatypeLibrary");
                if (dl == null)
                  {
                    Node p = parent;
                    while (dl == null && p != null &&
                           p.getNodeType() == Node.ELEMENT_NODE)
                      {
                        dl = ((Element) p)
                          .getAttribute("datatypeLibrary");
                        p = p.getParentNode();
                      }
                    if (dl == null)
                      dl = "";
                    element.setAttribute("datatypeLibrary", dl);
                  }
                // 4.4. type attribute of value element
                if ("value".equals(elementName))
                  {
                    String type = element.getAttribute("type");
                    if (type == null)
                      {
                        element.setAttribute("type", "token");
                        element.setAttribute("datatypeLibrary", "");
                      }
                  }
                // 4.16. Constraints
                // TODO validate type
              }
            // 4.6. externalRef element
            else if ("externalRef".equals(elementName))
              {
                Element externalRef = (Element) node;
                String href = externalRef.getAttribute("href");
                // check for recursion
                if (urls.contains(href))
                  throw new GrammarException("recursive href");
                urls.add(href);
                Element element = resolve(href);
                String eNs = element.getNamespaceURI();
                String eName = element.getLocalName();
                if (!(XMLConstants.RELAXNG_NS_URI.equals(eNs) ||
                      eNs == null) ||
                    !PATTERN_ELEMENTS.contains(eName))
                  throw new GrammarException("externally referenced element " +
                                             "is not a pattern");
                transform(element);
                urls.remove(href);
                String ns = element.getAttribute("ns");
                if (ns != null)
                  element.setAttribute("ns",
                                       externalRef.getAttribute("ns"));
                element = (Element) externalRef.getOwnerDocument()
                  .importNode(element, true);
                parent.replaceChild(element, externalRef);
                return;
              }
            // 4.7 include element
            else if ("include".equals(elementName))
              {
                Element include = (Element) node;
                String href = include.getAttribute("href");
                // check for recursion
                if (urls.contains(href))
                  throw new GrammarException("recursive href");
                urls.add(href);
                Element element = resolve(href);
                String eNs = element.getNamespaceURI();
                String eName = element.getLocalName();
                if (!(XMLConstants.RELAXNG_NS_URI.equals(eNs) ||
                      eNs == null) ||
                    !"grammar".equals(eName))
                  throw new GrammarException("included element is not " +
                                             "a grammar");
                
                transform(element);
                urls.remove(href);
                // handle components
                List includeComponents = getComponents(include);
                List grammarComponents = getComponents(element);
                for (Iterator i = includeComponents.iterator(); i.hasNext(); )
                  {
                    Element comp = (Element) i.next();
                    String compName = comp.getLocalName();
                    if ("start".equals(compName))
                      {
                        boolean found = false;
                        for (Iterator j = grammarComponents.iterator();
                             j.hasNext(); )
                          {
                            Element c2 = (Element) j.next();
                            if ("start".equals(c2.getLocalName()))
                              {
                                c2.getParentNode().removeChild(c2);
                                found = true;
                              }
                          }
                        if (!found)
                          throw new GrammarException("no start component in " +
                                                     "included grammar");
                      }
                    else if ("define".equals(compName))
                      {
                        String name = comp.getAttribute("name");
                        boolean found = false;
                        for (Iterator j = grammarComponents.iterator();
                             j.hasNext(); )
                          {
                            Element c2 = (Element) j.next();
                            if ("define".equals(c2.getLocalName()) &&
                                name.equals(c2.getAttribute("name")))
                              {
                                c2.getParentNode().removeChild(c2);
                                found = true;
                              }
                          }
                        if (!found)
                          throw new GrammarException("no define component " +
                                                     "with name '" + name +
                                                     "' in included grammar");
                      }
                  }
                // transform to div element
                Document doc = include.getOwnerDocument();
                Element includeDiv = 
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "div");
                Element grammarDiv = 
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "div");
                // XXX copy include non-href attributes (none defined?)
                element = (Element) doc.importNode(element, true);
                Node ctx = element.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    grammarDiv.appendChild(ctx);
                    ctx = next;
                  }
                includeDiv.appendChild(grammarDiv);
                ctx = include.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    includeDiv.appendChild(ctx);
                    ctx = next;
                  }
                parent.replaceChild(includeDiv, include);
                transform(includeDiv);
                return;
              }
            // 4.8. name attribute of element and attribute elements
            else if ("attribute".equals(elementName) ||
                     "element".equals(elementName))
              {
                Element element = (Element) node;
                String name = element.getAttribute("name");
                if (name != null)
                  {
                    Document doc = element.getOwnerDocument();
                    Element n =
                      doc.createElementNS(XMLConstants.RELAXNG_NS_URI, "name");
                    n.appendChild(doc.createTextNode(name));
                    Node first = element.getFirstChild();
                    if (first != null)
                      element.insertBefore(n, first);
                    else
                      element.appendChild(n);
                    if ("attribute".equals(elementName))
                      {
                        String ns = element.getAttribute("ns");
                        if (ns != null)
                          {
                            n.setAttribute("ns", ns);
                            element.removeAttribute("ns");
                          }
                      }
                    element.removeAttribute("name");
                  }
                // 4.12. Number of child elements
                if ("attribute".equals(elementName))
                  {
                    if (getComponents(node).size() == 1)
                      {
                        Document doc = node.getOwnerDocument();
                        Element text =
                          doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                              "text");
                        node.appendChild(text);
                      }
                  }
                else // element
                  {
                    if (node.getChildNodes().getLength() > 2)
                      {
                        // transform to 2 child elements
                        Document doc = node.getOwnerDocument();
                        Element child =
                          doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                              "group");
                        Node ctx = getFirstChildElement(node);
                        ctx = getNextSiblingElement(ctx); // skip 1
                        while (ctx != null)
                          {
                            Node next = getNextSiblingElement(ctx);
                            child.appendChild(ctx);
                            ctx = next;
                          }
                        node.appendChild(child);
                      }
                  }
              }
            // 4.11. div element
            else if ("div".equals(elementName))
              {
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    parent.insertBefore(ctx, node);
                    transform(ctx);
                    ctx = next;
                  }
                parent.removeChild(node);
                return;
              }
            else if ("mixed".equals(elementName))
              {
                // 4.12. Number of child elements
                transformToOneChildElement(node, "group");
                // 4.13. mixed element
                Document doc = node.getOwnerDocument();
                Node interleave =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "interleave");
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    interleave.appendChild(ctx);
                    ctx = next;
                  }
                Node text =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "text");
                interleave.appendChild(text);
                parent.insertBefore(interleave, node);
                parent.removeChild(node);
                node = interleave;
              }
            else if ("optional".equals(elementName))
              {
                // 4.12. Number of child elements
                transformToOneChildElement(node, "group");
                // 4.14. optional element
                Document doc = node.getOwnerDocument();
                Node choice =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "choice");
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    choice.appendChild(ctx);
                    ctx = next;
                  }
                Node empty =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "empty");
                choice.appendChild(empty);
                parent.insertBefore(choice, node);
                parent.removeChild(node);
                node = choice;
              }
            else if ("zeroOrMore".equals(elementName))
              {
                // 4.12. Number of child elements
                transformToOneChildElement(node, "group");
                // 4.15. zeroOrMore element
                Document doc = node.getOwnerDocument();
                Node choice =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "choice");
                Node oneOrMore =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "oneOrMore");
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    oneOrMore.appendChild(ctx);
                    ctx = next;
                  }
                Node empty =
                  doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                      "empty");
                choice.appendChild(oneOrMore);
                choice.appendChild(empty);
                parent.insertBefore(choice, node);
                parent.removeChild(node);
                node = choice;
              }
            else if ("list".equals(elementName) ||
                     "oneOrMore".equals(elementName) ||
                     "define".equals(elementName))
              {
                // 4.12. Number of child elements
                transformToOneChildElement(node, "group");
              }
            else if ("except".equals(elementName))
              {
                // 4.12. Number of child elements
                transformToOneChildElement(node, "choice");
                // 4.16. Constraints
                String parentName = parent.getLocalName();
                if ("anyName".equals(parentName))
                  forbidDescendants(node, Collections.singleton("anyName"));
                else if ("nsName".equals(parentName))
                  {
                    Set names = new HashSet();
                    names.add("nsName");
                    names.add("anyName");
                    forbidDescendants(node, names);
                  }
              }
            else if ("choice".equals(elementName) ||
                     "group".equals(elementName) ||
                     "interleave".equals(elementName))
              {
                // 4.12. Number of child elements
                Node ctx = getFirstChildElement(node);
                Node next = getNextSiblingElement(ctx);
                if (next == null)
                  {
                    // replace
                    parent.insertBefore(ctx, node);
                    parent.removeChild(node);
                    transform(ctx);
                    return;
                  }
                else
                  {
                    // transform to 2 child elements
                    Node next2 = getNextSiblingElement(next);
                    if (next2 != null)
                      {
                        Document doc = node.getOwnerDocument();
                        Node child =
                          doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                              elementName);
                        child.appendChild(ctx);
                        child.appendChild(next);
                        node.insertBefore(next2, child);
                        transform(node); // recurse
                      }
                  }
              }
            // 4.17. combine attribute
            else if ("grammar".equals(elementName))
              {
                String combine = null;
                List nodes = new LinkedList();
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    if ("start".equals(ctx.getLocalName()))
                      {
                        String c = ((Element) ctx).getAttribute("combine");
                        if (combine != null && !combine.equals(c))
                          throw new GrammarException("multiple start elements "+
                                                     "but no combine attribute");
                        combine = c;
                        nodes.add(ctx);
                      }
                    ctx = next;
                  }
                if (!nodes.isEmpty())
                  combineNodes(node, combine, "start", nodes);
                // defines
                Map defines = new HashMap();
                Map defineCombines = new HashMap();
                ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    if ("define".equals(ctx.getLocalName()))
                      {
                        String name = ((Element) ctx).getAttribute("name");
                        combine = (String) defineCombines.get(name);
                        String c = ((Element) ctx).getAttribute("combine");
                        if (combine != null && !combine.equals(c))
                          throw new GrammarException("multiple define " +
                                                     "elements with name '"+
                                                     name + "' but no " +
                                                     "combine attribute");
                        defineCombines.put(name, c);
                        nodes = (List) defines.get(name);
                        if (nodes == null)
                          {
                            nodes = new LinkedList();
                            defines.put(name, nodes);
                          }
                        nodes.add(ctx);
                      }
                    ctx = next;
                  }
                for (Iterator i = defines.keySet().iterator(); i.hasNext(); )
                  {
                    String name = (String) i.next();
                    combine = (String) defineCombines.get(name);
                    nodes = (List) defines.get(name);
                    if (!nodes.isEmpty())
                      combineNodes(node, combine, "define", nodes);
                  }
              }
            // 4.9. ns attribute
            if ("name".equals(elementName) ||
                "nsName".equals(elementName) ||
                "value".equals(elementName))
              {
                Element element = (Element) node;
                String ns = element.getAttribute("ns");
                if (ns == null)
                  {
                    Node ctx = parent;
                    while (ns == null && ctx != null &&
                           ctx.getNodeType() == Node.ELEMENT_NODE)
                      {
                        ns = ((Element) ctx).getAttribute("ns");
                        ctx = ctx.getParentNode();
                      }
                    element.setAttribute("ns", (ns == null) ? "" : ns);
                  }
                if ("name".equals(elementName))
                  {
                    // 4.10. QNames
                    String name = element.getTextContent();
                    int ci = name.indexOf(':');
                    if (ci != -1)
                      {
                        String prefix = name.substring(0, ci);
                        element.setTextContent(name.substring(ci + 1));
                        ns = element.lookupNamespaceURI(prefix);
                        element.setAttribute("ns", (ns == null) ? "" : ns);
                      }
                    // 4.16. Constraints
                    if (isDescendantOfFirstChildOfAttribute(element) &&
                        "".equals(element.getAttribute("ns")) &&
                        "xmlns".equals(element.getTextContent()))
                      throw new GrammarException("name cannot be xmlns");
                  }
                else if ("nsName".equals(elementName))
                  {
                    // 4.16. Constraints
                    if (isDescendantOfFirstChildOfAttribute(element) &&
                        "http://www.w3.org/2000/xmlns"
                        .equals(element.getAttribute("ns")))
                      throw new GrammarException("nsName cannot be XMLNS URI");
                  }
              }
          }
        
        break;
      case Node.TEXT_NODE:
      case Node.CDATA_SECTION_NODE:
        // 4.2 Whitespace
        String parentName = parent.getLocalName();
        if ("name".equals(parentName))
          node.setNodeValue(node.getNodeValue().trim());
        if (!"param".equals(parentName) &&
            !"value".equals(parentName) &&
            isWhitespace(node.getNodeValue()))
          parent.removeChild(node);
        break;
      case Node.DOCUMENT_NODE:
        break;
      default:
        parent.removeChild(node);
      }
    // Transform children
    Node ctx = node.getFirstChild();
    while (ctx != null)
      {
        Node next = ctx.getNextSibling();
        transform(ctx);
        ctx = next;
      }
  }

  /**
   * Transforms the schema to place all defines under the top-level grammar
   * element and replace all other grammar elements by their start child.
   */
  private void transformGrammar(Node grammar, Node node)
    throws GrammarException
  {
    if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        String elementName = node.getLocalName();
        if ("grammar".equals(elementName))
          {
            handleRefs(grammar, node, node);
            Node start = null;
            Node ctx = node.getFirstChild();
            while (ctx != null)
              {
                Node next = ctx.getNextSibling();
                String childName = ctx.getLocalName();
                if ("define".equals(childName))
                  grammar.appendChild(ctx);
                else if ("start".equals(childName))
                  start = ctx;
                ctx = next;
              }
            if (start == null)
              throw new GrammarException("no start element for grammar");
            Node p = getFirstChildElement(start);
            Node parent = node.getParentNode();
            parent.insertBefore(p, node);
            parent.removeChild(node);
            node = p;
          }
        Node ctx = node.getFirstChild();
        while (ctx != null)
          {
            Node next = ctx.getNextSibling();
            transformGrammar(grammar, ctx);
            ctx = next;
          }
      }
  }

  /**
   * Checks that all references in the specified grammar match a define in
   * the grammar.
   */
  private void handleRefs(Node grammar1, Node grammar2, Node node)
    throws GrammarException
  {
    if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        String elementName = node.getLocalName();
        if ("ref".equals(elementName) || "parentRef".equals(elementName))
          {
            Node grammar = grammar2;
            if ("parentRef".equals(elementName))
              grammar = grammar1;
            
            String name = ((Element) node).getAttribute("name");
            if (name != null)
              throw new GrammarException("no name attribute on " +
                                         elementName);
            Node define = null;
            for (Node ctx = grammar.getFirstChild();
                 define == null && ctx != null;
                 ctx = ctx.getNextSibling())
              {
                if ("define".equals(ctx.getLocalName()))
                  {
                    String dname = ((Element) ctx).getAttribute("name");
                    if (name.equals(dname))
                      define = ctx;
                  }
              }
            if (define == null)
              throw new GrammarException("no define for '" + name + "'");
            name = ((Element) define).getAttribute("new-name");
            if (name == null)
              {
                name = createRefName();
                ((Element) define).setAttribute("new-name", name);
              }
            if ("parentRef".equals(elementName))
              {
                Document doc = node.getOwnerDocument();
                Node ref = doc.createElementNS(XMLConstants.RELAXNG_NS_URI,
                                               "ref");
                Node ctx = node.getFirstChild();
                while (ctx != null)
                  {
                    Node next = ctx.getNextSibling();
                    ref.appendChild(ctx);
                    ctx = next;
                  }
                Node parent = node.getParentNode();
                parent.insertBefore(ref, node);
                parent.removeChild(node);
                node = ref;
              }
            ((Element) node).setAttribute("name", name);
          }
        else if ("grammar".equals(elementName))
          {
            grammar1 = grammar2;
            grammar2 = node;
          }
        Node ctx = node.getFirstChild();
        while (ctx != null)
          {
            Node next = ctx.getNextSibling();
            handleRefs(grammar1, grammar2, ctx);
            ctx = next;
          }
      }
  }

  private String createRefName()
  {
    return "ref" + Integer.toString(refCount++);
  }

  private void transform2(Node node)
    throws GrammarException
  {
    Node parent = node.getParentNode();
    if (node.getNodeType() == Node.ELEMENT_NODE)
      {
        String elementName = node.getLocalName();
        // 4.20. notAllowed element
        if ("notAllowed".equals(elementName))
          {
            String parentName = parent.getLocalName();
            if ("attribute".equals(parentName) ||
                "list".equals(parentName) ||
                "group".equals(parentName) ||
                "interleave".equals(parentName) ||
                "oneOrMore".equals(parentName))
              {
                Node pp = parent.getParentNode();
                pp.insertBefore(node, parent);
                pp.removeChild(parent);
                transform2(node); // apply recursively
                return;
              }
            else if ("choice".equals(parentName))
              {
                Node p1 = getFirstChildElement(parent);
                Node p2 = getNextSiblingElement(p1);
                if (p1 == null || p2 == null)
                  throw new GrammarException("choice does not have two " +
                                             "children");
                String p1Name = p1.getLocalName();
                String p2Name = p2.getLocalName();
                Node pp = parent.getParentNode();
                if ("notAllowed".equals(p1Name) &&
                    "notAllowed".equals(p2Name))
                  {
                    pp.insertBefore(p1, parent);
                    pp.removeChild(parent);
                    transform2(p1); //apply recursively
                    return;
                  }
                else if ("notAllowed".equals(p1Name))
                  {
                    pp.insertBefore(p2, parent);
                    pp.removeChild(parent);
                    transform2(p2);
                    return;
                  }
                else
                  {
                    pp.insertBefore(p1, parent);
                    pp.removeChild(parent);
                    transform2(p1);
                    return;
                  }
              }
            else if ("except".equals(parentName))
              {
                Node pp = parent.getParentNode();
                pp.removeChild(parent);
                return;
              }
          }
        // 4.21. empty element
        else if ("empty".equals(elementName))
          {
            String parentName = parent.getLocalName();
            if ("group".equals(parentName) ||
                "interleave".equals(parentName))
              {
                Node p1 = getFirstChildElement(parent);
                Node p2 = getNextSiblingElement(p1);
                if (p1 == null || p2 == null)
                  throw new GrammarException(parentName + " does not have " +
                                             "two children");
                String p1Name = p1.getLocalName();
                String p2Name = p2.getLocalName();
                Node pp = parent.getParentNode();
                if ("empty".equals(p1Name) &&
                    "empty".equals(p2Name))
                  {
                    pp.insertBefore(p1, parent);
                    pp.removeChild(parent);
                    transform2(p1);
                    return;
                  }
                else if ("empty".equals(p1Name))
                  {
                    pp.insertBefore(p2, parent);
                    pp.removeChild(parent);
                    transform2(p2);
                    return;
                  }
                else
                  {
                    pp.insertBefore(p1, parent);
                    pp.removeChild(parent);
                    transform2(p1);
                    return;
                  }
              }
            else if ("choice".equals(parentName))
              {
                Node p1 = getFirstChildElement(parent);
                Node p2 = getNextSiblingElement(p1);
                if (p1 == null || p2 == null)
                  throw new GrammarException(parentName + " does not have " +
                                             "two children");
                String p1Name = p1.getLocalName();
                String p2Name = p2.getLocalName();
                Node pp = parent.getParentNode();
                if ("empty".equals(p1Name) &&
                    "empty".equals(p2Name))
                  {
                    pp.insertBefore(p1, parent);
                    pp.removeChild(parent);
                    transform2(p1);
                    return;
                  }
              }
            else if ("oneOrMore".equals(parentName))
              {
                Node pp = parent.getParentNode();
                pp.insertBefore(node, parent);
                pp.removeChild(parent);
                transform2(node);
                return;
              }
          }
        Node ctx = node.getFirstChild();
        while (ctx != null)
          {
            Node next = ctx.getNextSibling();
            transform2(ctx);
            ctx = next;
          }
      }
  }

  private static boolean isWhitespace(String text)
  {
    int len = text.length();
    for (int i = 0; i < len; i++)
      {
        char c = text.charAt(i);
        if (c != ' ' && c != '\t' && c != '\n' && c != '\r')
          return false;
      }
    return true;
  }

  private static String escapeURL(String url)
  {
    try
      {
        return URLEncoder.encode(url, "UTF-8");
      }
    catch (UnsupportedEncodingException e)
      {
        RuntimeException e2 = new RuntimeException("UTF-8 is unsupported");
        e2.initCause(e);
        throw e2;
      }
  }

  /**
   * Resolve a URL to an element, as described in section 4.5.
   */
  private static Element resolve(String url)
    throws IOException
  {
    try
      {
        URL u = new URL(url);
        InputStream in = u.openStream();
        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        f.setNamespaceAware(true);
        f.setCoalescing(true);
        f.setExpandEntityReferences(true);
        f.setIgnoringComments(true);
        f.setIgnoringElementContentWhitespace(true);
        DocumentBuilder b = f.newDocumentBuilder();
        Document doc = b.parse(in, url);
        in.close();
        String fragment = u.getRef();
        if (fragment != null)
          return doc.getElementById(fragment);
        return doc.getDocumentElement();
      }
    catch (SAXException e)
      {
        IOException e2 = new IOException("error parsing included element");
        e2.initCause(e);
        throw e2;
      }
    catch (ParserConfigurationException e)
      {
        IOException e2 = new IOException("error parsing included element");
        e2.initCause(e);
        throw e2;
      }
  }

  /**
   * Returns the "components" of an element, as described in section 4.7.
   */
  private List getComponents(Node node)
  {
    List ret = new LinkedList();
    for (Node ctx = node.getFirstChild(); ctx != null;
         ctx = ctx.getNextSibling())
      {
        if (ctx.getNodeType() != Node.ELEMENT_NODE)
          continue;
        String ns = ctx.getNamespaceURI();
        if (ns != null && !ns.equals(XMLConstants.RELAXNG_NS_URI))
          continue;
        String name = ctx.getLocalName();
        if ("div".equals(name))
          ret.addAll(getComponents(ctx));
        else if (VOCABULARY.containsKey(name))
          ret.add(ctx);
      }
    return ret;
  }

  private static void transformToOneChildElement(Node node, String name)
  {
    if (node.getChildNodes().getLength() < 2)
      return;
    Document doc = node.getOwnerDocument();
    Element child = doc.createElementNS(XMLConstants.RELAXNG_NS_URI, name);
    Node ctx = getFirstChildElement(node);
    while (ctx != null)
      {
        Node next = getNextSiblingElement(ctx);
        child.appendChild(ctx);
        ctx = next;
      }
    node.appendChild(child);
  }
  
  private static Element getFirstChildElement(Node node)
  {
    Node ctx = node.getFirstChild();
    while (ctx != null && ctx.getNodeType() != Node.ELEMENT_NODE)
      ctx = ctx.getNextSibling();
    return (Element) ctx;
  }

  private static Element getNextSiblingElement(Node node)
  {
    Node ctx = node.getNextSibling();
    while (ctx != null && ctx.getNodeType() != Node.ELEMENT_NODE)
      ctx = ctx.getNextSibling();
    return (Element) ctx;
  }

  private static void forbidDescendants(Node node, Set names)
    throws GrammarException
  {
    for (Node ctx = node.getFirstChild(); ctx != null;
         ctx = ctx.getNextSibling())
      {
        String ns = ctx.getNamespaceURI();
        if (!XMLConstants.RELAXNG_NS_URI.equals(ns))
          continue;
        String name = ctx.getLocalName();
        if (names.contains(name))
          throw new GrammarException("name not allowed: " + name);
        forbidDescendants(ctx, names);
      }
  }

  private static boolean isDescendantOfFirstChildOfAttribute(Node node)
  {
    Node child = node;
    Node parent = node.getParentNode();
    while (parent != null && !"attribute".equals(parent.getLocalName()))
      {
        child = parent;
        parent = child.getParentNode();
      }
    if (parent == null)
      return false;
    Node firstChild = getFirstChildElement(parent);
    return firstChild == child;
  }

  private static void combineNodes(Node node, String combine, String name,
                                   List nodes)
  {
    Document doc = node.getOwnerDocument();
    Node child =
      doc.createElementNS(XMLConstants.RELAXNG_NS_URI, name);
    Node combineNode =
      doc.createElementNS(XMLConstants.RELAXNG_NS_URI, combine);
    child.appendChild(combineNode);
    boolean inserted = false;
    for (Iterator i = nodes.iterator(); i.hasNext(); )
      {
        Node startNode = (Node) i.next();
        if (!inserted)
          {
            node.insertBefore(child, startNode);
            inserted = true;
          }
        Node ctx = startNode.getFirstChild();
        while (ctx != null)
          {
            Node next = ctx.getNextSibling();
            combineNode.appendChild(ctx);
            ctx = next;
          }
        node.removeChild(startNode);
      }
  }

  Grammar parseGrammar(Element node)
    throws GrammarException
  {
    checkName(node, "grammar");
    Grammar grammar = new Grammar();
    Element start = getFirstChildElement(node);
    grammar.start = parsePattern(getFirstChildElement(start));
    for (Element define = getNextSiblingElement(start); define != null;
         define = getNextSiblingElement(define))
      grammar.defines.add(parseDefine(define));
    return grammar;
  }

  Define parseDefine(Element node)
    throws GrammarException
  {
    checkName(node, "define");
    Define define = new Define();
    define.name = node.getAttribute("name");
    define.element = parseElement(getFirstChildElement(node));
    return define;
  }

  Pattern parseTop(Element node)
    throws GrammarException
  {
    String name = node.getLocalName();
    if ("notAllowed".equals(name))
      return parseNotAllowed(node);
    return parsePattern(node);
  }

  Pattern parsePattern(Element node)
    throws GrammarException
  {
    String name = node.getLocalName();
    if ("empty".equals(name))
      return parseEmpty(node);
    return parseNonEmptyPattern(node);
  }

  Pattern parseNonEmptyPattern(Element node)
    throws GrammarException
  {
    String name = node.getLocalName();
    if ("text".equals(name))
      return parseText(node);
    else if ("data".equals(name))
      return parseData(node);
    else if ("value".equals(name))
      return parseValue(node);
    else if ("list".equals(name))
      return parseList(node);
    else if ("attribute".equals(name))
      return parseAttribute(node);
    else if ("ref".equals(name))
      return parseRef(node);
    else if ("oneOrMore".equals(name))
      return parseOneOrMore(node);
    else if ("choice".equals(name))
      return parseChoice(node);
    else if ("group".equals(name))
      return parseGroup(node);
    else if ("interleave".equals(name))
      return parseInterleave(node);
    throw new GrammarException("invalid pattern: " + name);
  }

  ElementPattern parseElement(Element node)
    throws GrammarException
  {
    checkName(node, "element");
    ElementPattern element = new ElementPattern();
    Element nameClass = getFirstChildElement(node);
    element.nameClass = parseNameClass(nameClass);
    element.pattern = parseTop(getNextSiblingElement(nameClass));
    return element;
  }

  NotAllowedPattern parseNotAllowed(Element node)
    throws GrammarException
  {
    checkName(node, "notAllowed");
    return NotAllowedPattern.INSTANCE;
  }

  EmptyPattern parseEmpty(Element node)
    throws GrammarException
  {
    checkName(node, "empty");
    return EmptyPattern.INSTANCE;
  }

  TextPattern parseText(Element node)
    throws GrammarException
  {
    checkName(node, "text");
    return TextPattern.INSTANCE;
  }

  DataPattern parseData(Element node)
    throws GrammarException
  {
    checkName(node, "data");
    DataPattern data = new DataPattern();
    DatatypeLibrary dl =
      getDatatypeLibrary(node.getAttribute("datatypeLibrary"));
    String type = node.getAttribute("type");
    try
      {
        data.type = dl.createDatatype(type);
        data.datatypeLibrary = dl;
      }
    catch (DatatypeException e)
      {
        GrammarException e2 = new GrammarException(type);
        e2.initCause(e);
        throw e2;
      }
    Element ctx = getFirstChildElement(node);
    while (ctx != null)
      {
        Element next = getNextSiblingElement(ctx);
        String name = ctx.getLocalName();
        if ("param".equals(name))
          data.params.add(parseParam(ctx));
        else if ("except".equals(name) && next == null)
          data.exceptPattern = parsePattern(getFirstChildElement(ctx));
        else
          throw new GrammarException("invalid element: " + name);
        ctx = next;
      }
    return data;
  }

  Param parseParam(Element node)
    throws GrammarException
  {
    checkName(node, "param");
    Param param  = new Param();
    param.name = node.getAttribute("name");
    param.value = node.getTextContent();
    return param;
  }

  ValuePattern parseValue(Element node)
    throws GrammarException
  {
    checkName(node, "value");
    ValuePattern value = new ValuePattern();
    DatatypeLibrary dl =
      getDatatypeLibrary(node.getAttribute("datatypeLibrary"));
    String type = node.getAttribute("type");
    try
      {
        value.type = dl.createDatatype(type);
        value.datatypeLibrary = dl;
      }
    catch (DatatypeException e)
      {
        GrammarException e2 = new GrammarException(type);
        e2.initCause(e);
        throw e2;
      }
    value.ns = node.getAttribute("ns");
    value.value = node.getTextContent();
    return value;
  }
  
  ListPattern parseList(Element node)
    throws GrammarException
  {
    checkName(node, "list");
    ListPattern list = new ListPattern();
    list.pattern = parsePattern(getFirstChildElement(node));
    return list;
  }

  AttributePattern parseAttribute(Element node)
    throws GrammarException
  {
    checkName(node, "attribute");
    AttributePattern attribute = new AttributePattern();
    Element nameClass = getFirstChildElement(node);
    attribute.nameClass = parseNameClass(nameClass);
    attribute.pattern = parsePattern(getNextSiblingElement(nameClass));
    return attribute;
  }

  RefPattern parseRef(Element node)
    throws GrammarException
  {
    checkName(node, "ref");
    RefPattern ref = new RefPattern();
    ref.name = node.getAttribute("name");
    return ref;
  }

  OneOrMorePattern parseOneOrMore(Element node)
    throws GrammarException
  {
    checkName(node, "oneOrMore");
    OneOrMorePattern oneOrMore = new OneOrMorePattern();
    oneOrMore.pattern = parseNonEmptyPattern(getFirstChildElement(node));
    return oneOrMore;
  }

  ChoicePattern parseChoice(Element node)
    throws GrammarException
  {
    checkName(node, "choice");
    ChoicePattern choice = new ChoicePattern();
    Element p1 = getFirstChildElement(node);
    Element p2 = getNextSiblingElement(p1);
    choice.pattern1 = parsePattern(p1);
    choice.pattern2 = parseNonEmptyPattern(p2);
    return choice;
  }

  GroupPattern parseGroup(Element node)
    throws GrammarException
  {
    checkName(node, "group");
    GroupPattern group = new GroupPattern();
    Element p1 = getFirstChildElement(node);
    Element p2 = getNextSiblingElement(p1);
    group.pattern1 = parseNonEmptyPattern(p1);
    group.pattern2 = parseNonEmptyPattern(p2);
    return group;
  }

  InterleavePattern parseInterleave(Element node)
    throws GrammarException
  {
    checkName(node, "interleave");
    InterleavePattern interleave = new InterleavePattern();
    Element p1 = getFirstChildElement(node);
    Element p2 = getNextSiblingElement(p1);
    interleave.pattern1 = parseNonEmptyPattern(p1);
    interleave.pattern2 = parseNonEmptyPattern(p2);
    return interleave;
  }

  NameClass parseNameClass(Element node)
    throws GrammarException
  {
    String name = node.getLocalName();
    if ("anyName".equals(name))
      return parseAnyName(node);
    else if ("name".equals(name))
      return parseName(node);
    else if ("nsName".equals(name))
      return parseNsName(node);
    else if ("choice".equals(name))
      return parseChoiceNameClass(node);
    throw new GrammarException("invalid name class: " + name);
  }

  AnyNameNameClass parseAnyName(Element node)
    throws GrammarException
  {
    checkName(node, "anyName");
    AnyNameNameClass anyName = new AnyNameNameClass();
    Element except = getFirstChildElement(node);
    if (except != null) {
      checkName(except, "except");
      anyName.exceptNameClass = parseNameClass(getFirstChildElement(except));
    }
    return anyName;
  }

  NameNameClass parseName(Element node)
    throws GrammarException
  {
    checkName(node, "name");
    NameNameClass name = new NameNameClass();
    name.ns = node.getAttribute("ns");
    name.name = node.getTextContent();
    return name;
  }

  NSNameNameClass parseNsName(Element node)
    throws GrammarException
  {
    checkName(node, "nsName");
    NSNameNameClass nsName = new NSNameNameClass();
    nsName.ns = node.getAttribute("ns");
    Element except = getFirstChildElement(node);
    if (except != null) {
      checkName(except, "except");
      nsName.exceptNameClass = parseNameClass(getFirstChildElement(except));
    }
    return nsName;
  }

  ChoiceNameClass parseChoiceNameClass(Element node)
    throws GrammarException
  {
    checkName(node, "choice");
    ChoiceNameClass choice = new ChoiceNameClass();
    Element c1 = getFirstChildElement(node);
    Element c2 = getNextSiblingElement(c1);
    choice.name1 = parseNameClass(c1);
    choice.name2 = parseNameClass(c2);
    return choice;
  }

  void checkName(Element node, String name)
    throws GrammarException
  {
    if (!name.equals(node.getLocalName()))
      throw new GrammarException("expecting " + name);
  }

  DatatypeLibrary getDatatypeLibrary(String uri)
    throws GrammarException
  {
    if (datatypeLibraries == null)
      datatypeLibraries = new HashMap();
    DatatypeLibrary library = (DatatypeLibrary) datatypeLibraries.get(uri);
    if (library == null)
      {
        library = new DatatypeLibraryLoader().createDatatypeLibrary(uri);
        if (library == null)
          throw new GrammarException("Datatype library not supported: " + uri);
        datatypeLibraries.put(uri, library);
      }
    return library;
  }

}
