public function prepare()
    {
        if ($this->_deleted) {
            throw new DataSift_Exception_InvalidData('Cannot prepare a deleted Historic.');
        }

        if ($this->_playback_id !== false) {
            throw new DataSift_Exception_InvalidData('This historic query has already been prepared.');
        }

        try {
            $res = $this->_user->post(
                'historics/prepare',
                array(
                    'hash' => $this->_hash,
                    'start' => $this->_start,
                    'end' => $this->_end,
                    'name' => $this->_name,
                    'sources' => implode(',', $this->_sources),
                    'sample' => $this->_sample,
                )
            );

            if (isset($res['id'])) {
                $this->_playback_id = $res['id'];
            } else {
                throw new DataSift_Exception_APIError('Prepared successfully but no playback ID in the response');
            }

            if (isset($res['dpus'])) {
                $this->_dpus = $res['dpus'];
            } else {
                throw new DataSift_Exception_APIError('Prepared successfully but no DPU cost in the response');
            }

            if (isset($res['availability'])) {
                $this->_availability = $res['availability'];
            } else {
                throw new DataSift_Exception_APIError('Prepared successfully but no availability in the response');
            }
        } catch (DataSift_Exception_APIError $e) {
            switch ($e->getCode()) {
                case 400:
                    // Missing or invalid parameters
                    throw new DataSift_Exception_InvalidData($e->getMessage());

                default:
                    throw new DataSift_Exception_APIError(
                        'Unexpected APIError code: ' . $e->getCode() . ' [' . $e->getMessage() . ']'
                    );
            }
        }
    }