function isArray(obj) 
{
    if ((typeof(obj) == "object") && (obj.constructor == Array)) 
    {
        return true;
    }
    
    return false;
}

function isBoolString(obj) 
{
    if ((obj.toLowerCase() == "true") || (obj.toLowerCase() == "false")) 
    {
        return true;
    }
    
    return false;
}

function isNumericString(obj) 
{
    var numberstring = "1234567890";
    
    for (var i=0;i<=obj.length-1;i++) 
    {
        if (numberstring.indexOf(obj.charAt(i),0) == -1) 
        {
            return false;
        }
    }

  return true;
}

function ToBool(obj) 
{
    if (obj.toLowerCase() == "true") 
    {
        return true;
    }
    
    return false;
}

function ConstructResult(node) 
{
    var Result;
    
    if ((node.childNodes.length == 1) && (node.firstChild.nodeType == 3)) 
    {
        if (isBoolString(node.firstChild.nodeValue)) 
        {
            Result = ToBool(node.firstChild.nodeValue);
        }
        else if (isNumericString(node.firstChild.nodeValue)) 
        {
            Result = parseInt(node.firstChild.nodeValue);
            
            ResultString = new String(Result);
                       
            if (ResultString != node.firstChild.nodeValue)
            {
                Result = node.firstChild.nodeValue; //fixes the possibility of the parsed result not being equal to the returned result.
            }
        } 
        else 
        {
            Result = node.firstChild.nodeValue;
        }
    } 
    else 
    {
        Result = new Object();

        for(var i=0;i<=node.childNodes.length-1;i++) 
        {
            var child_node = node.childNodes[i];
            if (child_node.nodeType == 1) 
            {
                if (Result[child_node.nodeName] != null)
                {
                    if (isArray(Result[child_node.nodeName]) == true) 
                    {
                        Result[child_node.nodeName][Result[child_node.nodeName].length] = ConstructResult(child_node);
                    } 
                    else 
                    {
                        var temp_obj = Result[child_node.nodeName];
                        Result[child_node.nodeName] = new Array();
                        Result[child_node.nodeName][0] = temp_obj;
                        Result[child_node.nodeName][1] = ConstructResult(child_node);
                    }
                } 
                else 
                {
                    Result[child_node.nodeName] = ConstructResult(child_node);
                }
            }
        }
    }
    
    return Result;
}

function GenerateSoapRequest(service_namespace, method, parameters)
{
    var Result = "";
    Result += "<?xml version='1.0' encoding='utf-8' ?>";
    Result += "<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/'>";
    Result += "<soap:Body>";
    Result += "<"+method+" xmlns='"+service_namespace+"' >";

    var param_array = parameters.split("&");
    for(var i=0;i<=param_array.length-1;i++)
    {
        var param_info_array = param_array[i].split("=");
        Result += "<"+param_info_array[0]+">"+param_info_array[1]+"</"+param_info_array[0]+">";
    }

    Result += "</"+method+">";
    Result += "</soap:Body>";
    Result += "</soap:Envelope>";

    return Result;
}

function Execute(service_url, service_namespace, method, parameters, callback, state)
{
    var RequestObject = null;
    
    if (window.XMLHttpRequest)
    {
        RequestObject = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        RequestObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    if (RequestObject != null)
    {
        RequestObject.onreadystatechange = function()
        {
            if (RequestObject.readyState == 4)
            {
                if (callback != null)
                {
                    if (RequestObject.status == 200)
                    {
                        var documentRoot = RequestObject.responseXML.documentElement.getElementsByTagName(method+"Response")[0].firstChild;
                        var response = ConstructResult(documentRoot);
                        
                        callback(response, state);
                    }
                    else
                    {
                        callback(null, state);
                    }
                }
            }
        }

        RequestObject.open("POST", service_url, true) ;
        RequestObject.setRequestHeader("SOAPAction", service_namespace+method) ;
        RequestObject.setRequestHeader("Content-Type", "text/xml; charset=utf-8" ) ;
      
        RequestObject.send(GenerateSoapRequest(service_namespace, method, parameters));
    }
}