/// <summary>
        /// Prepare this Historics query.
        /// </summary>
        public void prepare()
        {
            if (isDeleted())
            {
                throw new InvalidDataException("Cannot set the name of a deleted Historics query");
            }
            if (m_playback_id.Length > 0)
            {
                throw new InvalidDataException("This Historics query has already been prepared");
            }

            Dictionary <string, string> parameters = new Dictionary <string, string>();

            parameters.Add("hash", m_stream_hash);
            parameters.Add("start", Utils.DateTimeToUnixTimestamp(m_start_date).ToString());
            parameters.Add("end", Utils.DateTimeToUnixTimestamp(m_end_date).ToString());
            parameters.Add("name", m_name);
            parameters.Add("sources", string.Join(",", m_sources.ToArray()));
            try
            {
                JSONdn res = m_user.callApi("historics/prepare", parameters);

                if (!res.has("id"))
                {
                    throw new InvalidDataException("Prepared successfully but no playback ID in the response");
                }
                m_playback_id = res.getStringVal("id");

                if (!res.has("dpus"))
                {
                    throw new InvalidDataException("Prepared successfully but no DPU cost in the response");
                }
                m_dpus = res.getDoubleVal("dpus");

                if (!res.has("availability"))
                {
                    throw new InvalidDataException("Prepared successfully but no availability in the response");
                }
                m_availability = new HistoricDataAvailability(new JSONdn(res.getJVal("availability")));
            }
            catch (ApiException e)
            {
                // 400 = Missing or bad parameters.
                // 404 = Historics query not found.
                if (e.Code == 400 || e.Code == 404)
                {
                    throw new InvalidDataException(e.Message);
                }
                throw new ApiException("Unexpected API response code: " + e.Code.ToString() + " " + e.Message);
            }

            // Update our data.
            reloadData();
        }
        /// <summary>
        /// Prepare this Historics query.
        /// </summary>
        public void prepare()
        {
            if (isDeleted())
            {
                throw new InvalidDataException("Cannot set the name of a deleted Historics query");
            }
            if (m_playback_id.Length > 0)
            {
                throw new InvalidDataException("This Historics query has already been prepared");
            }

            Dictionary<string,string> parameters = new Dictionary<string,string>();
            parameters.Add("hash", m_stream_hash);
            parameters.Add("start", Utils.DateTimeToUnixTimestamp(m_start_date).ToString());
            parameters.Add("end", Utils.DateTimeToUnixTimestamp(m_end_date).ToString());
            parameters.Add("name", m_name);
            parameters.Add("sources", string.Join(",", m_sources.ToArray()));
            try
            {
                JSONdn res = m_user.callApi("historics/prepare", parameters);

                if (!res.has("id"))
                {
                    throw new InvalidDataException("Prepared successfully but no playback ID in the response");
                }
                m_playback_id = res.getStringVal("id");

                if (!res.has("dpus"))
                {
                    throw new InvalidDataException("Prepared successfully but no DPU cost in the response");
                }
                m_dpus = res.getDoubleVal("dpus");

                if (!res.has("availability"))
                {
                    throw new InvalidDataException("Prepared successfully but no availability in the response");
                }
                m_availability = new HistoricDataAvailability(new JSONdn(res.getJVal("availability")));
            }
            catch (ApiException e)
            {
                // 400 = Missing or bad parameters.
                // 404 = Historics query not found.
                if (e.Code == 400 || e.Code == 404)
                {
                    throw new InvalidDataException(e.Message);
                }
                throw new ApiException("Unexpected API response code: " + e.Code.ToString() + " " + e.Message);
            }

            // Update our data.
            reloadData();
        }