'Parse the predicate. Return a callable that can be used to filter
nodes. Update `self.soup_args` to take advantage of BeautifulSoup search
features.'

def __parse_predicate(self, predicate):

    try:
        position = int(predicate)
        if (self.axis == AXIS_DESCENDANT):
            return PredicateFilter('position', value=position)
        else:
            self.soup_args['limit'] = position
            self.index = (position - 1)
            return None
    except ValueError:
        pass
    if (predicate == 'last()'):
        self.index = (-1)
        return None
    negate = self._re_predicate_not.match(predicate)
    if negate:
        predicate = negate.group(1)
    function_match = self._re_predicate_function.match(predicate)
    if function_match:
        name = function_match.group(1)
        arguments = function_match.group(2)
        value = function_match.group(4)
        if (value is not None):
            value = function_match.group(5)
        return PredicateFilter(name, arguments, value)
    axis_match = self._re_predicate_axis.match(predicate)
    if axis_match:
        axis = axis_match.group(1)
        if (axis is None):
            axis = AXIS_CHILD
        elif (axis == '@'):
            axis = AXIS_ATTRIBUTE
        if (axis == AXIS_ATTRIBUTE):
            attribute_name = axis_match.group(3)
            if (axis_match.group(5) is not None):
                attribute_value = axis_match.group(6)
            elif (not negate):
                attribute_value = True
            else:
                attribute_value = None
            if (not self.soup_args.has_key('attrs')):
                self.soup_args['attrs'] = {}
            self.soup_args['attrs'][attribute_name] = attribute_value
            return None
        elif (axis == AXIS_CHILD):
            node_test = axis_match.group(3)
            node_value = axis_match.group(6)
            return PredicateFilter('axis', node_test, value=node_value, negate=negate)
    raise NotImplementedError('This    predicate    is    not    implemented')
