    Import requirements::

        >>> import yafowil.loader
        >>> from yafowil.base import factory

    Render plain, source is string::

        >>> widget = factory('autocomplete', name='root',
        ...                  props={'source': 'http://www.foo.bar/baz'})
        >>> pxml(widget())
http://www.foo.bar/baz
delay,300|minLength,1|type,remote
    Render plain, source is list::

        >>> widget = factory('autocomplete', name='root',
        ...                  props={'source': ['foo', 'bar']})
        >>> pxml(widget())
foo|bar
delay,300|minLength,1|type,local
    Render plain, source is callable::

        >>> def test_source(widget, data):
        ...     return 'http://from.callable/'
        >>> widget = factory('autocomplete', name='root',
        ...                  props={'source': test_source})
        >>> pxml(widget())
http://from.callable/
delay,300|minLength,1|type,remote
    Extraction::

        >>> data = widget.extract({'root': 'abc'})
        >>> data.printtree()
    , extracted='abc' at ...>

    Extract required::

        >>> widget = factory('error:autocomplete', name='root',
        ...                  props={'source': test_source,
        ...                         'required': 'Autocomplete widget is required'})
        >>> data = widget.extract({'root': ''})
        >>> data.errors
        [ExtractionError('Autocomplete widget is required',)]

        >>> pxml(widget(data))
Autocomplete widget is required
http://from.callable/
delay,300|minLength,1|type,remote
    Render, invalid source type::

        >>> widget = factory('autocomplete', name='root',
        ...                  props={'source': None})
        >>> widget()
        Traceback (most recent call last):
        ...
        ValueError: resulting source must be tuple/list or string