if (!$Browser.IsIe) 
{ 
  function XmlDocument (xml)
  {
    var xmlObj = document.implementation.createDocument("","",null);
    if(xml)
      xmlObj.loadXML(xml);
    xmlObj.setProperty("SelectionNamespaces","xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");

    return xmlObj; 
  }

  XmlDocument._changeReadyState = function (objDOMDocument, iReadyState) 
  {
    //change the readyState
    objDOMDocument.readyState = iReadyState;
    
    //if there is an onreadystatechange event handler, run it
    if (objDOMDocument.onreadystatechange != null && typeof objDOMDocument.onreadystatechange == "function")
      objDOMDocument.onreadystatechange();
  };
  
  //add the loadXML() method to the Document class
  Document.prototype.loadXML = function(strXML) 
  {
    //change the readystate
    XmlDocument._changeReadyState(this, 1);

    //create a DOMParser
    var objDOMParser = new DOMParser();
    
    //create new document from string
    var objDoc = objDOMParser.parseFromString(strXML, "text/xml");
      
    //make sure to remove all nodes from the document
    while (this.hasChildNodes())
		  this.removeChild(this.lastChild);

    //add the nodes from the new document (import and append to the current document)
    for (var i=0; i < objDoc.childNodes.length; i++) 
      this.appendChild(this.importNode(objDoc.childNodes[i], true));  
          
    //we can't fire the onload event, so we fake it
    //check for a parsing error
    if (!this.documentElement || this.documentElement.tagName == "parsererror")
      this.parseError = -9999999;

    //change the readyState
    XmlDocument._changeReadyState(this, 4);
  }
     
  //add the getter for the .xml attribute
  Node.prototype.__defineGetter__("xml", 
    function ()
    {
      //create a new XMLSerializer, get and return the XML string
      return (new XMLSerializer).serializeToString(this);
    });
    
  //add the readystate attribute for a Document
  Document.prototype.readyState = "0";
  
  //save a reference to the original load() method
  Document.prototype.__load__ = Document.prototype.load;

  //create our own load() method
  Document.prototype.load = function (strURL) 
  {
    //set the parseError to 0
    this.parseError = 0;

    //change the readyState
    XmlDocument._changeReadyState(this, 1);

    //watch for errors
    try 
    {
      //call the original load method
      this.__load__(strURL);    
    } 
    catch (objException) 
    {
      //set the parseError attribute
      this.parseError = -9999999;
      
      //change the readystate
      XmlDocument._changeReadyState(this, 4);
    } 
  };
    
  //add the onreadystatechange attribute
  Document.prototype.onreadystatechange = null;
  
  //add the parseError attribute
  Document.prototype.parseError = 0;
  
	Document.prototype.setProperty = function(name, value){
		if (name=="SelectionNamespaces") {
			namespaces = {};
			var a = value.split(" xmlns:");
			for (var i=1; i<a.length; i++) {
				var s = a[i].split("=");
				namespaces[s[0]] = s[1].replace(/\"/g, "");
			}
			this._namespaces = { lookupNamespaceURI : function(prefix){return namespaces[prefix]} };
		}
	};

	Document.prototype._namespaces = { lookupNamespaceURI : function(){return null} };

  //Map XPath functions
  if( document.implementation.hasFeature("XPath", "3.0") )
  {
	  XMLDocument.prototype.selectNodes = function(cXPathString, xNode)
	  {
		  xNode = xNode || this;
		  var aItems = this.evaluate(cXPathString, xNode, this._namespaces, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		  var aResult = [];
		  for( var i = 0; i < aItems.snapshotLength; i++)
	  	  aResult[i] =  aItems.snapshotItem(i);
  		
		  return aResult;
  	};
  	
	  XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode)
	  {
		  var xItems = this.selectNodes(cXPathString, xNode || this);
		  return xItems.length ? xItems[0] : null;
	  };

	  Element.prototype.selectNodes = function(cXPathString)
	  {
		  if(this.ownerDocument.selectNodes)
			  return this.ownerDocument.selectNodes(cXPathString, this);
		  else{throw "For XML Elements Only";}
	  };

	  Element.prototype.selectSingleNode = function(cXPathString)
	  {	
		  if(this.ownerDocument.selectSingleNode)
			  return this.ownerDocument.selectSingleNode(cXPathString, this);
		  else
		    throw "For XML Elements Only";
	  };
  }
    
/*////////////////////////////////////////////////////////////////////////////
CODE DERIVED FROM THE ATLAS COMPAT. LAYER JAVASCRIPT
////////////////////////////////////////////////////////////////////////////*/
  XMLDocument.prototype.transformNodeToObject = function(xsl)
  {
    var xslProcessor = new XSLTProcessor();
    xslProcessor.importStylesheet(xsl);
    return xslProcessor.transformToFragment(this, document.implementation.createDocument("","",null));
  }

  Node.prototype.__defineGetter__('baseName',
  function()
  {
    return this.localName; 
  });
  
  Node.prototype.__defineGetter__('text',
  function()
  { 
    return this.textContent; 
  });
  
  DocumentFragment.prototype.getElementById = function(id)
  {
    var nodeQueue =[];
    
    this.childNodes.each(function(childNode) {
      if (childNode.nodeType == 1)
        nodeQueue.queue(childNode);
    });
    
    while (nodeQueue.length)
    {
      var node = nodeQueue.dequeue();
      if (node.id == id)
        return node;

      node.childNodes.each(function (childNode) {
        if (childNode.nodeType == 1)
          nodeQueue.queue(childNode);
      });
    }
    return null;
  }
}
/*////////////////////////////////////////////////////////////////////////////
Microsoft IE CONDITIONAL CODE
////////////////////////////////////////////////////////////////////////////*/ 
else
{
  function XmlDocument(xml)
  {
    //find out which activeX to use
    var xmlObj = $Browser.GetActiveXObject(["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]);
    xmlObj.setProperty("SelectionLanguage", "XPath");
    xmlObj.setProperty("SelectionNamespaces","xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
    if(xml)
        xmlObj.loadXML(xml);
    return xmlObj;  
  }
/*////////////////////////////////////////////////////////////////////////////
XSLT TRANSFORMATION CODE - Makes IE mimic Moz XSLT
////////////////////////////////////////////////////////////////////////////*/

  /* Basic implementation of Mozilla's XSLTProcessor for IE. 
   * Reuses the same XSLT stylesheet for multiple transforms
   * @constructor
   */
  XSLTProcessor = function()
  {
      this.template = $Browser.GetActiveXObject(["MSXML2.XSLTemplate.6.0", "MSXML2.XSLTemplate.4.0", "MSXML2.XSLTemplate.3.0"]);
      this.processor = null;
  };
  /* Imports the given XSLT DOM and compiles it to a reusable transform
   * @argument xslDoc The XSLT DOMDocument to import
   */
  XSLTProcessor.prototype.importStylesheet = function(xslDoc)
  {
    // convert stylesheet to free threaded
    var converted = $Browser.GetActiveXObject(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
    converted.loadXML(xslDoc.xml);
    this.template.stylesheet = converted;
    this.processor = this.template.createProcessor();
    // (re)set default param values
    this.paramsSet = new Array();
  };
  /* Transform the given XML DOM
   * @argument sourceDoc The XML DOMDocument to transform
   * @return The transformation result as a DOM Document
   */
  XSLTProcessor.prototype.transformToDocument = function(sourceDoc)
  {
    this.processor.input = sourceDoc;
    this.processor.transform();
    var oDoc = $Browser.GetActiveXObject(["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"]);;
    oDoc.loadXML(this.processor.output+"");
    return oDoc;
  };
  /**
   * Set global XSLT parameter of the imported stylesheet
   * @argument nsURI The parameter namespace URI
   * @argument name The parameter base name
   * @argument value The new parameter value
   */
  XSLTProcessor.prototype.setParameter = function(nsURI, name, value)
  {
    /* nsURI is optional but cannot be null */
    if(nsURI)
      this.processor.addParameter(name, value, nsURI);
    else
      this.processor.addParameter(name, value);

    /* update updated params for getParameter */
    if(!this.paramsSet[""+nsURI])
      this.paramsSet[""+nsURI] = [];
    this.paramsSet[""+nsURI][name] = value;
  };
  /**
   * Gets a parameter if previously set by setParameter. Returns null
   * otherwise
   * @argument name The parameter base name
   * @argument value The new parameter value
   * @return The parameter value if reviously set by setParameter, null otherwise
   */
  XSLTProcessor.prototype.getParameter = function(nsURI, name)
  {
    nsURI = nsURI || "";
    return this.paramsSet[nsURI] ? this.paramsSet[nsURI][name] : null;
  };
}