function advAJAX() {

    var obj = new Object();

    obj.url = window.location.href;
    obj.method = "GET";
    obj.async = true;
    obj.mimeType = "text/xml";
    obj.username = null;
    obj.password = null;
    obj.parameters = new Object();
    obj.headers = new Object();
    obj.form = null;
    obj.disableForm = true;

    obj.unique = true;
    obj.uniqueParameter = "advajax_uniqid";

    obj.requestDone = false;
    obj.queryString = "";
    obj.responseText = null;
    obj.responseXML = null;
    obj.status = null;
    obj.statusText = null;
    obj.aborted = false;
    obj.timeout = 0;
    obj.retryCount = 0;
    obj.retryDelay = 1000;
    obj.tag = null;
    obj.group = null;

    obj.xmlHttpRequest = null;

    obj.onInitialization = null;
    obj.onFinalization = null;
    obj.onLoading = null;
    obj.onLoaded = null;
    obj.onInteractive = null
    obj.onComplete = null;
    obj.onSuccess = null;
    obj.onFatalError = null;
    obj.onError = null;
    obj.onTimeout = null;
    obj.onRetryDelay = null;
    obj.onRetry = null;
    obj.onGroupEnter = null;
    obj.onGroupLeave = null;

    obj.createXmlHttpRequest = function() {

        if (typeof XMLHttpRequest != "undefined")
          return new XMLHttpRequest();
        try {
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (E) {
            try {
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                if (typeof obj.onFatalError == "function")
                  obj.onFatalError(e);
                return null;
            }
            if (typeof obj.onFatalError == "function")
              obj.onFatalError(E);
        }
        return null;
    };

    obj._onInitializationHandled = false;
    obj._initObject = function() {

        if (obj.xmlHttpRequest != null) {
            delete obj.xmlHttpRequest["onreadystatechange"];
            obj.xmlHttpRequest = null;
        }
        if ((obj.xmlHttpRequest = obj.createXmlHttpRequest()) == null) {
            if (typeof obj.onFatalError == "function")
              obj.onFatalError(null);
            return null;
        };
        if (typeof obj.xmlHttpRequest.overrideMimeType != "undefined")
          obj.xmlHttpRequest.overrideMimeType(obj.mimeType);
        obj.xmlHttpRequest.onreadystatechange = function() {

            if (obj == null || obj.xmlHttpRequest == null)
              return;
            switch (obj.xmlHttpRequest.readyState) {
                case 1: obj._onLoading(obj); break;
                case 2: obj._onLoaded(obj); break;
                case 3: obj._onInteractive(obj); break;
                case 4: obj._onComplete(obj); break;
            }
        };
        obj._onLoadingHandled = false;
        obj._onLoadedHandled = false;
        obj._onInteractiveHandled = false;
        obj._onCompleteHandled = false;
    };

    obj._onLoading = function() {

        if (obj._onLoadingHandled)
          return;
        if (!obj._retry && obj.group != null) {
            if (typeof advAJAX._groupData[obj.group] == "undefined")
              advAJAX._groupData[obj.group] = 0;
            advAJAX._groupData[obj.group]++;
            if (typeof obj.onGroupEnter == "function" && advAJAX._groupData[obj.group] == 1)
              obj.onGroupEnter(obj);
        }
        if (typeof obj.onLoading == "function")
          obj.onLoading(obj);
        obj._onLoadingHandled = true;
    };
    obj._onLoaded = function() {

        if (obj._onLoadedHandled)
          return;
        if (typeof obj.onLoaded == "function")
          obj.onLoaded(obj);
        obj._onLoadedHandled = true;
    };
    obj._onInteractive = function() {

        if (obj._onInteractiveHandled)
          return;
        if (typeof obj.onInteractive == "function")
          obj.onInteractive(obj);
        obj._onInteractiveHandled = true;
    };
    obj._onComplete = function() {

        if (obj._onCompleteHandled || obj.aborted)
          return;
        obj.requestDone = true;
        with (obj.xmlHttpRequest) {
            obj.responseText = responseText;
            obj.responseXML = responseXML;
            if (typeof status != "undefined")
              obj.status = status;
            if (typeof statusText != "undefined")
              obj.statusText = statusText;
        }
        if (typeof obj.onComplete == "function")
          obj.onComplete(obj);
        obj._onCompleteHandled = true;
        if (obj.status == 200 && typeof obj.onSuccess == "function")
          obj.onSuccess(obj);
        else if (typeof obj.onError == "function")
          obj.onError(obj);
        delete obj.xmlHttpRequest['onreadystatechange'];
        obj.xmlHttpRequest = null;
        if (obj.disableForm)
          obj.switchForm(true);
        obj._groupLeave();
        if (typeof obj.onFinalization == "function")
          obj.onFinalization(obj);
    };

    obj._groupLeave = function() {

        if (obj.group != null) {
            advAJAX._groupData[obj.group]--;
            if (typeof obj.onGroupLeave == "function" && advAJAX._groupData[obj.group] == 0)
              obj.onGroupLeave(obj);
        }
    };

    obj._retry = false;
    obj._retryNo = 0;
    obj._onTimeout = function() {

        if (obj == null || obj.xmlHttpRequest == null || obj._onCompleteHandled)
          return;
        obj.aborted = true;
        obj.xmlHttpRequest.abort();
        if (typeof obj.onTimeout == "function")
          obj.onTimeout(obj);
        obj._retry = true;
        if (obj._retryNo != obj.retryCount) {
            obj._initObject();
            if (obj.retryDelay > 0) {
                if (typeof obj.onRetryDelay == "function")
                  obj.onRetryDelay(obj);
                startTime = new Date().getTime();
                while (new Date().getTime() - startTime < obj.retryDelay);
            }
            obj._retryNo++;
            if (typeof obj.onRetry == "function")
              obj.onRetry(obj, obj._retryNo);
            obj.run();
        } else {
            delete obj.xmlHttpRequest["onreadystatechange"];
            obj.xmlHttpRequest = null;
            if (obj.disableForm)
              obj.switchForm(true);
            obj._groupLeave();
            if (typeof obj.onFinalization == "function")
              obj.onFinalization(obj);
        }
    };

    //
    obj.run = function() {

        obj._initObject();
        if (obj.xmlHttpRequest == null)
          return false;
        obj.aborted = false;
        if (typeof obj.onInitialization == "function" && !obj._onInitializationHandled) {
            obj.onInitialization(obj);
            obj._onInitializationHandled = true;
            if(obj.aborted) //controllo introdotto da Gabriele :)
               return;
        }
        if (obj.method == "GET" && obj.unique)
          obj.parameters[encodeURIComponent(obj.uniqueParameter)] =
            new Date().getTime().toString().substr(5) + Math.floor(Math.random() * 100).toString();
        if (!obj._retry) {
            for (var a in obj.parameters) {
                if (obj.queryString.length > 0)
                  obj.queryString += "&";
                obj.queryString += encodeURIComponent(a) + "=" + encodeURIComponent(obj.parameters[a]);
            }
            if (obj.method == "GET" && obj.queryString.length > 0)
              obj.url += (obj.url.indexOf("?") != -1 ? "&" : "?") + obj.queryString;
        }
        if (obj.disableForm)
          obj.switchForm(false);
        try {
            obj.xmlHttpRequest.open(obj.method, obj.url, obj.async, obj.username, obj.password);
        } catch (e) {
            if (typeof obj.onFatalError == "function")
              obj.onFatalError(e);
            return;
        }
        if (obj.timeout > 0)
          setTimeout(obj._onTimeout, obj.timeout);
        if (typeof obj.xmlHttpRequest.setRequestHeader != "undefined")
            for (var a in obj.headers)
              obj.xmlHttpRequest.setRequestHeader(encodeURIComponent(a), encodeURIComponent(obj.headers[a]));
        if (obj.method == "POST" && typeof obj.xmlHttpRequest.setRequestHeader != "undefined") {
            obj.xmlHttpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            obj.xmlHttpRequest.send(obj.queryString);
        } else if (obj.method == "GET")
          obj.xmlHttpRequest.send(null);
    };

    obj.handleArguments = function(args) {

        if (typeof args.form == "object" && args.form != null) {
            obj.form = args.form;
            obj.appendForm();
        }
        for (a in args) {
            if (typeof obj[a] == "undefined")
              obj.parameters[a] = args[a]; else {
              if (a != "parameters" && a != "headers")
                obj[a] = args[a]; else
                for (b in args[a])
                  obj[a][b] = args[a][b];
              }
        }
        obj.method = obj.method.toUpperCase();
    };

    obj.switchForm = function(enable) {

        if (typeof obj.form != "object" || obj.form == null)
          return;
        with (obj.form)
          for (var nr = 0; nr < elements.length; nr++)
            if (!enable) {
                if (elements[nr]["disabled"])
                  elements[nr]["advajax_disabled"] = true; else
                  elements[nr]["disabled"] = "disabled";
            } else
              if (typeof elements[nr]["advajax_disabled"] == "undefined")
                elements[nr].removeAttribute("disabled");
    };

    obj.appendForm = function() {

        with (obj.form) {
            obj.method = method.toUpperCase();
            obj.url = action;
            for (var nr = 0; nr < elements.length; nr++) {
                var e = elements[nr];
                if (e.disabled)
                  continue;
                switch (e.type) {

                    case "text":
                    case "password":
                    case "hidden":
                    case "textarea":
                      obj.addParameter(e.name, e.value);
                      break;

                    case "select-one":
                      if (e.selectedIndex >= 0)
                        obj.addParameter(e.name, e.options[e.selectedIndex].value);
                      break;

                    case "select-multiple":
                      for (var nr2 = 0; nr2 < e.options.length; nr2++)
                        if (e.options[nr2].selected)
                          obj.addParameter(e.name, e.options[nr2].value);
                      break;

                    case "checkbox":
                    case "radio":
                      if (e.checked)
                        obj.addParameter(e.name, e.value);
                      break;
                }
            }
        }
    };

    obj.addParameter = function(name, value) {

        obj.parameters[name] = value;
    };
    obj.delParameter = function(name) {

        delete obj.parameters[name];
    };

    if (typeof advAJAX._defaultParameters != "undefined")
      obj.handleArguments(advAJAX._defaultParameters);
        return obj;
}

advAJAX.get = function(args) {

    return advAJAX.handleRequest("GET", args);
};

advAJAX.post = function(args) {

    return advAJAX.handleRequest("POST", args);
};

advAJAX.head = function(args) {

    return advAJAX.handleRequest("HEAD", args);
};

advAJAX.submit = function(form, args) {

    if (typeof args == "undefined" || args == null)
      return -1;
    if (typeof form != "object" || form == null)
      return -2;
    var request = new advAJAX();
    args["form"] = form;
    request.handleArguments(args);
    return request.run();
};

advAJAX.assign = function(form, args) {

    if (typeof args == "undefined" || args == null)
      return -1;
    if (typeof form != "object" || form == null)
      return -2;
    if (typeof form["onsubmit"] == "function")
      form["advajax_onsubmit"] = form["onsubmit"];
    form["advajax_args"] = args;
    form["onsubmit"] = function() {

        if (typeof this["advajax_onsubmit"] != "undefined")
          this["advajax_onsubmit"]();
        if (advAJAX.submit(this, this["advajax_args"]) == false)
          return true;
        return false;
    }
    return true;
};

advAJAX.handleRequest = function(requestType, args) {

    if (typeof args == "undefined" || args == null)
      return -1;
    var request = new advAJAX();
    request.method = requestType;
    request.handleArguments(args);
    return request.run();
};

advAJAX._defaultParameters = new Object();
advAJAX.setDefaultParameters = function(args) {

    advAJAX._defaultParameters = new Object();
    for (a in args)
      advAJAX._defaultParameters[a] = args[a];
};

advAJAX._groupData = new Object();
