public function upsert($table, $id, array $data)
    {
        if (isset($this->prepared[$table]['ref']) && $this->execute($table, $id)) {
            $data[] = $id;
            if ($row = $this->fetch($table)) {
                return ($this->execute($this->prepared[$table]['ref']['update'], $data)) ? array_shift($row) : false;
            } else {
                return $this->execute($this->prepared[$table]['ref']['insert'], $data);
            }
        }
        $first = each($data);
        $single = (is_array($first['value'])) ? $first['value'] : false;
        if ($single) {
            $data = array_keys($single);
        }
        if ($stmt = $this->prepare("SELECT {$id} FROM {$table} WHERE {$id} = ?", 'row')) {
            $this->prepared[$stmt]['ref']['update'] = $this->update($table, $id, $data);
            $this->prepared[$stmt]['ref']['insert'] = $this->insert($table, array_merge($data, array($id)));
        }
        if ($single && $stmt) {
            $id = $this->upsert($stmt, $first['key'], array_values($single));
            $this->close($stmt);

            return $id;
        }

        return $stmt;
    }