/// <summary>
        /// Try to parse the given JSON representation of a tariff.
        /// </summary>
        /// <param name="JSON">The JSON to parse.</param>
        /// <param name="Tariff">The parsed tariff.</param>
        /// <param name="ErrorResponse">An optional error response.</param>
        /// <param name="CountryCodeURL">An optional country code, e.g. from the HTTP URL.</param>
        /// <param name="PartyIdURL">An optional party identification, e.g. from the HTTP URL.</param>
        /// <param name="TariffIdURL">An optional tariff identification, e.g. from the HTTP URL.</param>
        /// <param name="CustomTariffParser">A delegate to parse custom tariff JSON objects.</param>
        public static Boolean TryParse(JObject JSON,
                                       out Tariff Tariff,
                                       out String ErrorResponse,
                                       CountryCode?CountryCodeURL = null,
                                       Party_Id?PartyIdURL        = null,
                                       Tariff_Id?TariffIdURL      = null,
                                       CustomJObjectParserDelegate <Tariff> CustomTariffParser = null)
        {
            try
            {
                Tariff = default;

                if (JSON?.HasValues != true)
                {
                    ErrorResponse = "The given JSON object must not be null or empty!";
                    return(false);
                }

                #region Parse CountryCode           [optional]

                if (JSON.ParseOptionalStruct("country_code",
                                             "country code",
                                             CountryCode.TryParse,
                                             out CountryCode? CountryCodeBody,
                                             out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                if (!CountryCodeURL.HasValue && !CountryCodeBody.HasValue)
                {
                    ErrorResponse = "The country code is missing!";
                    return(false);
                }

                if (CountryCodeURL.HasValue && CountryCodeBody.HasValue && CountryCodeURL.Value != CountryCodeBody.Value)
                {
                    ErrorResponse = "The optional country code given within the JSON body does not match the one given in the URL!";
                    return(false);
                }

                #endregion

                #region Parse PartyIdURL            [optional]

                if (JSON.ParseOptionalStruct("party_id",
                                             "party identification",
                                             Party_Id.TryParse,
                                             out Party_Id? PartyIdBody,
                                             out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                if (!PartyIdURL.HasValue && !PartyIdBody.HasValue)
                {
                    ErrorResponse = "The party identification is missing!";
                    return(false);
                }

                if (PartyIdURL.HasValue && PartyIdBody.HasValue && PartyIdURL.Value != PartyIdBody.Value)
                {
                    ErrorResponse = "The optional party identification given within the JSON body does not match the one given in the URL!";
                    return(false);
                }

                #endregion

                #region Parse Id                    [optional]

                if (JSON.ParseOptionalStruct("id",
                                             "tariff identification",
                                             Tariff_Id.TryParse,
                                             out Tariff_Id? TariffIdBody,
                                             out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                if (!TariffIdURL.HasValue && !TariffIdBody.HasValue)
                {
                    ErrorResponse = "The tariff identification is missing!";
                    return(false);
                }

                if (TariffIdURL.HasValue && TariffIdBody.HasValue && TariffIdURL.Value != TariffIdBody.Value)
                {
                    ErrorResponse = "The optional tariff identification given within the JSON body does not match the one given in the URL!";
                    return(false);
                }

                #endregion

                #region Parse Currency              [mandatory]

                if (!JSON.ParseMandatory("currency",
                                         "currency",
                                         OCPIv2_1_1.Currency.TryParse,
                                         out Currency Currency,
                                         out ErrorResponse))
                {
                    return(false);
                }

                #endregion

                #region Parse TariffType            [optional]

                if (JSON.ParseOptionalEnum("type",
                                           "tariff type",
                                           out TariffTypes? TariffType,
                                           out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse TariffAltText         [optional]

                if (JSON.ParseOptionalJSON("tariff_alt_text",
                                           "tariff alternative text",
                                           DisplayText.TryParse,
                                           out IEnumerable <DisplayText> TariffAltText,
                                           out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse TariffAltURL          [optional]

                if (JSON.ParseOptional("tariff_alt_url",
                                       "tariff alternative URL",
                                       URL.TryParse,
                                       out URL? TariffAltURL,
                                       out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }


                #endregion

                #region Parse MinPrice              [optional]

                if (JSON.ParseOptionalJSON("min_price",
                                           "minimum price",
                                           Price.TryParse,
                                           out Price? MinPrice,
                                           out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse MaxPrice              [optional]

                if (JSON.ParseOptionalJSON("max_price",
                                           "maximum price",
                                           Price.TryParse,
                                           out Price? MaxPrice,
                                           out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse TariffElements        [mandatory]

                if (JSON.ParseMandatoryJSON("elements",
                                            "tariff elements",
                                            TariffElement.TryParse,
                                            out IEnumerable <TariffElement> TariffElements,
                                            out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse Start                 [optional]

                if (JSON.ParseOptional("start_date_time",
                                       "start timestamp",
                                       out DateTime? Start,
                                       out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse End                   [optional]

                if (JSON.ParseOptional("end_date_time",
                                       "end timestamp",
                                       out DateTime? End,
                                       out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse EnergyMix             [optional]

                if (JSON.ParseOptionalJSON("energy_mix",
                                           "energy mix",
                                           OCPIv2_1_1.EnergyMix.TryParse,
                                           out EnergyMix EnergyMix,
                                           out ErrorResponse))
                {
                    if (ErrorResponse != null)
                    {
                        return(false);
                    }
                }

                #endregion

                #region Parse LastUpdated           [mandatory]

                if (!JSON.ParseMandatory("last_updated",
                                         "last updated",
                                         out DateTime LastUpdated,
                                         out ErrorResponse))
                {
                    return(false);
                }

                #endregion


                Tariff = new Tariff(CountryCodeBody ?? CountryCodeURL.Value,
                                    PartyIdBody ?? PartyIdURL.Value,
                                    TariffIdBody ?? TariffIdURL.Value,
                                    Currency,
                                    TariffElements,

                                    TariffType,
                                    TariffAltText,
                                    TariffAltURL,
                                    MinPrice,
                                    MaxPrice,
                                    Start,
                                    End,
                                    EnergyMix,
                                    LastUpdated);

                if (CustomTariffParser != null)
                {
                    Tariff = CustomTariffParser(JSON,
                                                Tariff);
                }

                return(true);
            }
            catch (Exception e)
            {
                Tariff        = default;
                ErrorResponse = "The given JSON representation of a tariff is invalid: " + e.Message;
                return(false);
            }
        }