
	/* ~~~~~~~~~~~~~~~~~~~~ SOAP Object ~~~~~~~~~~~~~~~~~~~~ */
	function SOAPEnvelope(operation, ns)
	{
	    try{
		    this.obj = XML('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"><soap:Body></soap:Body></soap:Envelope>')
		    this.soapAction = ns + ((/\/$/.test(ns))?"":"/") + operation;
            this.ns = ns; 
		    this.operation = this.addChild(operation, this.obj.selectSingleNode("//soap:Envelope/soap:Body"));
		    this.operation.setAttribute('soap:encodingStyle','http://schemas.xmlsoap.org/soap/encoding/');
		    return this;
	    }catch(e){alert("err se:"+e.description)}
	}		
	
	SOAPEnvelope.prototype.addChild = function(name, parentNode, value)
	{
	    try{
		    var el = this.obj.createElement(name);
		    el.setAttribute("xmlns", this.ns);
		    parentNode.appendChild(el);
		    if( value ) { var tn = this.obj.createCDATASection(value); el.appendChild(tn)}
		    return el;
	    }
	    catch(e){alert("addchild error:"+e.description)}
	}
	
	SOAPEnvelope.prototype.compileArgs = function(node, args)
	{
		for (prop in args){
			if (typeof args[prop] != 'object') {
				var o = this.addChild(prop, node, args[prop]);
				//if (typeof prop == 'boolean') o.setAttribute("xsi:type", 'xsd.boolean');
			} 
			else {
				var o = this.addChild(prop, node);
				this.compileArgs(o,args[prop]);
			}
		}
		return node;
	} 

	SOAPEnvelope.prototype.send = function(path, args, callback)
	{
		while(this.operation.hasChildNodes()){this.operation.removeChild(this.operation.lastChild)}
		this.compileArgs(this.operation, args);
        var ajax = new Ajax.Request(path, {
            method      : "POST",
            mimeType    : "application/soap+xml",
            headers     :  {'Content-length':this.obj.xml.length,
                            'Charset': 'utf-8',
                            'Content-Type': 'text/xml; charset=utf-8',
                            'Host': new URL(path).host,
                            'SOAPAction': this.soapAction
                            },
            onComplete  : function(response) {
               var payload = XML.tag(response.xml, "*", "Body");
               callback(payload);
            },
            onFailure   : function(response) {
                alert('ajax.failure: '+ response.status +' = '+ response.statusText );
            },
            onError     : function(error) {alert('ajax.error: '+ error.message );}
        })
        ajax.send(this.obj.xml);
	}
