function xbXMLDocument(namespaceURI, nodeName, doctype)
{
    this.doc = null;
    this.isDocument = false;
    this.nodes = new Array();
    if (namespaceURI == "isDocument") {
        this.doc = document;
        this.isDocument = true;
        return;
    }

    if (document.implementation && document.implementation.createDocument)
    {
        //Mozilla incorrectly uses '' as no-namespaceURI
        if (!namespaceURI)
            namespaceURI = '';

        if (!doctype)
            doctype = null;
        this.doc = document.implementation.createDocument(namespaceURI, nodeName, doctype);
    }
}

xbXMLDocument.prototype = {

	load:function(file) {
		this.doc.load(file);
	},
	
	set onload(callback) {
		this.doc.onload = callback;
	},
	
	nodeWrapperFactory:function(node) {
		if (!node)
		{
			return null;
		}
		if (node.nodeType == 1) {
			var bxe_id = node.getAttribute("bxe_id");
		}
		if (bxe_id && this.nodes[bxe_id] && this.nodes[bxe_id].className ==  "XMLNodeWrapper") {
			return this.nodes[bxe_id];
		} else {
			this.nodes[bxe_id] = new XMLNodeWrapper(node,this);
			return this.nodes[bxe_id];
		}

	},

	getElementsByTagName:function(name) {
		return this.getElementsByTagNameNS("",name);
	},

	getElementsByTagNameNS:function(uri,name) {
		var nodes = this.doc.getElementsByTagNameNS(uri,name);
		var nodesWrapper = new Array();
		for (var i = 0; i < nodes.length; i++)
		{
			nodesWrapper[i] = this.nodeWrapperFactory(nodes[i]);
		}

		return nodesWrapper;
	},
	getElementById:function (id) {
		return this.nodeWrapperFactory(this.doc.getElementById(id));
	},

	importNode:function(importedNode,deep) {
		return this.nodeWrapperFactory(this.doc.importNode(importedNode.node,deep));
	},
	createNode:function(nodeType,nodeName,nodeValue,nodeNamespace) {
		return this.nodeWrapperFactory(this.doc.createNode(importedNode,deep));
	},

	createElement:function(nodeName) {
		return this.nodeWrapperFactory(this.doc.createElement(nodeName));
	}

}
function XMLNodeWrapper(node,docu) {

	this.node = node;
	this.ownerDocument = docu;
	this.bxe_id = bxe_id++;
	if (node.nodeType == 1 && !node.getAttribute("bxe_id"))
	{
		node.setAttribute("bxe_id",this.bxe_id);
	}
	//this.parentNode = node.parentNode;

	this.className = "XMLNodeWrapper";
	if (this.node && this.node.ownerDocument == document) {
		this.isDocument = true;
	}
}


XMLNodeWrapper.prototype = {

   cloneNode:function (deep) {
	   return this.ownerDocument.nodeWrapperFactory(this.node.cloneNode(deep));
   },

   xml:function() {
	   return this.node.xml;
   },
   appendChild:function(childNode) {
	   return this.ownerDocument.nodeWrapperFactory(this.node.appendChild(childNode.node));
   },

   getOwnerDocument:function() {
	   return this.ownerDocument;
   }
}
