'Commit this item to the database
@param ignore_errors: skip invalid components
(still reports errors)'

def commit(self, ignore_errors=False):

    if self.committed:
        return True
    if ((self.parent is not None) and self.parent.skip):
        return True
    db = current.db
    s3db = current.s3db
    xml = current.xml
    ATTRIBUTE = xml.ATTRIBUTE
    METHOD = self.METHOD
    CREATE = METHOD.CREATE
    UPDATE = METHOD.UPDATE
    DELETE = METHOD.DELETE
    MERGE = METHOD.MERGE
    POLICY = self.POLICY
    THIS = POLICY['THIS']
    NEWER = POLICY['NEWER']
    MASTER = POLICY['MASTER']
    UID = xml.UID
    MCI = xml.MCI
    MTIME = xml.MTIME
    VALIDATION_ERROR = current.ERROR.VALIDATION_ERROR
    self.mtime = s3_utc(self.mtime)
    self._resolve_references()
    if (not self.validate()):
        self.skip = True
        parent = self.parent
        if (parent is not None):
            parent.error = VALIDATION_ERROR
            element = parent.element
            if (not element.get(ATTRIBUTE.error, False)):
                element.set(ATTRIBUTE.error, s3_unicode(parent.error))
        return ignore_errors
    elif ((self.method not in (MERGE, DELETE)) and self.components):
        for component in self.components:
            if ((component.accepted is False) or (component.data is None)):
                if hasattr(component, 'tablename'):
                    tn = component.tablename
                else:
                    tn = None
                component.skip = True
                self.skip = True
                self.error = VALIDATION_ERROR
                return ignore_errors
    elif ((self.method in (MERGE, DELETE)) and (not self.accepted)):
        self.skip = True
        return True
    if (not self.authorize()):
        self.error = current.ERROR.NOT_PERMITTED
        self.skip = True
        return ignore_errors
    method = self.method
    strategy = self.strategy
    if (not isinstance(strategy, (list, tuple))):
        strategy = [strategy]
    if (method not in strategy):
        self.error = current.ERROR.NOT_PERMITTED
        self.skip = True
        return True
    table = self.table
    original = self.original
    original_mtime = None
    original_mci = 0
    if original:
        if hasattr(table, MTIME):
            original_mtime = s3_utc(original[MTIME])
        if hasattr(table, MCI):
            original_mci = original[MCI]
        original_deleted = (('deleted' in original) and original.deleted)
    else:
        original_deleted = False
    job = self.job
    original_modified = True
    self.modified = True
    self.conflict = False
    last_sync = s3_utc(job.last_sync)
    if last_sync:
        if (original_mtime and (original_mtime < last_sync)):
            original_modified = False
        if (self.mtime and (self.mtime < last_sync)):
            self.modified = False
        if (self.modified and original_modified):
            self.conflict = True
    if (self.conflict and (method in (UPDATE, DELETE, MERGE))):
        if job.onconflict:
            job.onconflict(self)
    if (self.data is not None):
        data = table._filter_fields(self.data, id=True)
    else:
        data = Storage()
    if isinstance(self.update_policy, dict):
        def update_policy(f):
            setting = self.update_policy
            p = setting.get(f, setting.get('__default__', THIS))
            if (p not in POLICY):
                return THIS
            return p
    else:
        def update_policy(f):
            p = self.update_policy
            if (p not in POLICY):
                return THIS
            return p
    if callable(job.log):
        job.log(self)
    tablename = self.tablename
    enforce_realm_update = False
    if (method == UPDATE):
        if original:
            if original_deleted:
                policy = update_policy(None)
                if (((policy == NEWER) and original_mtime and (original_mtime > self.mtime)) or ((policy == MASTER) and ((original_mci == 0) or (self.mci != 1)))):
                    self.skip = True
                    return True
            fields = data.keys()
            for f in fields:
                if (f in original):
                    if (type(original[f]) is datetime):
                        if (s3_utc(data[f]) == s3_utc(original[f])):
                            del data[f]
                            continue
                    elif (data[f] == original[f]):
                        del data[f]
                        continue
                remove = False
                policy = update_policy(f)
                if (policy == THIS):
                    remove = True
                elif (policy == NEWER):
                    if (original_mtime and (original_mtime > self.mtime)):
                        remove = True
                elif (policy == MASTER):
                    if ((original_mci == 0) or (self.mci != 1)):
                        remove = True
                if remove:
                    del data[f]
            if original_deleted:
                data['deleted'] = False
                if hasattr(table, 'deleted_fk'):
                    data['deleted_fk'] = ''
                if hasattr(table, 'created_by'):
                    data['created_by'] = table.created_by.default
                if hasattr(table, 'modified_by'):
                    data['modified_by'] = table.modified_by.default
                for fieldname in table.fields:
                    field = table[fieldname]
                    default = field.default
                    if ((str(field.type)[:9] == 'reference') and (fieldname not in data) and (default is not None)):
                        data[fieldname] = default
                enforce_realm_update = True
        if ((not self.skip) and (not self.conflict) and (len(data) or self.components or self.references)):
            if (self.uid and hasattr(table, UID)):
                data[UID] = self.uid
            if (MTIME in table):
                data[MTIME] = self.mtime
            if (MCI in data):
                del data[MCI]
            query = (table._id == self.id)
            try:
                db(query).update(**dict(data))
            except:
                self.error = sys.exc_info()[1]
                self.skip = True
                return ignore_errors
            else:
                self.committed = True
        else:
            self.committed = True
    elif (method == CREATE):
        if (UID in data):
            del data[UID]
        if (MCI in data):
            del data[MCI]
        for f in data:
            if ((update_policy(f) == MASTER) and (self.mci != 1)):
                del data[f]
        if (len(data) or self.components or self.references):
            if (self.uid and (UID in table.fields)):
                data[UID] = self.uid
            if (MCI in table.fields):
                data[MCI] = self.mci
            try:
                success = table.insert(**dict(data))
            except:
                self.error = sys.exc_info()[1]
                self.skip = True
                return ignore_errors
            if success:
                self.id = success
                self.committed = True
        else:
            self.skip = True
            return True
    elif (method == DELETE):
        if original:
            if original_deleted:
                self.skip = True
            policy = update_policy(None)
            if (policy == THIS):
                self.skip = True
            elif ((policy == NEWER) and (original_mtime and (original_mtime > self.mtime))):
                self.skip = True
            elif ((policy == MASTER) and ((original_mci == 0) or (self.mci != 1))):
                self.skip = True
        else:
            self.skip = True
        if ((not self.skip) and (not self.conflict)):
            resource = s3db.resource(tablename, id=self.id)
            success = resource.delete(cascade=True)
            if resource.error:
                self.error = resource.error
                self.skip = True
                return ignore_errors
        return True
    elif (method == MERGE):
        if (UID not in table.fields):
            self.skip = True
        elif original:
            if original_deleted:
                self.skip = True
            policy = update_policy(None)
            if (policy == THIS):
                self.skip = True
            elif ((policy == NEWER) and (original_mtime and (original_mtime > self.mtime))):
                self.skip = True
            elif ((policy == MASTER) and ((original_mci == 0) or (self.mci != 1))):
                self.skip = True
        else:
            self.skip = True
        if ((not self.skip) and (not self.conflict)):
            row = db((table[UID] == data[xml.REPLACEDBY])).select(table._id, limitby=(0, 1)).first()
            if row:
                original_id = row[table._id]
                resource = s3db.resource(tablename, id=[original_id, self.id])
                try:
                    success = resource.merge(original_id, self.id)
                except:
                    self.error = sys.exc_info()[1]
                    self.skip = True
                    return ignore_errors
                if success:
                    self.committed = True
            else:
                self.skip = True
        return True
    else:
        raise RuntimeError(('unknown    import    method:    %s' % method))
    if self.committed:
        form = Storage()
        form.method = method
        form.vars = self.data
        (prefix, name) = tablename.split('_', 1)
        if self.id:
            form.vars.id = self.id
        current.audit(method, prefix, name, form=form, record=self.id, representation='xml')
        if (MTIME in table.fields):
            modified_on = table[MTIME]
            modified_on_update = modified_on.update
            modified_on.update = None
        else:
            modified_on_update = None
        s3db.update_super(table, form.vars)
        if (method == CREATE):
            current.auth.s3_set_record_owner(table, self.id)
        elif (method == UPDATE):
            update_realm = (enforce_realm_update or s3db.get_config(table, 'update_realm'))
            if update_realm:
                current.auth.set_realm_entity(table, self.id, force_update=True)
        key = ('%s_onaccept' % method)
        onaccept = current.deployment_settings.get_import_callback(tablename, key)
        if onaccept:
            callback(onaccept, form, tablename=tablename)
        if (modified_on_update is not None):
            modified_on.update = modified_on_update
    if (self.update and self.id):
        for u in self.update:
            item = u.get('item', None)
            if (not item):
                continue
            field = u.get('field', None)
            if isinstance(field, (list, tuple)):
                (pkey, fkey) = field
                query = (table.id == self.id)
                row = db(query).select(table[pkey], limitby=(0, 1)).first()
                if row:
                    item._update_reference(fkey, row[pkey])
            else:
                item._update_reference(field, self.id)
    return True
