/// <summary>
        /// This function is used purely to check the inputs for each given function, to ensure that the request bodies are built properly.
        /// </summary>
        /// <param name="rateRequest"></param>
        /// <param name="calculateRequest"></param>
        /// <returns></returns>
        private string CheckForValidInput(GetTaxRateRequest rateRequest = null, CalculateTaxRequest calculateRequest = null)
        {
            if (rateRequest != null)
            {
                switch (rateRequest.Country)
                {
                case "US":
                    if (rateRequest.ZipCode.Length < 3)
                    {
                        return("US ZipCode Length");
                    }
                    break;

                case "CA":
                    if (rateRequest.ZipCode.Length < 5)
                    {
                        return("CA ZipCode Length");
                    }
                    break;

                case "":
                case null:
                    return("No Country Code");
                }
            }

            if (calculateRequest != null)
            {
                //If Country is not correct, throw an error; no need to check the switch for that
                if (calculateRequest.from_country.Length < 2 || calculateRequest.to_country.Length < 2)
                {
                    return("Short Country Code");
                }
                if (calculateRequest.from_state.Length < 2 || calculateRequest.to_state.Length < 2)
                {
                    return("Short State Code");
                }
                if (calculateRequest.from_country == "US" && calculateRequest.from_zip.Length < 3 || calculateRequest.to_zip.Length < 3)
                {
                    return("US ZipCode Length");
                }
                if (calculateRequest.from_country == "CA" && calculateRequest.from_zip.Length < 5 || calculateRequest.from_zip.Length < 5)
                {
                    return("CA ZipCode Length");
                }
                if (calculateRequest.line_items.Count < 1)
                {
                    return("No Line Items");
                }
            }

            return("OK");
        }
        /// <summary>
        /// GETs the tax rate from TaxJar, given a ZipCode and a Country code
        /// All other parameters are not required, but will give more information if given
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public double GetTaxRate(GetTaxRateRequest request)
        {
            //FIlter inputs at the top to ensure a properly generated request body
            string errorText = CheckForValidInput(request, null);
            string responseText;
            double combinedRate = 0.0;

            if (errorText == "OK")
            {
                try
                {
                    //make call to TaxJar API...
                    TaxJarUrl.Append($"rates/{request.ZipCode}?country={request.Country}&city={request.City}");
                    //Append initial values; if street isnt null, append that after this.
                    if (request.Street != null && request.Street != "")
                    {
                        TaxJarUrl.Append($"&street={request.Street}");
                    }

                    //Create a Web Request;
                    var httpWebRequest = WebRequest.CreateHttp(TaxJarUrl.ToString());
                    //GET command
                    httpWebRequest.Method  = "GET";
                    httpWebRequest.Timeout = 300000;
                    //Set a Custom Authorization token; The API requires something that isn't standard.
                    httpWebRequest.Headers["Authorization"] = $"Token token=\"{apiToken}\"";

                    //Call the API and get a response object
                    var response = (HttpWebResponse)httpWebRequest.GetResponse();

                    //Stream it to Read it.
                    var stream = response.GetResponseStream();
                    if (stream != null)
                    {
                        using (var streamReader = new StreamReader(stream))
                        {
                            responseText = streamReader.ReadToEnd();
                        }

                        //Parse the stream into a JObject so we can get the info wenwant from a specific node.
                        var contentObject = JObject.Parse(responseText);

                        //Return the Combined Rate member value, or the Standard Rate, if combined rate isn't present.
                        if (contentObject["rate"]["combined_rate"] == null)
                        {
                            combinedRate = Convert.ToDouble(contentObject["rate"]["standard_rate"]);
                        }
                        else
                        {
                            combinedRate = Convert.ToDouble(contentObject["rate"]["combined_rate"]);
                        }
                    }
                }
                catch (WebException wex)
                {
                    //Toss the web exception up to the Controller to handle it.
                    throw wex;
                }
            }
            else
            {
                switch (errorText)
                {
                case "US ZipCode Length":
                    throw new ArgumentException("US ZipCode Requires at least 3 characters", "US ZipCode");

                case "CA ZipCode Length":
                    throw new ArgumentException("CA Zipcode must be at least 5 characters", "CA ZipCode");

                case "No Country Code":
                    throw new ArgumentException("No Country Code Present", "Country");
                }
            }


            //Assuming Combined_Rate is Requested, return that, or, again, the standard rate
            return(combinedRate);
        }