class Hpricot::Elements

def self.filter(nodes, expr, truth = true)

def self.filter(nodes, expr, truth = true)
    until expr.empty?
        _, *m = *expr.match(/^(?:#{ATTR_RE}|#{BRACK_RE}|#{FUNC_RE}|#{CUST_RE}|#{CATCH_RE})/)
        break unless _
        expr = $'
        m.compact!
        if m[0] == '@'
            m[0] = "@#{m.slice!(2,1)}"
        end
        if m[0] == '[' && m[1] =~ /^\d+$/
            m = [":", "nth", m[1].to_i-1]
        end
        if m[0] == ":" && m[1] == "not"
            nodes, = Elements.filter(nodes, m[2], false)
        elsif "#{m[0]}#{m[1]}" =~ /^(:even|:odd)$/
            new_nodes = []
            nodes.each_with_index {|n,i| new_nodes.push(n) if (i % 2 == (m[1] == "even" ? 0 : 1)) }
            nodes = new_nodes
        elsif "#{m[0]}#{m[1]}" =~ /^(:first|:last)$/
            nodes = [nodes.send(m[1])]
        else
            meth = "filter[#{m[0]}#{m[1]}]" unless m[0].empty?
            if meth and Traverse.method_defined? meth
                args = m[2..-1]
            else
                meth = "filter[#{m[0]}]"
                if Traverse.method_defined? meth
                    args = m[1..-1]
                end
            end
            i = -1
            nodes = Elements[*nodes.find_all do |x| 
                                  i += 1
                                  x.send(meth, *([*args] + [i])) ? truth : !truth
                              end]
        end
    end
    [nodes, expr]
end