with (classes) {

with (dom) {

dom.Document = function ()
{
 if (classes.Document) return this;

 dom.Node.call(this);

 var This = new Object;

 This.implementation = dom.DOMImplementation;

 This.The_DOMDocument = this;

 with (this)
 {
  if ("setProperty" in this) setProperty("SelectionLanguage", "XPath");
  if ("resolveExternals" in this) resolveExternals = false; // true;
  if ("validateOnParser" in this) validateOnParse = false; // true;

  This.inputEncoding = "inputEncoding" in this? inputEncoding : null;
  This.xmlEncoding = "xmlEncoding" in this? xmlEncoding : null; //
  This.xmlStandalone = "xmlStandalone" in this? xmlStandalone : null;
  This.documentURI = "documentURI" in this? documentURI : this.url? url : this.URL;

  This.doctype = doctype;
  This.documentElement = documentElement;

  This.xmlVersion = "xmlVersion" in this? xmlVersion : "1.0";
  This.strictErrorChecking = "strictErrorChecking" in this? strictErrorChecking : false;
  This.domConfig = "domConfig" in this? domConfig : null; // not implemented

  This.childNodes = dom.NodeList.call(childNodes);

  // Non-standard
  This.async = this.async;
 }

 with (Document)
 {
  This.createElement = createElement;
  This.createDocumentFragment = createDocumentFragment;
  This.createTextNode = createTextNode;
  This.createComment = createComment;
  This.createCDATASection = createCDATASection;
  This.createProcessingInstruction = createProcessingInstruction;
  This.createAttribute = createAttribute;
  This.createEntityReference = createEntityReference;
  This.getElementsByTagName = getElementsByTagName;
  This.importNode = importNode;

  This.getElementById = getElementById;
  This.adoptNode = adoptNode;
  This.normalizeDocument = normalizeDocument;
  This.renameNode = renameNode;

  // Non-standard
  This.load = load;
 }

 return This;
}

Document.createElement = function (tagName) { return Element.call(this.The_DOMDocument.createElement(tagName)); }
Document.createDocumentFragment = function () { return Node.call(this.The_DOMDocument.createDocumentFragment()); }
Document.createTextNode = function (data) { return Node.call(this.The_DOMDocument.createTextNode(data)); }
Document.createComment = function (data) { return "createComment" in this.The_DOMDocument? Node.call(this.The_DOMDocument.createComment(data)) : null; }
Document.createCDATASection = function (data) { return "createCDATASection" in this.The_DOMDocument? Node.call(this.The_DOMDocument.createCDATASection(data)) : null; }
Document.createProcessingInstruction = function (data) { return "createProcessingInstruction" in this.The_DOMDocument? Node.call(this.The_DOMDocument.createProcessingInstruction(data)) : null; }
Document.createAttribute = function (name) { return Node.call(this.The_DOMDocument.createAttribute(name)); }
Document.createEntityReference = function (name) { return Node.call(this.The_DOMDocument.createEntityReference(name)); }
Document.getElementsByTagName = function (tagname) { return NodeList.call(this.The_DOMDocument.getElementsByTagName(tagname)); }

Document.importNode = function (importedNode, deep) { with (this) // raises(DOMException);
{
 if (! importedNode) return null;

 if ("importNode" in The_DOMDocument) return Node.call(The_DOMDocument.importNode(importedNode, true));

 // This implementation only works with nodes of type ELEMENT_NODE

 var The_Node = null;

 if ("xml" in The_DOMDocument)
 {
  The_Node = The_DOMDocument.createDocumentFragment();

  The_Node.appendChild(importedNode.cloneNode(deep));
 }
 else if ("outerHTML" in importedNode) with (createElement("div"))
 {
  innerHTML = importedNode.outerHTML;

  if (firstChild)
  {
   The_Node = removeChild(firstChild);

   if (! deep) with (The_Node) while (firstChild) removeChild(firstChild);

   Node.call(The_Node);
  }
 }
 else with (createElement("div"))
 {
  innerHTML = (deep? importedNode : importedNode.cloneNode(false)).xml;

  if (firstChild)
  {
   The_Node = removeChild(firstChild);

   The_Node.removeAttribute("xmlns");

   Node.call(The_Node);
  }
 }

 return The_Node;
}}

Document.createElementNS = function (namespaceURI, qualifiedName) { /* NOT YET IMPLEMENTED */ return null; }
Document.createAttributeNS = function (namespaceURI, qualifiedName) { /* NOT YET IMPLEMENTED */ return null; }

Document.getElementsByTagNameNS = function (namespaceURI, localName) { with (this)
{
 if ("getElementsByTagNameNS" in The_DOMDocument) return The_DOMDocument.getElementsByTagName(namespaceURI, localName);

 // No way to determine the prefix, and there may be multiple prefixes anyway...!

 return NodeList.call(The_DOMDocument.getElementsByTagName("*"), localName, namespaceURI);
}}

Document.getElementById = function (elementId) { with (this)
{
 var The_Element = The_DOMDocument.getElementById? The_DOMDocument.getElementById(elementId) : The_DOMDocument.nodeFromID(elementId);

 return The_Element? Element.call(The_Element) : null;
}}

Document.adoptNode = function (source) { with (this)
{
 if ("adoptNode" in The_DOMDocument) return The_DOMDocument.adoptNode(source);

 source.parentNode.removeChild(source);

 return source.ownerDocument == The_DOMDocument? source : importNode(source, true);
}}

Document.normalizeDocument = function () { with (this)
{
 with (The_DOMDocument) if (documentElement && "normalize" in documentElement) documentElement.normalize();
}}

Document.renameNode = function (n, namespaceURI, qualifiedName) { return null; }

Document.load = function (xmlSource) { with (this)
{
 try { if (The_DOMDocument.documentElement) The_DOMDocument.removeChild(The_DOMDocument.documentElement); }
 catch (e) { The_DOMDocument = new ActiveXObject("Msxml2.FreeThreadedDOMDocument"); }

 with (The_DOMDocument)
 {
  async = this.async;

  if (load(xmlSource))
  {
   this.doctype = doctype;
   this.documentElement = documentElement;

   var xmlDeclaration_string = xml.substring(0, xml.indexOf('>'));

   if ("xmlVersion" in The_DOMDocument) this.xmlVersion = xmlVersion;
   else
   {
    var Result_Array = (new RegExp("version=['\"]\\S+(?=['\"])", "i")).exec(xmlDeclaration_string);

    if (Result_Array) this.xmlVersion = Result_Array[0].substring(9);

    if (! this.xmlVersion) this.xmlVersion = "1.0";
   }

   if ("xmlEncoding" in The_DOMDocument) this.xmlVersion = xmlEncoding;
   else
   {
//    var Result_Array = (new RegExp("encoding=['\"]\\S+(?=['\"])", "i")).exec(xmlDeclaration_string);

//    if (Result_Array) this.xmlEncoding = Result_Array[0].substring(10);

/*    if (! this.xmlEncoding) */ this.xmlEncoding = "utf-8";
   }

   if ("xmlStandalone" in The_DOMDocument) this.xmlVersion = xmlStandalone;
   else
   {
    var Result_Array = (new RegExp("standalone=['\"]\\S+(?=['\"])", "i")).exec(xmlDeclaration_string);

    this.xmlStandalone = (Result_Array && Result_Array[0].substring(12) == "yes")? true : false;
   }
  }
 }
}}

}

}

/*

 else switch (importedNode.nodeType)
 {
  case Node.ELEMENT_NODE:
  {
   The_Node = createElement(importedNode.nodeName);

   var attribute_count = importedNode.attributes.length;

   for (var attribute_index = 0; attribute_index != attribute_count; ++ attribute_index)
    with (importedNode.attributes.item(attribute_index)) if (nodeName != "xmlns") The_Node.setAttribute(nodeName, nodeValue);

   if (deep)
   {
    var This_Element = importedNode.firstChild,
        Child_Element;

    while (This_Element)
    {
     if (Child_Element = importNode(This_Element, true)) The_Node.appendChild(Child_Element);

     This_Element = This_Element.nextSibling;
    }
   }
  }
   break;
  case Node.TEXT_NODE: The_Node = createTextNode(importedNode.nodeValue);
   break;
  case Node.CDATA_SECTION_NODE: The_Node = createCDATASection(importedNode.nodeValue);
   break;
  default:;
 }

*/

/*

*/

/*

 else switch (importedNode.nodeType)
 {
  case Node.ELEMENT_NODE:
  {
   The_Node = createElement(importedNode.nodeName);

   var attribute_count = importedNode.attributes.length;

   for (var attribute_index = 0; attribute_index != attribute_count; ++ attribute_index)
    with (importedNode.attributes.item(attribute_index)) if (nodeName != "xmlns") The_Node.setAttribute(nodeName, nodeValue);

   if (deep)
   {
    var This_Element = importedNode.firstChild,
        Child_Element;

    while (This_Element)
    {
     if (Child_Element = importNode(This_Element, true)) The_Node.appendChild(Child_Element);

     This_Element = This_Element.nextSibling;
    }
   }
  }
   break;
  case Node.TEXT_NODE: The_Node = createTextNode(importedNode.nodeValue);
   break;
  case Node.CDATA_SECTION_NODE: The_Node = createCDATASection(importedNode.nodeValue);
   break;
  default:;
 }

*/
