function CreateParser(url){
	try {
		//This is put in a try-catch block because it doesn't work in the shell (yet)...
		Track("CreateParser(" + url + ")");
	} catch(e) {}
	
	var xmlParser = myXML.createDOMDocument();

	LoadXML(xmlParser, url)
	
	return xmlParser;
}


function LoadXML(xmlParser, url, suppressLoadError){
	try {
		//This is put in a try-catch block because it doesn't work in the shell (yet)...
		Track("LoadXML(xmlParser, " + url + ")");
	} catch(e) {}
	
	if (xmlParser == undefined) {return false;}
	if (url == undefined) {return false;}
	if (url.length == 0) {return false;}
	if (suppressLoadError == undefined) {suppressLoadError = false;}
	
	var loaded = xmlParser.load(url);

	if (loaded){
		loaded = CheckParseErrors(xmlParser, url);
	} else {
		if (!suppressLoadError) {
			if (confirm("There was a problem loading " + url + ".\n\nPress OK to try again. If this problem persists, please contact your system administrator.")){
				loaded = LoadXML(xmlParser, url);
			}
		}
	}
	
	return loaded;
}


function LoadXMLFragment(xmlParser, xmlFragment){
	try {
		//This is put in a try-catch block because it doesn't work in the shell (yet)...
		Track("LoadXMLFragment(xmlParser, " + xmlFragment + ")");
	} catch(e) {}
	
	if (xmlParser == undefined) {return false;}
	if (xmlFragment == undefined) {return false;}
	if (xmlFragment.length == 0) {return false;}

	var loaded = xmlParser.loadXML(xmlFragment);

	if (loaded) {
		loaded = CheckParseErrors(xmlParser);
	} else {
		if (confirm("There was a problem loading\n\n" + xmlFragment + ".\n\nPress OK to try again. If this problem persists, please contact your system administrator.")){
			loaded = LoadXMLFragment(xmlParser, xmlFragment);
		}
	}
	
	return loaded;
}


function CheckParseErrors(xmlParser, url){
	try {
		//This is put in a try-catch block because it doesn't work in the shell (yet)...
		Track("CheckParseErrors(xmlParser, " + url + ")");
	} catch(e) {}
	
	if (url == undefined) {url = "XML data";}

	if (xmlParser.parseError.errorCode == 0) {
		//alert("Succesfully validated!");
		return true;
	} else {
		var myErr = xmlParser.parseError;
		alert("There was a problem parsing " + url + ":\n\n" + myErr.reason + "\n\nLine " + myErr.line + "\n\n" + myErr.srcText);
		return false;
	}
}


var msXmlSigs = ["MSXML4.DOMDocument", "MSXML3.DOMDocument", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XmlDom"];
var msXmlSig = "";

var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1;
var isFF = document.implementation && document.implementation.createDocument;

if (isIE) {
	var parserFound = false;
	for (var i = 0; i < msXmlSigs.length && !parserFound; i++) {
		try {
			var objXML = new ActiveXObject(msXmlSigs[i]);
			msXmlSig = msXmlSigs[i];
			parserFound = true;                
		} catch (e) {}
	}
	if (!parserFound) {throw "No DOM DOcument found on your computer."}
}

if (isFF) {
	Document.prototype.loadXML = function(strXML) {
		changeReadyState(this, 1);
		var domDocParser = new DOMParser();
		var objDoc = domDocParser.parseFromString(strXML, "text/xml");
		while (this.hasChildNodes()){
			this.removeChild(this.lastChild);
		}
		
		for (var i = 0; i < objDoc.childNodes.length; i++) {
			var objImportedNode = this.importNode(objDoc.childNodes[i], true);
			this.appendChild(objImportedNode);
		}
		
		handleOnLoad(this);        
	}
    
    Node.prototype.__defineGetter__("xml", _Node_getXML);
    Node.prototype.__defineGetter__("text", _Node_getText);
    Document.prototype.readyState = "0";
    Document.prototype.__load__ = Document.prototype.load;
    Document.prototype.load = _Document_load;
    Document.prototype.onreadystatechange = null;
    Document.prototype.parseError = 0;
    Document.prototype.selectSingleNode = _selectSingleNode;
    Document.prototype.selectNodes = _selectNodes;
}


function myXML() { }

myXML.createDOMDocument = function(strNamespaceURI, strRootTagName) {
	var domDoc = null;
	
	if (isFF) {
		domDoc = document.implementation.createDocument(strNamespaceURI, strRootTagName, null);    
		domDoc.addEventListener("load", _Document_onload, false);
	} else if (isIE) {
		domDoc = new ActiveXObject(msXmlSig);
		if (strRootTagName) {
			if (strNamespaceURI) {
				domDoc.loadXML("<a0:" + strRootTagName + " xmlns:a0=\"" + strNamespaceURI + "\" />");
			} else {
				domDoc.loadXML("<" + strRootTagName + "/>");        
			}
		}
		domDoc.async = false;
	}
	
	return domDoc;
}

function _Node_getXML() {
	var objXMLSerializer = new XMLSerializer;
	var strXML = objXMLSerializer.serializeToString(this);
	return strXML;
}

function _Node_getText() {
	return this.textContent;
}

function _selectNodes(xPathQuery) {
	//alert("selectNodes for: " + xPathQuery);
	return this.evaluate(xPathQuery, this, null, XPathResult.ANY_TYPE, null);
}

function _selectSingleNode(xPathQuery) {
	//alert("selectSingleNode for: " + xPathQuery);
	return this.evaluate(xPathQuery, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

function _Document_load(strURL) {
	this.parseError = 0;
	
	changeReadyState(this, 1);
	
	try {
		this.__load__(strURL);
	} catch (objException) {
		this.parseError = -9999999;
		changeReadyState(this, 4);
	}
}

function _Document_onload() {
    handleOnLoad(this);
}

function handleOnLoad(domDoc) {
	if (!domDoc.documentElement || domDoc.documentElement.tagName == "parsererror"){
		domDoc.parseError = -9999999;
	}
	
	changeReadyState(domDoc, 4);
}

function changeReadyState(domDoc, iReadyState) {
	domDoc.readyState = iReadyState;
	
	if (domDoc.onreadystatechange != null && typeof domDoc.onreadystatechange == "function"){
		domDoc.onreadystatechange();
	}
}