lib/Ext/mixin/Sortable.js
function(index, sorters, defaultDirection) {
        // We begin by making sure we are dealing with an array of sorters
        if (!Ext.isArray(sorters)) {
            sorters = [sorters];
        }

        var ln = sorters.length,
            direction = defaultDirection || this.getDefaultSortDirection(),
            sortRoot = this.getSortRoot(),
            currentSorters = this.getSorters(),
            newSorters = [],
            sorterConfig, i, sorter, currentSorter;

        if (!currentSorters) {
            // This will guarantee that we get the collection
            currentSorters = this.createSortersCollection();
        }

        // We first have to convert every sorter into a proper Sorter instance
        for (i = 0; i < ln; i++) {
            sorter = sorters[i];
            sorterConfig = {
                direction: direction,
                root: sortRoot
            };

            // If we are dealing with a string we assume it is a property they want to sort on.
            if (typeof sorter === 'string') {
                currentSorter = currentSorters.get(sorter);

                if (!currentSorter) {
                    sorterConfig.property = sorter;
                } else {
                    if (defaultDirection) {
                        currentSorter.setDirection(defaultDirection);
                    } else {
                        // If we already have a sorter for this property we just toggle its direction.
                        currentSorter.toggle();
                    }
                    continue;
                }
            }
            // If it is a function, we assume its a sorting function.
            else if (Ext.isFunction(sorter)) {
                sorterConfig.sorterFn = sorter;
            }
            // If we are dealing with an object, we assume its a Sorter configuration. In this case
            // we create an instance of Sorter passing this configuration.
            else if (Ext.isObject(sorter)) {
                if (!sorter.isSorter) {
                    if (sorter.fn) {
                        sorter.sorterFn = sorter.fn;
                        delete sorter.fn;
                    }

                    sorterConfig = Ext.apply(sorterConfig, sorter);
                }
                else {
                    newSorters.push(sorter);
                    if (!sorter.getRoot()) {
                        sorter.setRoot(sortRoot);
                    }
                    continue;
                }
            }
            // Finally we get to the point where it has to be invalid
            // <debug>
            else {
                Ext.Logger.warn('Invalid sorter specified:', sorter);
            }
            // </debug>

            // If a sorter config was created, make it an instance
            sorter = Ext.create('Ext.util.Sorter', sorterConfig);
            newSorters.push(sorter);
        }

        // Now lets add the newly created sorters.
        for (i = 0, ln = newSorters.length; i < ln; i++) {
            currentSorters.insert(index + i, newSorters[i]);
        }

        this.dirtySortFn = true;

        if (currentSorters.length) {
            this.sorted = true;
        }
        return currentSorters;
    }
function(index, sorters, defaultDirection) {
        // We begin by making sure we are dealing with an array of sorters
        if (!Ext.isArray(sorters)) {
            sorters = [sorters];
        }

        var ln = sorters.length,
            direction = defaultDirection || this.getDefaultSortDirection(),
            sortRoot = this.getSortRoot(),
            currentSorters = this.getSorters(),
            newSorters = [],
            sorterConfig, i, sorter, currentSorter;

        if (!currentSorters) {
            // This will guarantee that we get the collection
            currentSorters = this.createSortersCollection();
        }

        // We first have to convert every sorter into a proper Sorter instance
        for (i = 0; i < ln; i++) {
            sorter = sorters[i];
            sorterConfig = {
                direction: direction,
                root: sortRoot
            };

            // If we are dealing with a string we assume it is a property they want to sort on.
            if (typeof sorter === 'string') {
                currentSorter = currentSorters.get(sorter);

                if (!currentSorter) {
                    sorterConfig.property = sorter;
                } else {
                    if (defaultDirection) {
                        currentSorter.setDirection(defaultDirection);
                    } else {
                        // If we already have a sorter for this property we just toggle its direction.
                        currentSorter.toggle();
                    }
                    continue;
                }
            }
            // If it is a function, we assume its a sorting function.
            else if (Ext.isFunction(sorter)) {
                sorterConfig.sorterFn = sorter;
            }
            // If we are dealing with an object, we assume its a Sorter configuration. In this case
            // we create an instance of Sorter passing this configuration.
            else if (Ext.isObject(sorter)) {
                if (!sorter.isSorter) {
                    if (sorter.fn) {
                        sorter.sorterFn = sorter.fn;
                        delete sorter.fn;
                    }

                    sorterConfig = Ext.apply(sorterConfig, sorter);
                }
                else {
                    newSorters.push(sorter);
                    if (!sorter.getRoot()) {
                        sorter.setRoot(sortRoot);
                    }
                    continue;
                }
            }
            // Finally we get to the point where it has to be invalid
            // <debug>
            else {
                Ext.Logger.warn('Invalid sorter specified:', sorter);
            }
            // </debug>

            // If a sorter config was created, make it an instance
            sorter = Ext.create('Ext.util.Sorter', sorterConfig);
            newSorters.push(sorter);
        }

        // Now lets add the newly created sorters.
        for (i = 0, ln = newSorters.length; i < ln; i++) {
            currentSorters.insert(index + i, newSorters[i]);
        }

        this.dirtySortFn = true;

        if (currentSorters.length) {
            this.sorted = true;
        }
        return currentSorters;
    }
This method inserts all the sorters in the passed array at the given index.
@param {Number} index The index at which to insert the sorters.
@param {Array} sorters Can be an instance of Ext.util.Sorter, a string indicating a property name,
an object representing an Ext.util.Sorter configuration, or a sort function.
@param {String} defaultDirection The default direction for each sorter in the array. Defaults
to the value of {@link #defaultSortDirection}. Can be either 'ASC' or 'DESC'.