The source code

    /**
     * @class Ext.util.Observable
     */
    Ext.apply(Ext.util.Observable.prototype, function(){
        // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
        // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
        // private
        function getMethodEvent(method){
            var e = (this.methodEvents = this.methodEvents ||
            {})[method], returnValue, v, cancel, obj = this;

            if (!e) {
                this.methodEvents[method] = e = {};
                e.originalFn = this[method];
                e.methodName = method;
                e.before = [];
                e.after = [];

                var makeCall = function(fn, scope, args){
                    if (!Ext.isEmpty(v = fn.apply(scope || obj, args))) {
                        if (Ext.isObject(v)) {
                            returnValue = !Ext.isEmpty(v.returnValue) ? v.returnValue : v;
                            cancel = !!v.cancel;
                        }
                        else
                            if (v === false) {
                                cancel = true;
                            }
                            else {
                                returnValue = v;
                            }
                    }
                };

                this[method] = function(){
                    var args = Ext.toArray(arguments);
                    returnValue = v = undefined;
                    cancel = false;

                    Ext.each(e.before, function(b){
                        makeCall(b.fn, b.scope, args);
                        if (cancel) {
                            return returnValue;
                        }
                    });

                    if (!Ext.isEmpty(v = e.originalFn.apply(obj, args))) {
                        returnValue = v;
                    }
                    Ext.each(e.after, function(a){
                        makeCall(a.fn, a.scope, args);
                        if (cancel) {
                            return returnValue;
                        }
                    });
                    return returnValue;
                };
            }
            return e;
        }

        return {
            // these are considered experimental
            // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
            // adds an "interceptor" called before the original method
            beforeMethod: function(method, fn, scope){
                getMethodEvent.call(this, method).before.push({
                    fn: fn,
                    scope: scope
                });
            },

            // adds a "sequence" called after the original method
            afterMethod: function(method, fn, scope){
                getMethodEvent.call(this, method).after.push({
                    fn: fn,
                    scope: scope
                });
            },

            removeMethodListener: function(method, fn, scope){
                var e = getMethodEvent.call(this, method), found = false;
                Ext.each(e.before, function(b, i, arr){
                    if (b.fn == fn && b.scope == scope) {
                        arr.splice(i, 1);
                        found = true;
                        return false;
                    }
                });
                if (!found) {
                    Ext.each(e.after, function(a, i, arr){
                        if (a.fn == fn && a.scope == scope) {
                            arr.splice(i, 1);
                            return false;
                        }
                    });
                }
            },

            /**
             * Relays selected events from the specified Observable as if the events were fired by this.
             * @param {Object} o The Observable whose events this object is to relay.
             * @param {Array} events Array of event names to relay.
             */
            relayEvents: function(o, events){
                var me = this;
                function createHandler(ename){
                    return function(){
                        return me.fireEvent.apply(me, [ename].concat(Ext.toArray(arguments)));
                    };
                }
                Ext.each(events, function(ename){
                    me.events[ename] = me.events[ename] || true;
                    o.on(ename, createHandler(ename), me);
                });
            },

            /**
             * Used to enable bubbling of events
             * @param {Object} events
             */
            enableBubble: function(events){
                var me = this;
                events = Ext.isArray(events) ? events : Ext.toArray(arguments);
                Ext.each(events, function(ename){
                    ename = ename.toLowerCase();
                    var ce = me.events[ename] || true;
                    if (typeof ce == "boolean") {
                        ce = new Ext.util.Event(me, ename);
                        me.events[ename] = ce;
                    }
                    ce.bubble = true;
                });
            }
        };
    }());

    /**
     * Starts capture on the specified Observable. All events will be passed
     * to the supplied function with the event name + standard signature of the event
     * before the event is fired. If the supplied function returns false,
     * the event will not fire.
     * @param {Observable} o The Observable to capture
     * @param {Function} fn The function to call
     * @param {Object} scope (optional) The scope (this object) for the fn
     * @static
     */
    Ext.util.Observable.capture = function(o, fn, scope){
        o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
    };

    /**
     * Sets observability on the passed class constructor.
     * This makes any event fired on any instance of the passed class also fire a single event through
     * the class allowing for central handling of events on many instances at once.
     * Usage:
    Ext.util.Observable.observeClass(Ext.data.Connection);
    Ext.data.Connection.on('beforerequest', function(con, options) {
        console.log("Ajax request made to " + options.url);
    });
     * @param {Function} c The class constructor to make observable.
     * @static
     */
    Ext.util.Observable.observeClass = function(c){
        Ext.apply(c, new Ext.util.Observable());
        c.prototype.fireEvent = function(){
            return (c.fireEvent.apply(c, arguments) !== false) &&
            (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false);
        };
    };