'Widget renderer, currently supports multiselect (default),
hierarchy and groupedopts widgets.
@param field: the input field
@param value: the value to populate the widget
@param attributes: attributes for the widget
@return: the widget'

def __call__(self, field, value, **attributes):

    options = self.options
    (component, link) = self.get_link()
    has_permission = current.auth.s3_has_permission
    ltablename = link.tablename
    if ((options.readonly is True) or (not has_permission('create', ltablename)) or (not has_permission('delete', ltablename))):
        return self.represent(value)
    multiple = options.get('multiple', True)
    options['multiple'] = multiple
    kfield = link.table[component.rkey]
    dummy_field = Storage(name=field.name, type=kfield.type, represent=kfield.represent)
    widget = options.get('widget')
    if (widget != 'hierarchy'):
        requires = options.get('requires')
        if (requires is None):
            zero = (None if multiple else options.get('zero', XML('&nbsp')))
            opts = self.get_options()
            if (zero is None):
                opts = dict(((k, v) for (k, v) in opts.items() if (k != '')))
            requires = IS_IN_SET(opts, multiple=multiple, zero=zero, sort=options.get('sort', True))
            if (zero is not None):
                requires = IS_EMPTY_OR(requires)
        dummy_field.requires = requires
    widget_opts = (lambda keys: dict(((k, v) for (k, v) in options.items() if (k in keys))))
    if ((widget == 'groupedopts') or ((not widget) and ('cols' in options))):
        from s3widgets import S3GroupedOptionsWidget
        w_opts = widget_opts(('cols', 'help_field', 'multiple', 'orientation', 'size', 'sort', 'table'))
        w = S3GroupedOptionsWidget(**w_opts)
    elif (widget == 'hierarchy'):
        from s3widgets import S3HierarchyWidget
        w_opts = widget_opts(('represent', 'multiple', 'leafonly', 'columns', 'filter'))
        w_opts['lookup'] = component.tablename
        w = S3HierarchyWidget(**w_opts)
    else:
        from s3widgets import S3MultiSelectWidget
        w_opts = widget_opts(('filter', 'header', 'selectedList', 'noneSelectedText', 'multiple', 'columns'))
        w = S3MultiSelectWidget(**w_opts)
    attr = dict(attributes)
    attr['_id'] = field.name
    if (not link.table[options.field].writable):
        _class = attr.get('_class', None)
        if _class:
            attr['_class'] = ('%s    hide' % _class)
        else:
            attr['_class'] = 'hide'
    widget = w(dummy_field, value, **attr)
    if hasattr(widget, 'add_class'):
        widget.add_class('inline-link')
    script = options.get('script')
    if script:
        current.response.s3.jquery_ready.append(script)
    return widget
