var async = (function (global) {

    // (C) WebReflection - Mit Style License

    // wrappers for asynchronous actrivity such:
    // setInterval, setTimeout, and XMLHttpRequest
    // if you inject stuff or you have extra async stuff
    // you are responsible for
    // ++async;
    // before you do it, and
    // --async;
    // when everything is completed

    /*@cc_on
    // @see http://webreflection.blogspot.com/2007/06/simple-settimeout-setinterval-extra.html
    (function(f){
    global.setTimeout=f(global.setTimeout);
    global.setInterval=f(global.setInterval);
    })(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
    @*/

    function add(i) {
        global.async = ++async;
        return i;
    }
    function rem() {
        global.async = async && --async;
    }
    function done() {
        var
            self = this,
            False = false,
            removeEventListener = "removeEventListener"
        ;
        self[removeEventListener]("load", done, False);
        self[removeEventListener]("error", done, False);
        self[removeEventListener]("abort", done, False);
        rem();
    }
    function open(ed) {
        return function open(way, to, go, my, fried) {
            var
                self = this,
                timer
            ;
            if (go || go == null) {
                timer = setInterval(function () {
                    if (self.readyState == 4) {
                        clearInterval(timer);
                        rem();
                    }
                }, 15);
            }
            // ed.apply(self, arguments) does not work in IE7
            self.open = ed;
            self.open(way, to, go, my, fried);
        };
    }
    var
        setTimeout = global.setTimeout,
        setInterval = global.setInterval,
        clearInterval = global.clearInterval,
        clearTimeout = global.clearTimeout,
        XMLHttpRequest = global.XMLHttpRequest,
        async = 0
    ;
    global.setTimeout = function (callback) {
        var
            args = [].slice.call(arguments)
        ;
        args[0] = function () {
            callback.apply(this, arguments);
            rem();
        };
        return add(setTimeout.apply(global, args));
    };
    global.setInterval = function () {
        return add(setInterval.apply(global, arguments));
    };
    global.clearTimeout = function (i) {
        clearTimeout(i);
        rem();
    };
    global.clearInterval = function (i) {
        clearInterval(i);
        rem();
    };
    global.XMLHttpRequest = function XHR() {
        var
            self = new XMLHttpRequest,
            False = false,
            addEventListener = "addEventListener"
        ;
        if (addEventListener in self /* fucking Opera !!! */ && self.addEventListener) {
            self[addEventListener]("load", done, False);
            self[addEventListener]("error", done, False);
            self[addEventListener]("abort", done, False);
        } else {
            self.open = open(self.open);
        }
        add();
        return self;
    };
    return 0;
}(this));
