    /**
     * @author Ed Spencer
     * @private
     *
     * The Router is an ordered set of route definitions that decode a url into a controller function to execute. Each
     * route defines a type of url to match, along with the controller function to call if it is matched. The Router is
     * usually managed exclusively by an {@link Ext.app.Application Application}, which also uses a
     * {@link Ext.app.History History} instance to find out when the browser's url has changed.
     *
     * Routes are almost always defined inside a {@link Ext.app.Controller Controller}, as opposed to on the Router itself.
     * End-developers should not usually need to interact directly with the Router as the Application and Controller
     * classes manage everything automatically. See the {@link Ext.app.Controller Controller documentation} for more
     * information on specifying routes.
     */
    Ext.define('Ext.app.Router', {
        requires: ['Ext.app.Route'],

        config: {
            /**
             * @cfg {Array} routes The set of routes contained within this Router. Read only
             */
            routes: [],

            /**
             * @cfg {Object} defaults Default configuration options for each Route connected to this Router.
             */
            defaults: {
                action: 'index'
            }
        },

        constructor: function(config) {
            this.initConfig(config);
        },

        /**
         * Connects a url-based route to a controller/action pair plus additional params
         * @param {String} url The url to recognize
         */
        connect: function(url, params) {
            params = Ext.apply({url: url}, params || {}, this.getDefaults());
            var route = Ext.create('Ext.app.Route', params);

            this.getRoutes().push(route);

            return route;
        },

        /**
         * Recognizes a url string connected to the Router, return the controller/action pair plus any additional
         * config associated with it
         * @param {String} url The url to recognize
         * @return {Object/undefined} If the url was recognized, the controller and action to call, else undefined
         */
        recognize: function(url) {
            var routes = this.getRoutes(),
                length = routes.length,
                i, result;

            for (i = 0; i < length; i++) {
                result = routes[i].recognize(url);

                if (result !== undefined) {
                    return result;
                }
            }

            return undefined;
        },

        /**
         * Convenience method which just calls the supplied function with the Router instance. Example usage:
    <pre><code>
    Ext.Router.draw(function(map) {
        map.connect('activate/:token', {controller: 'users', action: 'activate'});
        map.connect('home',            {controller: 'index', action: 'home'});
    });
    </code></pre>
         * @param {Function} fn The fn to call
         */
        draw: function(fn) {
            fn.call(this, this);
        },

        /**
         * @private
         */
        clear: function() {
            this.setRoutes([]);
        }
    }, function() {
        //<deprecated product=touch since=2.0>
        /**
         * Restores compatibility for the old Ext.Router.draw syntax. This needs to be here because apps often include
         * routes.js just after app.js, so this is our only opportunity to hook this in. There is a small piece of code
         * inside Application's onDependenciesLoaded that sets up the other end of this.
         * @singleton
         * @private
         */
        Ext.Router = {};

        var drawStack = [];

        /**
         * Application's onDependenciesLoaded has a deprecated-wrapped line that calls this. Basic idea is that once an
         * app has been instantiated we set that at Ext.Router's appInstance and then redirect any calls to
         * Ext.Router.draw to that app's Router. We keep a drawStack above so that we can call Ext.Router.draw one or
         * more times before the application is even instantiated and it will simply link it up once everything is
         * present.
         */
        Ext.Router.setAppInstance = function(app) {
            Ext.Router.appInstance = app;

            if (drawStack.length > 0) {
                Ext.each(drawStack, Ext.Router.draw);
            }
        };

        Ext.Router.draw = function(mapperFn) {
            Ext.Logger.deprecate(
                'Ext.Router.map is deprecated, please define your routes inline inside each Controller. ' +
                'Please see the 1.x -> 2.x migration guide for more details.'
            );

            var app = Ext.Router.appInstance,
                router;

            if (app) {
                router = app.getRouter();
                mapperFn(router);
            } else {
                drawStack.push(mapperFn);
            }
        };
        //</deprecated>
    });