private function doUpdate(array $changes) {
        $db     = $this->db();
        $entity = $this->dao()->getEntityMapping();
        $table  = $entity->getTableName();

        // collect identity infos
        $identity = $entity->getIdentity();
        $idColumn = $identity->getColumn();
        $idValue  = $identity->convertToDBValue($this->getObjectId(), $db);

        // collect version infos
        $versionMapping = $versionName = $versionColumn = $oldVersion = null;
        //if ($versionMapping = $entity->getVersion()) {
        //    $versionName   = $versionMapping->getName();
        //    $versionColumn = $versionMapping->getColumn();
        //    $oldVersion    = $object->getSnapshot()->$versionName;        // TODO: implement dirty check via snapshot
        //    $oldVersion    = $versionMapping->convertToDBValue($oldVersion, $db);
        //}

        // create SQL
        $sql = 'update '.$table.' set';                                     // update table
        foreach ($changes as $name => $value) {                             //    set ...
            $mapping     = $entity->getProperty($name);                     //        ...
            $columnName  = $mapping->getColumn();                           //        ...
            $columnValue = $mapping->convertToDBValue($value, $db);         //        column1 = value1,
            $sql .= ' '.$columnName.' = '.$columnValue.',';                 //        column2 = value2,
        }                                                                   //        ...
        $sql  = strLeft($sql, -1);                                          //        ...
        $sql .= ' where '.$idColumn.' = '.$idValue;                         //    where id = value
        if ($versionMapping) {                                              //        ...
            $op   = $oldVersion=='null' ? 'is':'=';                         //        ...
            $sql .= ' and '.$versionColumn.' '.$op.' '.$oldVersion;         //      and version = oldVersion
        }

        // execute SQL and check for concurrent modifications
        if ($db->execute($sql)->lastAffectedRows() != 1) {
            if ($versionMapping) {
                $this->reload();
                $msg = 'expected version: '.$oldVersion.', found version: '.$this->$versionName;
            }
            else $msg = 'record not found';
            throw new ConcurrentModificationException('Error updating '.get_class($this).' (oid='.$this->getObjectId().'), '.$msg);
        }
        return true;
    }