var testElement = function(node, method) {
    return node && node.nodeType == 1 && ( !method || method(node) );
};

function getChildren(node) {
    node = YAHOO.util.Dom.get(node);
    if (!node) {
    }

    return getChildrenBy(node);
}

function getChildrenBy(node, method) {
    var child = getFirstChildBy(node, method);
    var children = child ? [child] : [];

    getNextSiblingBy(child, function(node) {
        if ( !method || method(node) ) {
            children[children.length] = node;
        }
        return false; // fail test to collect all children
    });

    return children;
}

function getFirstChildBy(node, method) {
    var child = ( testElement(node.firstChild, method) ) ? node.firstChild : null;
    return child || getNextSiblingBy(node.firstChild, method);
}

function getNextSiblingBy(node, method) {
    while (node) {
        node = node.nextSibling;
        if ( testElement(node, method) ) {
            return node;
        }
    }
    return null;
}

function getNextSibling(node) {
    node = YAHOO.util.Dom.get(node);
    if (!node) {
        return null;
    }

    return getNextSiblingBy(node);
}

function getAncestorBy(node, method) {
    while (node = node.parentNode) { // NOTE: assignment
        if ( testElement(node, method) ) {
            return node;
        }
    }

    return null;
}

function getAncestorByTagName(node, tagName) {
    node = YAHOO.util.Dom.get(node);
    if (!node) {
        return null;
    }
    var method = function(el) {
         return el.tagName && el.tagName.toUpperCase() == tagName.toUpperCase();
    };

    return getAncestorBy(node, method);
}