public async Task<ValidateResult> Validate(Address address)
        {
            // Convert input address data to query string
            string querystring = string.Empty;
            querystring += (address.Line1 == null) ? string.Empty : "Line1=" + address.Line1.Replace(" ", "+");
            querystring += (address.Line2 == null) ? string.Empty : "&Line2=" + address.Line2.Replace(" ", "+");
            querystring += (address.Line3 == null) ? string.Empty : "&Line3=" + address.Line3.Replace(" ", "+");
            querystring += (address.City == null) ? string.Empty : "&City=" + address.City.Replace(" ", "+");
            querystring += (address.Region == null) ? string.Empty : "&Region=" + address.Region.Replace(" ", "+");
            querystring += (address.PostalCode == null) ? string.Empty : "&PostalCode=" + address.PostalCode.Replace(" ", "+");
            querystring += (address.Country == null) ? string.Empty : "&Country=" + address.Country.Replace(" ", "+");

            // Call the service
            Uri webAddress = new Uri(_svcUrl + "address/validate.xml?" + querystring);
            var request = HttpHelper.CreateRequest(webAddress, _accountNumber, _license);
            request.Method = "GET";

            ValidateResult result = new ValidateResult();
            try
            {
                WebResponse response = await request.GetResponseAsync();
                XmlSerializer r = new XmlSerializer(result.GetType());
                result = (ValidateResult)r.Deserialize(response.GetResponseStream());
                address = result.Address; // If the address was validated, take the validated address.
            }
            catch (WebException ex)
            {
                Stream responseStream = ((HttpWebResponse)ex.Response).GetResponseStream();
                StreamReader reader = new StreamReader(responseStream);
                string responseString = reader.ReadToEnd();

                // The service returns some error messages in JSON for authentication/unhandled errors.
                if (responseString.StartsWith("{")  || responseString.StartsWith("["))
                {
                    result = new ValidateResult();
                    result.ResultCode = SeverityLevel.Error;
                    Message msg = new Message();
                    msg.Severity = result.ResultCode;
                    msg.Summary = "The request was unable to be successfully serviced, please try again or contact Customer Service.";
                    msg.Source = "Avalara.Web.REST";
                    if (!((HttpWebResponse)ex.Response).StatusCode.Equals(HttpStatusCode.InternalServerError))
                    {
                        msg.Summary = "The user or account could not be authenticated.";
                        msg.Source = "Avalara.Web.Authorization"; 
                    }

                    result.Messages = new Message[1] { msg };
                }
                else
                {
                    XmlSerializer r = new XmlSerializer(result.GetType());
                    byte[] temp = Encoding.ASCII.GetBytes(responseString);
                    MemoryStream stream = new MemoryStream(temp);
                    result = (ValidateResult)r.Deserialize(stream); // Inelegant, but the deserializer only takes streams, and we already read ours out.
                }
            }

            return result;
        }
        public async Task GeoTaxTest()
        {
            // Header Level Elements
            // Required Header Level Elements
            var configSection = ConfigurationHelper.GetConfiguration();
            string accountNumber = configSection["accountNumber"];
            string licenseKey = configSection["licenseKey"];
            string serviceUrl = configSection["serviceUrl"];

            ITaxService taxSvc = new TaxService(accountNumber, licenseKey, serviceUrl);

            GetTaxRequest getTaxRequest = new GetTaxRequest
            {
                CustomerCode = "ABC4335",
                DocDate = "2014-01-01",
                CompanyCode = "APITrialCompany",
                Client = "AvaTaxSample",
                DocCode = "INV001",
                DetailLevel = DetailLevel.Tax,
                Commit = false,
                DocType = DocType.SalesInvoice,
                PurchaseOrderNo = "PO123456",
                ReferenceCode = "ref123456",
                PosLaneCode = "09",
                CurrencyCode = "USD"
            };

            // Document Level Elements
            // Required Request Parameters

            // Best Practice Request Parameters

            // Situational Request Parameters
            // getTaxRequest.CustomerUsageType = "G";
            // getTaxRequest.ExemptionNo = "12345";
            // getTaxRequest.BusinessIdentificationNo = "234243";
            // getTaxRequest.Discount = 50;
            // getTaxRequest.TaxOverride = new TaxOverrideDef();
            // getTaxRequest.TaxOverride.TaxOverrideType = "TaxDate";
            // getTaxRequest.TaxOverride.Reason = "Adjustment for return";
            // getTaxRequest.TaxOverride.TaxDate = "2013-07-01";
            // getTaxRequest.TaxOverride.TaxAmount = "0";

            // Optional Request Parameters

            // Address Data
            Address address1 = new Address
            {
                AddressCode = "01",
                Line1 = "45 Fremont Street",
                City = "San Francisco",
                Region = "CA"
            };

            Address address2 = new Address
            {
                AddressCode = "02",
                Line1 = "118 N Clark St",
                Line2 = "Suite 100",
                Line3 = "ATTN Accounts Payable",
                City = "Chicago",
                Region = "IL",
                Country = "US",
                PostalCode = "60602"
            };

            Address address3 = new Address
            {
                AddressCode = "03",
                Latitude = (decimal) 47.627935,
                Longitude = (decimal) -122.51702
            };
            Address[] addresses = {address1, address2, address3};
            getTaxRequest.Addresses = addresses;

            // Line Data
            // Required Parameters
            Line line1 = new Line
            {
                LineNo = "01",
                ItemCode = "N543",
                Qty = 1,
                Amount = 10,
                OriginCode = "01",
                DestinationCode = "02",
                Description = "Red Size 7 Widget",
                TaxCode = "NT",
                Ref1 = "ref123",
                Ref2 = "ref456"
            };

            // Best Practice Request Parameters

            // Situational Request Parameters
            // line1.CustomerUsageType = "L";
            // line1.Discounted = true;
            // line1.TaxIncluded = true;
            // line1.BusinessIdentificationNo = "234243";
            // line1.TaxOverride = new TaxOverrideDef();
            // line1.TaxOverride.TaxOverrideType = "TaxDate";
            // line1.TaxOverride.Reason = "Adjustment for return";
            // line1.TaxOverride.TaxDate = "2013-07-01";
            // line1.TaxOverride.TaxAmount = "0";

            // Optional Request Parameters

            Line line2 = new Line
            {
                LineNo = "02",
                ItemCode = "T345",
                Qty = 3,
                Amount = 150,
                OriginCode = "01",
                DestinationCode = "03",
                Description = "Size 10 Green Running Shoe",
                TaxCode = "PC030147"
            };

            Line line3 = new Line
            {
                LineNo = "02-FR",
                ItemCode = "FREIGHT",
                Qty = 1,
                Amount = 15,
                OriginCode = "01",
                DestinationCode = "03",
                Description = "Shipping Charge",
                TaxCode = "FR"
            };
            Line[] lines = {line1, line2, line3};
            getTaxRequest.Lines = lines;

            GetTaxResult getTaxResult = await taxSvc.GetTax(getTaxRequest);

            // Print results
            Console.WriteLine("GetTaxTest Result: {0}", getTaxResult.ResultCode);
            if (!getTaxResult.ResultCode.Equals(SeverityLevel.Success))
            {
                foreach (Message message in getTaxResult.Messages)
                {
                    Console.WriteLine(message.Summary);
                }
            }
            else
            {
                Console.WriteLine("Document Code: {0} Total Tax: {1}", getTaxResult.DocCode, getTaxResult.TotalTax);
                foreach (TaxLine taxLine in getTaxResult.TaxLines ?? Enumerable.Empty<TaxLine>())
                {
                    Console.WriteLine("    Line Number: {0} Line Tax: {1}", taxLine.LineNo,
                        taxLine.Tax.ToString(CultureInfo.CurrentCulture));
                    foreach (TaxDetail taxDetail in taxLine.TaxDetails ?? Enumerable.Empty<TaxDetail>())
                    {
                        Console.WriteLine("        Jurisdiction: {0}Tax: {1}", taxDetail.JurisName,
                            taxDetail.Tax.ToString(CultureInfo.CurrentCulture));
                    }
                }
            }
        }
        public async Task AddressValidateTest()
        {
            // Header Level Elements
            // Required Header Level Elements
            var configSection = ConfigurationHelper.GetConfiguration();
            string accountNumber = configSection["accountNumber"];
            string licenseKey = configSection["licenseKey"];
            string serviceUrl = configSection["serviceUrl"];

            IAddressService addressSvc = new AddressService(accountNumber, licenseKey, serviceUrl);

            Address address = new Address
            {
                Line1 = "118 N Clark St",
                City = "Chicago",
                Region = "IL",
                Line2 = "Suite 100",
                Line3 = "ATTN Accounts Payable",
                Country = "US",
                PostalCode = "60602"
            };

            // Required Request Parameters

            // Optional Request Parameters

            ValidateResult validateResult = await addressSvc.Validate(address);

            // Print results
            Console.WriteLine("ValidateAddressTest Result: {0}", validateResult.ResultCode);
            if (!validateResult.ResultCode.Equals(SeverityLevel.Success))
            {
                foreach (Message message in validateResult.Messages)
                {
                    Console.WriteLine(message.Summary);
                }
            }
            else
            {
                Console.WriteLine(validateResult.Address.Line1
                                  + " "
                                  + validateResult.Address.City
                                  + ", "
                                  + validateResult.Address.Region
                                  + " "
                                  + validateResult.Address.PostalCode);
            }
        }