'Post-processes this form element against the POST data of the
request, and create/update/delete any related records.
@param form: the form
@param master_id: the ID of the master record in the form
@param format: the data format extension (for audit)'

def accept(self, form, master_id=None, format=None):

    fname = self._formname(separator='_')
    options = self.options
    multiple = options.get('multiple', True)
    defaults = options.get('default', {})
    if (fname in form.vars):
        try:
            data = json.loads(form.vars[fname])
        except ValueError:
            return
        component_name = data.get('component', None)
        if (not component_name):
            return
        data = data.get('data', None)
        if (not data):
            return
        resource = self.resource
        if (component_name in resource.components):
            component = resource.components[component_name]
        else:
            return
        link = component.link
        if (link and options.get('link', True)):
            actuate_link = False
            component = link
        else:
            actuate_link = True
        prefix = component.prefix
        name = component.name
        tablename = component.tablename
        db = current.db
        table = db[tablename]
        s3db = current.s3db
        auth = current.auth
        has_permission = auth.s3_has_permission
        audit = current.audit
        onaccept = s3db.onaccept
        for item in data:
            if ((not ('_changed' in item)) and (not ('_delete' in item))):
                continue
            values = Storage()
            valid = True
            for (f, d) in item.iteritems():
                if ((f[0] != '_') and d and isinstance(d, dict)):
                    field = table[f]
                    widget = field.widget
                    if (not hasattr(field, 'type')):
                        continue
                    elif (field.type == 'upload'):
                        rowindex = item.get('_index', None)
                        if (rowindex is not None):
                            filename = self._store_file(table, f, rowindex)
                            if filename:
                                values[f] = filename
                    elif isinstance(widget, S3Selector):
                        (value, error) = widget.postprocess(d['value'])
                        if (not error):
                            values[f] = value
                        else:
                            valid = False
                            break
                    else:
                        try:
                            (value, error) = s3_validate(table, f, d['value'])
                        except AttributeError:
                            continue
                        if (not error):
                            values[f] = value
                        else:
                            valid = False
                            break
            if (not valid):
                continue
            record_id = item.get('_id')
            delete = item.get('_delete')
            if (not record_id):
                if delete:
                    continue
                elif ((not component.multiple) or (not multiple)):
                    query = ((resource._id == master_id) & component.get_join())
                    f = self._filterby_query()
                    if (f is not None):
                        query &= f
                    DELETED = current.xml.DELETED
                    if (DELETED in table.fields):
                        query &= (table[DELETED] != True)
                    row = db(query).select(table._id, limitby=(0, 1)).first()
                    if row:
                        record_id = row[table._id]
            if record_id:
                if delete:
                    authorized = has_permission('delete', tablename, record_id)
                    if (not authorized):
                        continue
                    c = s3db.resource(tablename, id=record_id)
                    success = c.delete(cascade=True, format='html')
                else:
                    authorized = has_permission('update', tablename, record_id)
                    if (not authorized):
                        continue
                    query = (table._id == record_id)
                    success = db(query).update(**values)
                    values[table._id.name] = record_id
                    if success:
                        audit('update', prefix, name, record=record_id, representation=format)
                        s3db.update_super(table, values)
                        update_realm = s3db.get_config(table, 'update_realm')
                        if update_realm:
                            auth.set_realm_entity(table, values, force_update=True)
                        onaccept(table, Storage(vars=values), method='update')
            else:
                authorized = has_permission('create', tablename)
                if (not authorized):
                    continue
                pkey = component.pkey
                mastertable = resource.table
                if (pkey != mastertable._id.name):
                    query = (mastertable._id == master_id)
                    master = db(query).select(mastertable._id, mastertable[pkey], limitby=(0, 1)).first()
                    if (not master):
                        return
                else:
                    master = Storage({pkey: master_id})
                values = component.get_defaults(master, defaults=defaults, data=values)
                if ((not actuate_link) or (not link)):
                    values[component.fkey] = master[pkey]
                else:
                    fkey = component.fkey
                    if ((fkey != 'id') and (fkey in component.fields) and (fkey not in values)):
                        if ((fkey == 'pe_id') and (pkey == 'person_id')):
                            ptable = s3db.pr_person
                            query = (ptable.id == master[pkey])
                            person = db(query).select(ptable.pe_id, limitby=(0, 1)).first()
                            if person:
                                values['pe_id'] = person.pe_id
                            else:
                                s3_debug('S3Forms', ('Cannot    find    person    with    ID:    %s' % master[pkey]))
                        elif ((resource.tablename == 'pr_person') and (fkey == 'case_id') and (pkey == 'id')):
                            ltable = component.link.table
                            query = (ltable.person_id == master[pkey])
                            link_record = db(query).select(ltable.id, limitby=(0, 1)).first()
                            if link_record:
                                values[fkey] = link_record[pkey]
                            else:
                                s3_debug('S3Forms', ('Cannot    find    case    for    person    ID:    %s' % master[pkey]))
                        else:
                            values[fkey] = master[pkey]
                try:
                    record_id = component._table.insert(**values)
                except:
                    s3_debug('S3Forms', ('Cannot    insert    values    %s    into    table:    %s' % (values, component._table)))
                    raise
                if record_id:
                    table = db[tablename]
                    audit('create', prefix, name, record=record_id, representation=format)
                    values[table._id.name] = record_id
                    s3db.update_super(table, values)
                    if (link and actuate_link and options.get('update_link', True)):
                        link.update_link(master, values)
                    auth.s3_set_record_owner(table, record_id)
                    subform = Storage(vars=Storage(values))
                    onaccept(table, subform, method='create')
        return True
    else:
        return False
