    /*!
     * Ext JS Library 3.3.0
     * Copyright(c) 2006-2010 Ext JS, Inc.
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.util.Functions
     * @singleton
     */
    Ext.util.Functions = {
        /**
         * Creates an interceptor function. The passed function is called before the original one. If it returns false,
         * the original one is not called. The resulting function returns the results of the original function.
         * The passed function is called with the parameters of the original function. Example usage:
         *
    var sayHi = function(name){
        alert('Hi, ' + name);
    }

    sayHi('Fred'); // alerts "Hi, Fred"

    // create a new function that validates input without
    // directly modifying the original function:
    var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
        return name == 'Brian';
    });

    sayHiToFriend('Fred');  // no alert
    sayHiToFriend('Brian'); // alerts "Hi, Brian"

         * @param {Function} origFn The original function.
         * @param {Function} newFn The function to call before the original
         * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
         * If omitted, defaults to the scope in which the original function is called or the browser window.
         * @return {Function} The new function
         */
        createInterceptor: function(origFn, newFn, scope) {
            var method = origFn;
            if (!Ext.isFunction(newFn)) {
                return origFn;
            }
            else {
                return function() {
                    var me = this,
                        args = arguments;
                    newFn.target = me;
                    newFn.method = origFn;
                    return (newFn.apply(scope || me || window, args) !== false) ?
                            origFn.apply(me || window, args) :
                            null;
                };
            }
        },

        /**
         * Creates a delegate (callback) that sets the scope to obj.
         * Call directly on any function. Example: Ext.createDelegate(this.myFunction, this, [arg1, arg2])
         * Will create a function that is automatically scoped to obj so that the this variable inside the
         * callback points to obj. Example usage:
         *
    var sayHi = function(name){
        // Note this use of "this.text" here.  This function expects to
        // execute within a scope that contains a text property.  In this
        // example, the "this" variable is pointing to the btn object that
        // was passed in createDelegate below.
        alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
    }

    var btn = new Ext.Button({
        text: 'Say Hi',
        renderTo: Ext.getBody()
    });

    // This callback will execute in the scope of the
    // button instance. Clicking the button alerts
    // "Hi, Fred. You clicked the "Say Hi" button."
    btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));

         * @param {Function} fn The function to delegate.
         * @param {Object} scope (optional) The scope (this reference) in which the function is executed.
         * If omitted, defaults to the browser window.
         * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
         * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
         * if a number the args are inserted at the specified position
         * @return {Function} The new function
         */
        createDelegate: function(fn, obj, args, appendArgs) {
            if (!Ext.isFunction(fn)) {
                return fn;
            }
            return function() {
                var callArgs = args || arguments;
                if (appendArgs === true) {
                    callArgs = Array.prototype.slice.call(arguments, 0);
                    callArgs = callArgs.concat(args);
                }
                else if (Ext.isNumber(appendArgs)) {
                    callArgs = Array.prototype.slice.call(arguments, 0);
                    // copy arguments first
                    var applyArgs = [appendArgs, 0].concat(args);
                    // create method call params
                    Array.prototype.splice.apply(callArgs, applyArgs);
                    // splice them in
                }
                return fn.apply(obj || window, callArgs);
            };
        },

        /**
         * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
         *
    var sayHi = function(name){
        alert('Hi, ' + name);
    }

    // executes immediately:
    sayHi('Fred');

    // executes after 2 seconds:
    Ext.defer(sayHi, 2000, this, ['Fred']);

    // this syntax is sometimes useful for deferring
    // execution of an anonymous function:
    Ext.defer(function(){
        alert('Anonymous');
    }, 100);

         * @param {Function} fn The function to defer.
         * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
         * @param {Object} scope (optional) The scope (this reference) in which the function is executed.
         * If omitted, defaults to the browser window.
         * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
         * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
         * if a number the args are inserted at the specified position
         * @return {Number} The timeout id that can be used with clearTimeout
         */
        defer: function(fn, millis, obj, args, appendArgs) {
            fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
            if (millis > 0) {
                return setTimeout(fn, millis);
            }
            fn();
            return 0;
        },

        /**
         * Create a combined function call sequence of the original function + the passed function.
         * The resulting function returns the results of the original function.
         * The passed fcn is called with the parameters of the original function. Example usage:
         *

    var sayHi = function(name){
        alert('Hi, ' + name);
    }

    sayHi('Fred'); // alerts "Hi, Fred"

    var sayGoodbye = Ext.createSequence(sayHi, function(name){
        alert('Bye, ' + name);
    });

    sayGoodbye('Fred'); // both alerts show

         * @param {Function} origFn The original function.
         * @param {Function} newFn The function to sequence
         * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
         * If omitted, defaults to the scope in which the original function is called or the browser window.
         * @return {Function} The new function
         */
        createSequence: function(origFn, newFn, scope) {
            if (!Ext.isFunction(newFn)) {
                return origFn;
            }
            else {
                return function() {
                    var retval = origFn.apply(this || window, arguments);
                    newFn.apply(scope || this || window, arguments);
                    return retval;
                };
            }
        }
    };

    /**
     * Shorthand for {@link Ext.util.Functions#defer}
     * @param {Function} fn The function to defer.
     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
     * @param {Object} scope (optional) The scope (this reference) in which the function is executed.
     * If omitted, defaults to the browser window.
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     * if a number the args are inserted at the specified position
     * @return {Number} The timeout id that can be used with clearTimeout
     * @member Ext
     * @method defer
     */

    Ext.defer = Ext.util.Functions.defer;

    /**
     * Shorthand for {@link Ext.util.Functions#createInterceptor}
     * @param {Function} origFn The original function.
     * @param {Function} newFn The function to call before the original
     * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
     * If omitted, defaults to the scope in which the original function is called or the browser window.
     * @return {Function} The new function
     * @member Ext
     * @method defer
     */

    Ext.createInterceptor = Ext.util.Functions.createInterceptor;

    /**
     * Shorthand for {@link Ext.util.Functions#createSequence}
     * @param {Function} origFn The original function.
     * @param {Function} newFn The function to sequence
     * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
     * If omitted, defaults to the scope in which the original function is called or the browser window.
     * @return {Function} The new function
     * @member Ext
     * @method defer
     */

    Ext.createSequence = Ext.util.Functions.createSequence;

    /**
     * Shorthand for {@link Ext.util.Functions#createDelegate}
     * @param {Function} fn The function to delegate.
     * @param {Object} scope (optional) The scope (this reference) in which the function is executed.
     * If omitted, defaults to the browser window.
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     * if a number the args are inserted at the specified position
     * @return {Function} The new function
     * @member Ext
     * @method defer
     */
    Ext.createDelegate = Ext.util.Functions.createDelegate;