var zXml  = {
    useActiveX: (typeof ActiveXObject != "undefined"),
    useDom: document.implementation && document.implementation.createDocument,
    useXmlHttp: (typeof XMLHttpRequest != "undefined")
};

zXml.ARR_XMLHTTP_VERS  = ["MSXML2.XmlHttp.6.0","MSXML2.XmlHttp.3.0"];

zXml.ARR_DOM_VERS  = ["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.5.0","MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","Microsoft.XmlDom","MSXML.DOMDocument"];

function zXmlHttp() {
}

zXmlHttp.createRequest = function (){

    if (zXml.useXmlHttp) {
        return new XMLHttpRequest();
    } else if (zXml.useActiveX) {
        if (!zXml.XMLHTTP_VER) {
            for (var i=0; i < zXml.ARR_XMLHTTP_VERS.length; i++) {
                try {
                    new ActiveXObject(zXml.ARR_XMLHTTP_VERS[i]);
                    zXml.XMLHTTP_VER = zXml.ARR_XMLHTTP_VERS[i];
                    break;
                } catch (oError) {
                }
            }
        }
        if (zXml.XMLHTTP_VER) {
            return new ActiveXObject(zXml.XMLHTTP_VER);
        } else {
            throw new Error("Could not create XML HTTP Request.");
        }
    } else {
        throw new Error("Your browser doesn't support an XML HTTP Request.");
    }
};

zXmlHttp.isSupported = function ()/*:Boolean*/ {
    return zXml.useXmlHttp || zXml.useActiveX;
};

function zXmlDom() {
}

zXmlDom.createDocument = function () {
    if (zXml.useDom) {
        var oXmlDom = document.implementation.createDocument("","",null);
        return oXmlDom;
    } else if (zXml.useActiveX) {
        if (!zXml.DOM_VER) {
            for (var i=0; i < zXml.ARR_DOM_VERS.length; i++) {
                try {
                    new ActiveXObject(zXml.ARR_DOM_VERS[i]);
                    zXml.DOM_VER = zXml.ARR_DOM_VERS[i];
                    break;
                } catch (oError) {
                }
            }
        }
        if (zXml.DOM_VER) {
            return new ActiveXObject(zXml.DOM_VER);
        } else {
            throw new Error("Could not create XML DOM document.");
        }
    } else {
        throw new Error("Your browser doesn't support an XML DOM document.");
    }
};
zXmlDom.isSupported = function (){
    return zXml.useDom || zXml.useActiveX;
};
var oMozDocument = null;

if (typeof Document !="undefined") {
    oMozDocument = Document;
}
if (oMozDocument) {
    oMozDocument.prototype.loadXML = function (sXml) {

        var oParser = new DOMParser();
        var oXmlDom = oParser.parseFromString(sXml, "text/xml");
        while (this.firstChild) {
            this.removeChild(this.firstChild);
        }
        for (var i=0; i < oXmlDom.childNodes.length; i++) {
            var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
            this.appendChild(oNewNode);
        }

    };

     oMozDocument.prototype.selectNodes = Element.prototype.selectNodes = function (xpath){
         var  xpe  =   new  XPathEvaluator();
         var  nsResolver  =  xpe.createNSResolver( this .ownerDocument  ==   null   ?
         this .documentElement :  this .ownerDocument.documentElement);
         var  result  =  xpe.evaluate(xpath,  this , nsResolver,  0 ,  null );
         var  found  =  [];
         var  res;
         while  (res  =  result.iterateNext())
         found.push(res);
         return  found;
     }

    Node.prototype.__defineGetter__("xml", function () {
        var oSerializer = new XMLSerializer();
        return oSerializer.serializeToString(this, "text/xml");
    });
    Node.prototype.__defineGetter__("text", function () {
        var sText = "";
        for (var i = 0; i < this.childNodes.length; i++) {
            if (this.childNodes[i].hasChildNodes()) {
                sText += this.childNodes[i].text;
            } else {
                sText += this.childNodes[i].nodeValue;
            }
        }
        return sText;
    });
}

function zXslt() {
}

zXslt.transformToText = function (oXml, oXslt) {
    if (typeof XSLTProcessor != "undefined") {
        var oProcessor = new XSLTProcessor();
        oProcessor.importStylesheet(oXslt);
        var oResultDom = oProcessor.transformToDocument(oXml);
        var sResult = oResultDom.xml;
        if (sResult.indexOf("<transformiix:result") > -1) {
            sResult = sResult.substring(sResult.indexOf(">") + 1,
                                        sResult.lastIndexOf("<"));
        }
        return sResult;
    } else if (zXml.useActiveX) {
        return oXml.transformNode(oXslt);
    } else {
        throw new Error("No XSLT engine found.");
    }
};

function zXPath() {
}

zXPath.selectNodes = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {
    if (typeof XPathEvaluator != "undefined") {
        oXmlNs = oXmlNs || {};
        var nsResolver = function (sPrefix) {
    			  return oXmlNs[sPrefix];
        };
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver,
                                          XPathResult.ORDERED_NODE_ITERATOR_TYPE,
                                          null);
        var aNodes = new Array;
        if (oResult != null) {
            var oElement = oResult.iterateNext();
            while(oElement) {
                aNodes.push(oElement);
                oElement = oResult.iterateNext();
            }
        }
        return aNodes;
    } else if (zXml.useActiveX) {
    		if (oXmlNs) {
            var sXmlNs = "";
            for (var sProp in oXmlNs) {
                sXmlNs += "xmlns:" + sProp + "=\'" + oXmlNs[sProp] + "\' ";
            }
    			  oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
    		}
        return oRefNode.selectNodes(sXPath);
    } else {
        throw new Error("No XPath engine found.");
    }
};
/**
 * Selects the first node matching a given XPath expression.
 * @param oRefNode The node from which to evaluate the expression.
 * @param sXPath The XPath expression.
 * @param oXmlNs An object containing the namespaces used in the expression.
 * @return An XML node matching the expression or null if no matches found.
 */
zXPath.selectSingleNode = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {
    if (typeof XPathEvaluator != "undefined") {
        oXmlNs = oXmlNs || {};
        var nsResolver = function (sPrefix) {
    			  return oXmlNs[sPrefix];
        };
        var oEvaluator = new XPathEvaluator();
        var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver,
                                          XPathResult.FIRST_ORDERED_NODE_TYPE, null);
        if (oResult != null) {
            return oResult.singleNodeValue;
        } else {
            return null;
        }
    } else if (zXml.useActiveX) {
    		if (oXmlNs) {
            var sXmlNs = "";
            for (var sProp in oXmlNs) {
                sXmlNs += "xmlns:" + sProp + "=\'" + oXmlNs[sProp] + "\' ";
            }
    			  oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
    		}
        return oRefNode.selectSingleNode(sXPath);
    } else {
        throw new Error("No XPath engine found.")
    }
};
/**
 * General purpose XML serializer.
 * @class
 */
function zXMLSerializer() {
}
/**
 * Serializes the given XML node into an XML string.
 * @param oNode The XML node to serialize.
 * @return An XML string.
 */
zXMLSerializer.prototype.serializeToString = function (oNode /*:Node*/)/*:String*/ {
    var sXml = "";
    switch (oNode.nodeType) {
        case 1: //element
            sXml = "<" + oNode.tagName;
            for (var i=0; i < oNode.attributes.length; i++) {
                sXml += " " + oNode.attributes[i].name + "=\"" + oNode.attributes[i].value + "\"";
            }
            sXml += ">";
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            sXml += "</" + oNode.tagName + ">";
            break;
        case 3: //text node
            sXml = oNode.nodeValue;
            break;
        case 4: //cdata
            sXml = "<![CDATA[" + oNode.nodeValue + "]]>";
            break;
        case 7: //processing instruction
            sXml = "<?" + oNode.nodevalue + "?>";
            break;
        case 8: //comment
            sXml = "<!--" + oNode.nodevalue + "-->";
            break;
        case 9: //document
            for (var i=0; i < oNode.childNodes.length; i++){
                sXml += this.serializeToString(oNode.childNodes[i]);
            }
            break;
    }
    return sXml;
};

String.prototype.Trim = function() {
	 return this.replace(/(^\s*)|(\s*$)/g, "");
}
String.prototype.LTrim = function() {
 	return this.replace(/(^\s*)/g, "");
}
String.prototype.RTrim = function() {
 	 return this.replace(/(\s*$)/g, "");
}

