function SOAPClient()
{
    var m_serviceurl;
    var m_servicenamespace = "";
    var m_methodname;    
    var m_parameters = new Array();

    this.setServiceUrl = function(val)
    {
        m_serviceurl = val;
    }

    this.setServiceNamespace = function(val)
    {
        m_servicenamespace = val;
    }
    
    this.setMethodName = function(val)
    {
        m_methodname = val;
    }

    this.addParameter = function(pname, pval)
    {
        m_parameters[pname] = pval;
    }
	
	this.call = function()
	{
	    // load WSDL
		
		try{
			m_wsdl = new ActiveXObject("Microsoft.XMLDOM");
		}
		catch(exception){
			m_wsdl = document.implementation.createDocument("","",null);
			//return null;
		}
		
	    m_wsdl.load(m_serviceurl + "?wsdl");            
	        
	    // build SOAP request
	    var sXml = 
	        "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
	        "<soap:Envelope " +
	        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
	        "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
	        "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
	        "<soap:Body>" +
	        "<" + m_methodname + " xmlns=\"" + m_servicenamespace + "\">";
	    for(var i in m_parameters)
	        sXml += "<" + i + ">" + m_parameters[i] + "</" + i + ">";
	    sXml += "</" + m_methodname + "></soap:Body></soap:Envelope>";
	    
		var xmlHTTP;
		try{
			xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(exception){
			try
			{
				xmlHTTP  = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(exception2)
			{
			xmlHTTP = new XMLHttpRequest();
			}
		}
		xmlHTTP.open("POST", m_serviceurl, false);
	    xmlHTTP.setRequestHeader("SOAPAction", m_servicenamespace + m_methodname);
	    xmlHTTP.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
	    xmlHTTP.send(sXml);
	   
	    // set raw xml
	    m_rawxml = xmlHTTP.responseXML.xml + "";
	     // .NET way - the only way :-)
		var nd = SelectSingleNode(xmlHTTP.responseXML, "//" + m_methodname + "Result");
		
		if(nd == null)
	    {
			var faultcode = SelectSingleNode(xmlHTTP.responseXML, "//faultcode/text()");
			if(faultcode != null)
	            throw new Error(500, SelectSingleNode(xmlHTTP.responseXML, "//faultcode/text()").nodeValue + " - " + SelectSingleNode(xmlHTTP.responseXML, "//faultcode/text()").nodeValue);
	        else
	            return null;
	    }
		
		return this.soapresult2object(nd);
	} 
	
	this.soapresult2object = function(node)
	{
	    return this.node2object(node);
	}

	this.node2object = function(node)
	{    
	    // null node
	    if(node == null)
	        return null;
	    // text node
	    if(node.nodeType == 3 || node.nodeType == 4)
	        return this.extractValue(node);

	    // leaf node
	    if (node.hasChildNodes() && node.childNodes.length==1 && (node.firstChild.nodeType == 3 || node.firstChild.nodeType == 4))
	        return this.node2object(node.firstChild);
	    var isarray = false;
	    var el = m_wsdl.selectSingleNode("//s:element[@name='" + node.nodeName + "']");
	    isarray = (el!=null && el.attributes.getNamedItem("type")!=null && (el.attributes.getNamedItem("type").nodeValue + "").toLowerCase().indexOf("arrayof") != -1);

	    // object node
	    if(!isarray)
	    {
	        var obj = null;
	        if(node.hasChildNodes())
	            obj = new Object();
	        for(var i = 0; i < node.childNodes.length; i++)
	        {
	            var p = this.node2object(node.childNodes[i]);
	            obj[node.childNodes[i].nodeName] = p;
	        }
	        return obj;
	    }

	    // list node
	    else
	    {
	        // create node ref
	        var l = new Array();
	        for(var i = 0; i < node.childNodes.length; i++)
	        {
	            var cn = node.childNodes[i];
	            l[l.length] = this.node2object(cn);
	        }
	        return l;
	    }
	    return null;
	} 

	this.extractValue = function(node)
	{
	    var value = node.nodeValue;
	    var el = m_wsdl.selectSingleNode("//s:element[@name='" + node.parentNode.nodeName + "']");
	    var type = (el != null && el.attributes.getNamedItem("type") != null) ? (el.attributes.getNamedItem("type").nodeValue + "").toLowerCase() : null;
	    switch(type)
	    {
	        default:
	        case "s:string":            
	        {
	            return (value != null) ? value + "" : "";
	        }
	        case "s:boolean":
	        {
	            return value+"" == "true";
	        }
	        case "s:int":
	        case "s:long":
	        {
	            return (value != null) ? parseInt(value + "", 10) : 0;
	        }
	        case "s:double":
	        {
	            return (value != null) ? parseFloat(value + "") : 0;
	        }
	        case "s:datetime":
	        {
	            if(value == null)
	                return null;
	            else
	            {
	                value = value + "";
	                value = value.substring(0, value.lastIndexOf("."));
	                value = value.replace(/T/gi," ");
	                value = value.replace(/-/gi,"/");
	                var d = new Date();
	                d.setTime(Date.parse(value));                                        
	                return d;                
	            }
	        }
	    }        
	} 

		
} 

 function SelectSingleNode(xmlDoc, elementPath)
    {
        if(window.ActiveXObject)
        {
            return xmlDoc.selectSingleNode(elementPath);
        }
        else
        {
           var xpe = new XPathEvaluator();
           var nsResolver = xpe.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);
           var results = xpe.evaluate(elementPath,xmlDoc,nsResolver,XPathResult.FIRST_ORDERED_NODE_TYPE, null);
           return results.singleNodeValue; 
        }
    }


