YAHOO.util.Dom.toggleClass = function (el, className) {
    if (YAHOO.util.Dom.hasClass (el, className)) {
        YAHOO.util.Dom.removeClass (el, className);
    } else {
        YAHOO.util.Dom.addClass (el, className);
    };
};
YAHOO.util.Dom.getAncestorsByClass = function (obj, className, tag, iterations, findFirst) {
    className    = className        || false;
    tag            = tag            || false;
    obj            = YAHOO.util.Dom.get (obj);
    if (!obj) {
        return false;
    };

    var ancestors    = new Array;
    var parent        = obj.parentNode;
    var iteration    = iterations || 20;
    while (parent && iteration--){
        if (YAHOO.util.Dom.hasClass (parent, className) || !className){
            if (!tag || (tag && parent.nodeName.toLowerCase () == tag)){
                ancestors.push (parent);
                if (findFirst) {
                    return parent;
                };
            };
        };
        parent    = parent.parentNode;
    };
    return ancestors.length ? ancestors : false;
};
YAHOO.util.Dom.getElementsBySelector = function (selector) {
    if (!document.getElementsByTagName){
        return new Array;
    };
    var getAllChildren = function (e)    {
        return e.all ? e.all : e.getElementsByTagName ('*');
    };
    var tokens            = selector.split (' ');
    var currentContext    = new Array (document);
    for (var i = 0; i < tokens.length; i++) {
        token    = tokens [ i ].replace (/^\s+/,'').replace (/\s+$/, '');
        if (token.indexOf ('#') > -1) {
            var bits    = token.split ('#');
            var tagName    = bits [ 0 ];
            var id        = bits [ 1 ];
            var element    = YAHOO.util.Dom.get(id);
            if ( !element ) {
                return new Array;
            }
            if (tagName && element.nodeName.toLowerCase() != tagName) {
                return new Array;
            };
            currentContext    = new Array (element);
            continue;
        };
        if (token.indexOf ('.') > -1) {
            var bits        = token.split('.');
            var tagName        = bits[0];
            var className    = bits[1];
            if (!tagName) {
                tagName        = '*';
            };
            var found        = new Array;
            var foundCount    = 0;
            for (var h = 0; h < currentContext.length; h++) {
                var elements    = tagName == '*' ? getAllChildren (currentContext [ h ]) : currentContext [ h ].getElementsByTagName (tagName);
                for (var j = 0; j < elements.length; j++) {
                    found [ foundCount++ ]    = elements [ j ];
                };
            };
            currentContext            = new Array;
            var currentContextIndex    = 0;
            for (var k = 0; k < found.length; k++) {
                if (found [ k ].className && found [ k ].className.match (new RegExp ('\\b' + className + '\\b'))) {
                    currentContext [ currentContextIndex++ ] = found [ k ];
                };
            };
            continue;
        };
        if (token.match (/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
            var tagName            = RegExp.$1;
            var attrName        = RegExp.$2;
            var attrOperator    = RegExp.$3;
            var attrValue        = RegExp.$4;
            if (!tagName) {
                tagName    = '*';
            };
            var found        = new Array;
            var foundCount    = 0;
            var elements;
            for (var h = 0; h < currentContext.length; h++) {
                if (tagName == '*') {
                    elements    = getAllChildren (currentContext [ h ]);
                } else {
                    elements    = currentContext [ h ].getElementsByTagName (tagName);
                };
                for (var j = 0; j < elements.length; j++) {
                    found [ foundCount++ ]    = elements [ j ];
                };
            };
            currentContext            = new Array;
            var currentContextIndex    = 0;
            var checkFunction;
            switch (attrOperator) {
                case '=':
                    checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
                    break;
                case '~':
                    checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
                    break;
                case '|':
                    checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
                    break;
                case '^':
                    checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
                    break;
                case '$':
                    checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
                    break;
                case '*':
                    checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
                    break;
                default :
                    checkFunction = function(e) { return e.getAttribute(attrName); };
            };
            currentContext        = new Array;
            var currentContextIndex    = 0;
            for (var k = 0; k < found.length; k++) {
                if (checkFunction (found [ k ])) {
                    currentontext [ currentContextIndex++ ]    = found [ k ];
                };
            };
            continue;
        };
        if (!currentContext [ 0 ]) {
            return;
        };
        tagName            = token;
        var found        = new Array;
        var foundCount    = 0;
        for (var h = 0; h < currentContext.length; h++) {
            var elements    = currentContext [ h ].getElementsByTagName (tagName);
            for (var j = 0; j < elements.length; j++)    {
                found [ foundCount++ ]    = elements [ j ];
            };
        };
        currentContext    = found;
    };
    return currentContext;
};