Show:
                            /**
                             * The Search Component
                             *
                             * @module aui-search
                             * @submodule aui-search-ternary-search-tree
                             */
                            
                            var Lang = A.Lang;
                            
                            /**
                             * A base class for TernarySearchTree.
                             *
                             * @class A.TernarySearchTree
                             * @extends Base
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var TernarySearchTree = A.Component.create({
                            
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'TernarySearchTree',
                            
                                /**
                                 * Static property provides a string to identify the namespace.
                                 *
                                 * @property NS
                                 * @type String
                                 * @static
                                 */
                                NS: 'ternarysearchtree',
                            
                                /**
                                 * Static property used to define which component it extends.
                                 *
                                 * @property EXTENDS
                                 * @type Object
                                 * @static
                                 */
                                EXTENDS: A.Base,
                            
                                prototype: {
                            
                                    /**
                                     * Adds a word in the tree.
                                     *
                                     * @method add
                                     * @param word
                                     */
                                    add: function(word) {
                                        var instance = this;
                            
                                        var root = instance._root;
                            
                                        var node = instance._insert(root, word, 0);
                            
                                        if (!Lang.isValue(root)) {
                                            instance._root = node;
                                        }
                                    },
                            
                                    /**
                                     * Checks if the argument is part of the tree.
                                     *
                                     * @method contains
                                     * @param word
                                     * @return {Boolean}
                                     */
                                    contains: function(word) {
                                        var instance = this;
                            
                                        var node = instance._search(instance._root, word, 0);
                            
                                        return !!(Lang.isValue(node) && node.isEndOfWord());
                                    },
                            
                                    /**
                                     * Set tree's root to `null`.
                                     *
                                     * @method empty
                                     */
                                    empty: function() {
                                        var instance = this;
                            
                                        instance._root = null;
                                    },
                            
                                    /**
                                     * Checks if a pattern match.
                                     *
                                     * @method patternMatch
                                     * @param pattern
                                     * @return {Array}
                                     */
                                    patternMatch: function(pattern) {
                                        var instance = this;
                            
                                        var results = [];
                            
                                        instance._patternMatch(instance._root, pattern, 0, results);
                            
                                        return results;
                                    },
                            
                                    /**
                                     * Searches for a prefix in the tree.
                                     *
                                     * @method prefixSearch
                                     * @param prefix
                                     * @return {Array}
                                     */
                                    prefixSearch: function(prefix) {
                                        var instance = this;
                            
                                        var results = [];
                            
                                        var node = instance._search(instance._root, prefix, 0);
                            
                                        if (node) {
                                            instance._inOrderTraversal(node.get('child'), results);
                                        }
                            
                                        return results;
                                    },
                            
                                    /**
                                     * Traversals a tree.
                                     *
                                     * @method _inOrderTraversal
                                     * @param node
                                     * @param results
                                     * @protected
                                     */
                                    _inOrderTraversal: function(node, results) {
                                        var instance = this;
                            
                                        if (!Lang.isValue(node)) {
                                            return;
                                        }
                            
                                        instance._inOrderTraversal(node.get('smallerNode'), results);
                            
                                        if (node.isEndOfWord()) {
                                            results.push(node.get('word'));
                                        }
                            
                                        instance._inOrderTraversal(node.get('child'), results);
                            
                                        instance._inOrderTraversal(node.get('largerNode'), results);
                                    },
                            
                                    /**
                                     * Insert a node in the tree.
                                     *
                                     * @method _insert
                                     * @param node
                                     * @param word
                                     * @param index
                                     * @protected
                                     */
                                    _insert: function(node, word, index) {
                                        var instance = this;
                            
                                        var character = word.charAt(index);
                            
                                        if (Lang.isValue(node)) {
                                            if (character === node.get('character')) {
                                                if (index + 1 < word.length) {
                                                    node.set('child', instance._insert(node.get('child'), word, index + 1));
                                                }
                                                else {
                                                    node.set('word', word);
                                                }
                                            }
                                            else if (character < node.get('character')) {
                                                node.set('smallerNode', instance._insert(node.get('smallerNode'), word, index));
                                            }
                                            else {
                                                node.set('largerNode', instance._insert(node.get('largerNode'), word, index));
                                            }
                                        }
                                        else {
                                            node = instance._insert(
                                                new A.TernarySearchNode({
                                                    character: character
                                                }),
                                                word,
                                                index
                                            );
                                        }
                            
                                        return node;
                                    },
                            
                                    /**
                                     * Recursive search for a pattern in the tree.
                                     *
                                     * @method _patternMatch
                                     * @param node
                                     * @param pattern
                                     * @param index
                                     * @param results
                                     * @protected
                                     */
                                    _patternMatch: function(node, pattern, index, results) {
                                        var instance = this;
                            
                                        if (Lang.isValue(node)) {
                                            var character = pattern.charAt(index);
                            
                                            var nodeCharacter = node.get('character');
                            
                                            var patternChar = TernarySearchTree.PATTERN_CHAR;
                            
                                            if (character === patternChar || character < nodeCharacter) {
                                                instance._patternMatch(node.get('smallerNode'), pattern, index, results);
                                            }
                            
                                            if (character === patternChar || character === nodeCharacter) {
                                                if (index + 1 < pattern.length) {
                                                    instance._patternMatch(node.get('child'), pattern, index + 1, results);
                                                }
                                                else if (node.isEndOfWord()) {
                                                    results.push(node.get('word'));
                                                }
                                            }
                            
                                            if (character === patternChar || character > nodeCharacter) {
                                                instance._patternMatch(node.get('largerNode'), pattern, index, results);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Recursive search for a node in the tree.
                                     *
                                     * @method _search
                                     * @param node
                                     * @param word
                                     * @param index
                                     * @protected
                                     */
                                    _search: function(node, word, index) {
                                        var instance = this;
                            
                                        var result = node;
                            
                                        if (Lang.isValue(node)) {
                                            var character = word.charAt(index);
                            
                                            var nodeCharacter = node.get('character');
                            
                                            if (character === nodeCharacter) {
                                                if (index + 1 < word.length) {
                                                    result = instance._search(node.get('child'), word, index + 1);
                                                }
                                            }
                                            else if (character < nodeCharacter) {
                                                result = instance._search(node.get('smallerNode'), word, index);
                                            }
                                            else {
                                                result = instance._search(node.get('largerNode'), word, index);
                                            }
                                        }
                            
                                        return result;
                                    }
                                }
                            });
                            
                            TernarySearchTree.PATTERN_CHAR = '?';
                            
                            A.TernarySearchTree = TernarySearchTree;