def sequence(context, data):
    """Generate a sequence of numbers.

    It is the memorious equivalent of the xrange function, accepting the
    ``start``, ``stop`` and ``step`` parameters.

    This can run in two ways:
    * As a single function generating all numbers in the given range.
    * Recursively, generating numbers one by one with an optional ``delay``.

    The latter mode is useful in order to generate very large sequences
    without completely clogging up the user queue.

    If an optional ``tag`` is given, each number will be emitted only once
    across multiple runs of the crawler.
    """
    number = data.get('number', context.params.get('start', 1))
    stop = context.params.get('stop')
    step = context.params.get('step', 1)
    delay = context.params.get('delay')
    prefix = context.params.get('tag')
    while True:
        tag = None if prefix is None else '%s:%s' % (prefix, number)
        if tag is None or not context.check_tag(tag):
            data['number'] = number
            context.emit(data=data)
        if tag is not None:
            context.set_tag(tag, True)
        number = number + step
        if step > 0 and number >= stop:
            break
        if step < 0 and number <= stop:
            break
        if delay is not None:
            data['number'] = number
            context.recurse(data=data, delay=delay)
            break
