'Internal update / replace helper.'

def _update(self, sock_info, criteria, document, upsert=False, check_keys=True, multi=False, manipulate=False, write_concern=None, op_id=None, ordered=True, bypass_doc_val=False, collation=None):

    common.validate_boolean('upsert', upsert)
    if manipulate:
        document = self.__database._fix_incoming(document, self)
    collation = validate_collation_or_none(collation)
    concern = (write_concern or self.write_concern).document
    acknowledged = (concern.get('w') != 0)
    update_doc = SON([('q', criteria), ('u', document), ('multi', multi), ('upsert', upsert)])
    if (collation is not None):
        if (sock_info.max_wire_version < 5):
            raise ConfigurationError('Must    be    connected    to    MongoDB    3.4+    to    use    collations.')
        elif (not acknowledged):
            raise ConfigurationError('Collation    is    unsupported    for    unacknowledged    writes.')
        else:
            update_doc['collation'] = collation
    command = SON([('update', self.name), ('ordered', ordered), ('updates', [update_doc])])
    if concern:
        command['writeConcern'] = concern
    if ((sock_info.max_wire_version > 1) and acknowledged):
        if (bypass_doc_val and (sock_info.max_wire_version >= 4)):
            command['bypassDocumentValidation'] = True
        result = sock_info.command(self.__database.name, command, codec_options=self.__write_response_codec_options).copy()
        _check_write_command_response([(0, result)])
        if (result.get('n') and ('upserted' not in result)):
            result['updatedExisting'] = True
        else:
            result['updatedExisting'] = False
            if ('upserted' in result):
                result['upserted'] = result['upserted'][0]['_id']
        return result
    else:
        return self._legacy_write(sock_info, 'update', command, acknowledged, op_id, bypass_doc_val, message.update, self.__full_name, upsert, multi, criteria, document, acknowledged, concern, check_keys, self.__write_response_codec_options)
