function getDomDocumentPrefix() {
	if (getDomDocumentPrefix.prefix)
		return getDomDocumentPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".DomDocument.3.0");
			//o = new ActiveXObject(prefixes[i] + ".XMLDOM");
			return getDomDocumentPrefix.prefix = prefixes[i];
		}
		catch (ex) {
			//alert("kan object niet aanmaken prefixes[i]: " + prefixes[i]);
		};
	}
	
	throw new Error("Could not find an installed XML parser");
}

// XmlDocument factory
function XmlDocument() {}

XmlDocument.create = function () {
	try {
		//alert('create xmlDocument');
		// DOM2
		if (document.implementation && document.implementation.createDocument) {
			//alert("XmlDocument.create (doc): " + doc);
			var doc = document.implementation.createDocument("", "", null);
			//alert("XmlDocument.create (doc): " + doc);
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (doc.readyState == null) {
				doc.readyState = 1;
				doc.addEventListener("load", function () {
					                            doc.readyState = 4;
					                            if (typeof doc.onreadystatechange == "function")
						                            doc.onreadystatechange();
				                            }, false);
			}
			
			return doc;
		}
		if (window.ActiveXObject)
			//alert("(window.ActiveXObject): ");
			//alert("getDomDocumentPrefix(): " + getDomDocumentPrefix());
			//alert("aanmaken van object " + getDomDocumentPrefix() + ".DomDocument");
			//alert(new ActiveXObject(getDomDocumentPrefix() + ".DomDocument"));

			return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
			
	}
	catch (ex) {
	    throw new Error("Your browser does not support XmlDocument objects");
	}
};

// Create the loadXML method and xml getter for Mozilla
//alert("window.DOMParser: " + window.DOMParser);
//alert("window.XMLSerializer: " + window.XMLSerializer);
//alert("window.Node: " + window.Node);
//alert("Node.prototype: " + Node.prototype);
//alert("Node.prototype.__defineGetter__: " + Node.prototype.__defineGetter__);
//alert("xPath): " + xPath));

if (window.DOMParser &&
	window.XMLSerializer &&
	window.Node && Node.prototype && Node.prototype.__defineGetter__) {

	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both!
	Document.prototype.loadXML = function (s) {	
		//alert("Document.prototype");
		// parse the string to a new doc	
		var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
		// remove all initial children
		while (this.hasChildNodes())
			this.removeChild(this.lastChild);
		// insert and import nodes
		for (var i = 0; i < doc2.childNodes.length; i++) {
			this.appendChild(this.importNode(doc2.childNodes[i], true));
		}
	};
	
	/*
	 * xml getter
	 *
	 * This serializes the DOM tree to an XML String
	 *
	 * Usage: var sXml = oNode.xml
	 *
	 */
	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both!
	Document.prototype.__defineGetter__("xml", function () {
		//alert("Document.prototype.__defineGetter__");
		return (new XMLSerializer()).serializeToString(this);
	});
  
    // select the first node that matches the XPath expression
    // xPath: the XPath expression to use
    XMLDocument.prototype.selectSingleNode = function(xPath) {
	//alert("XMLDocument.prototype.selectSingleNode");
        var doc = this;
        if (doc.nodeType != 9)
            doc = doc.ownerDocument;
            
        if (doc.nsResolver == null) doc.nsResolver = function(prefix) { return(null); };
        
        var node = doc.evaluate(xPath, this, doc.nsResolver, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
        if (node != null) node = node.singleNodeValue;
            return(node);
    }; // selectSingleNode

    Node.prototype.__defineGetter__("text", function () {return(this.textContent);}); // text
}