'Perform a CSS selection operation on the current element.'

def select(self, selector, _candidate_generator=None, limit=None):

    tokens = re.sub(',[\\s]*', ',', selector).split()
    current_context = [self]
    if (tokens[(-1)] in self._selector_combinators):
        raise ValueError(('Final    combinator    "%s"    is    missing    an    argument.' % tokens[(-1)]))
    if self._select_debug:
        print ('Running    CSS    selector    "%s"' % selector)
    for (index, token_group) in enumerate(tokens):
        new_context = []
        new_context_ids = set([])
        grouped_tokens = token_group.split(',')
        if ('' in grouped_tokens):
            raise ValueError(('Invalid    group    selection    syntax:    %s' % token_group))
        if (tokens[(index - 1)] in self._selector_combinators):
            if self._select_debug:
                print '        Token    was    consumed    by    the    previous    combinator.'
            continue
        for token in grouped_tokens:
            if self._select_debug:
                print ('    Considering    token    "%s"' % token)
            recursive_candidate_generator = None
            tag_name = None
            checker = None
            m = self.attribselect_re.match(token)
            if (m is not None):
                (tag_name, attribute, operator, value) = m.groups()
                checker = self._attribute_checker(operator, attribute, value)
            elif ('#' in token):
                (tag_name, tag_id) = token.split('#', 1)
                def id_matches(tag):
                    return (tag.get('id', None) == tag_id)
                checker = id_matches
            elif ('.' in token):
                (tag_name, klass) = token.split('.', 1)
                classes = set(klass.split('.'))
                def classes_match(candidate):
                    return classes.issubset(candidate.get('class', []))
                checker = classes_match
            elif (':' in token):
                (tag_name, pseudo) = token.split(':', 1)
                if (tag_name == ''):
                    raise ValueError('A    pseudo-class    must    be    prefixed    with    a    tag    name.')
                pseudo_attributes = re.match('([a-zA-Z\\d-]+)\\(([a-zA-Z\\d]+)\\)', pseudo)
                found = []
                if (pseudo_attributes is None):
                    pseudo_type = pseudo
                    pseudo_value = None
                else:
                    (pseudo_type, pseudo_value) = pseudo_attributes.groups()
                if (pseudo_type == 'nth-of-type'):
                    try:
                        pseudo_value = int(pseudo_value)
                    except:
                        raise NotImplementedError('Only    numeric    values    are    currently    supported    for    the    nth-of-type    pseudo-class.')
                    if (pseudo_value < 1):
                        raise ValueError('nth-of-type    pseudo-class    value    must    be    at    least    1.')
                    class Counter(object, ):
                        def __init__(self, destination):
                            self.count = 0
                            self.destination = destination
                        def nth_child_of_type(self, tag):
                            self.count += 1
                            if (self.count == self.destination):
                                return True
                            if (self.count > self.destination):
                                raise StopIteration()
                            return False
                    checker = Counter(pseudo_value).nth_child_of_type
                else:
                    raise NotImplementedError('Only    the    following    pseudo-classes    are    implemented:    nth-of-type.')
            elif (token == '*'):
                pass
            elif (token == '>'):
                recursive_candidate_generator = (lambda tag: tag.children)
            elif (token == '~'):
                recursive_candidate_generator = (lambda tag: tag.next_siblings)
            elif (token == '+'):
                def next_tag_sibling(tag):
                    (yield tag.find_next_sibling(True))
                recursive_candidate_generator = next_tag_sibling
            elif self.tag_name_re.match(token):
                tag_name = token
            else:
                raise ValueError(('Unsupported    or    invalid    CSS    selector:    "%s"' % token))
            if recursive_candidate_generator:
                next_token = tokens[(index + 1)]
                def recursive_select(tag):
                    if self._select_debug:
                        print ('                Calling    select("%s")    recursively    on    %s    %s' % (next_token, tag.name, tag.attrs))
                        print ('-' * 40)
                    for i in tag.select(next_token, recursive_candidate_generator):
                        if self._select_debug:
                            print ('(Recursive    select    picked    up    candidate    %s    %s)' % (i.name, i.attrs))
                        (yield i)
                    if self._select_debug:
                        print ('-' * 40)
                _use_candidate_generator = recursive_select
            elif (_candidate_generator is None):
                if self._select_debug:
                    if tag_name:
                        check = '[any]'
                    else:
                        check = tag_name
                    print ('            Default    candidate    generator,    tag    name="%s"' % check)
                if self._select_debug:
                    def default_candidate_generator(tag):
                        for child in tag.descendants:
                            if (not isinstance(child, Tag)):
                                continue
                            if (tag_name and (not (child.name == tag_name))):
                                continue
                            (yield child)
                    _use_candidate_generator = default_candidate_generator
                else:
                    _use_candidate_generator = (lambda tag: tag.descendants)
            else:
                _use_candidate_generator = _candidate_generator
            count = 0
            for tag in current_context:
                if self._select_debug:
                    print ('                Running    candidate    generator    on    %s    %s' % (tag.name, repr(tag.attrs)))
                for candidate in _use_candidate_generator(tag):
                    if (not isinstance(candidate, Tag)):
                        continue
                    if (tag_name and (candidate.name != tag_name)):
                        continue
                    if (checker is not None):
                        try:
                            result = checker(candidate)
                        except StopIteration:
                            break
                    if ((checker is None) or result):
                        if self._select_debug:
                            print ('                    SUCCESS    %s    %s' % (candidate.name, repr(candidate.attrs)))
                        if (id(candidate) not in new_context_ids):
                            new_context.append(candidate)
                            new_context_ids.add(id(candidate))
                            if (limit and (len(new_context) >= limit)):
                                break
                    elif self._select_debug:
                        print ('                    FAILURE    %s    %s' % (candidate.name, repr(candidate.attrs)))
        current_context = new_context
    if self._select_debug:
        print 'Final    verdict:'
        for i in current_context:
            print ('    %s    %s' % (i.name, i.attrs))
    return current_context
