/// <summary>
        /// Gets list of profiles, associated with the particular name-address or name-zip pair.
        /// Throws an exception if response status is 404.
        /// More information at: https://nextcaller.com/documentation/v2.1/#/profiles/retrieve-profile-name-address/curl.
        /// </summary>
        /// <param name="nameAddressData">Pair of name and address or name and zip code.</param>
        /// <returns>Profiles, associated with the particular name-address or name-zip pair.</returns>
        public string GetByNameAddressJson(NameAddress nameAddressData)
        {
            var parameters = new []
            {
                new UrlParameter(nameAddressFirstNameParameterName, nameAddressData.FirstName ?? ""),
                new UrlParameter(nameAddressLastNameParameterName, nameAddressData.LastName ?? ""),
                new UrlParameter(nameAddressAddressParameterName, nameAddressData.AddressLine ?? ""),
                new UrlParameter(formatParameterName, DefaultResponseType.ToString())
            };
            var additional = nameAddressData.ZipCode != 0
                ? new[]
                {
                    new UrlParameter(nameAddressZipParameterName, nameAddressData.ZipCode.ToString(CultureInfo.InvariantCulture))
                }
                : new[]
                {
                    new UrlParameter(nameAddressCityParameterName, nameAddressData.City ?? ""),
                    new UrlParameter(nameAddressStateParameterName, nameAddressData.State ?? "")
                };

            string url = BuildUrl(phoneUrl, parameters.Concat(additional).ToArray());

            return httpTransport.Request(url, DefaultResponseType);
        }
        /// <summary>
        /// Gets list of profiles, associated with the particular name-address or name-zip pair.
        /// Throws an exception if response status is 404.
        /// More information at: https://nextcaller.com/documentation/v2.1/#/profiles/retreive-profile-name-address/curl.
        /// </summary>
        /// <param name="nameAddressData">Pair of name and address or name and zip code.</param>
        /// <returns>Profiles, associated with the particular name-address or name-zip pair.</returns>
        public IList<Profile> GetByNameAddress(NameAddress nameAddressData)
        {
            Utility.EnsureParameterValid(!(nameAddressData == null), "nameAddressData");

            string content = GetByNameAddressJson(nameAddressData);

            return JsonSerializer.ParseProfileList(content);
        }
        public static void Run()
        {
            const string Username = "";
            const string Password = "";
            const bool Sandbox = true;

            NextCallerClient client = new NextCallerClient(Username, Password, Sandbox);

            NameAddress nameAddress = new NameAddress
            {
                AddressLine = "129 West 81st Street",
                FirstName = "Jerry",
                LastName = "Seinfeld",
                City = "New York",
                State = "NY"
            };

            try
            {
                IList<Profile> profiles = client.GetByNameAddress(nameAddress);

                Profile profile = profiles.First();

                //profile.Id = "97d949a413f4ea8b85e9586e1f2d9a";
                //profile.FirstName = "Jerry";
                //profile.LastName = "Seinfeld";
                //profile.Name = "Jerry K Seingeld";
                //profile.Language = "English";

                //Phone phone = profile.Phones.First();
                //phone.Number = "2125558383";
                //phone.ResourceUri = "/v2/records/2125558383/";

                //profile.Carrier = "Verizon Wireless";
                //profile.LineType = "LAN";

                //Address address = profile.Addresses.First();
                //address.City = "New York";
                //address.State = "NY";
                //address.Country = "USA";
                //address.Line1 = "129 West 81st Street";
                //address.Line2 = "Apt 5a";
                //address.ZipCode = "10024";
                //address.ExtendedZip = "";

                //profile.Email = "*****@*****.**";
                //profile.LinkedEmails = new[]
                //{
                //	"*****@*****.**", "*****@*****.**", "*****@*****.**"
                //};
                //profile.SocialLinks = new[]
                //{
                //	new Dictionary<string, object>()
                //	{
                //		{ "type", "twitter" },
                //		{ "url", "http://www.twitter.com/example" },
                //		{ "followers", 323 }
                //	}
                //};
                //profile.Relatives = new []
                //{
                //	new Relative
                //	{
                //		Id = "a4bf8cff1bfd61d8611d396997bb29",
                //		Name = "Clark Kent",
                //		ResourceUri = "/v2/users/90c6a00c6391421d3a764716927cd8/"
                //	}
                //};
                //profile.DateOfBirth = "05/15/1970";
                //profile.Gender = "Male";
                //profile.Age = "45-54";
                //profile.HouseholdIncome = "50k-75k";
                //profile.HomeOwnerStatus = "Rent";
                //profile.LengthOfResidence = "12 Years";
                //profile.Occupation = "Entertainer";
                //profile.Education = "Completed College";
                //profile.ResourceUri = "/v2/users/97d949a413f4ea8b85e9586e1f2d9a/";

            }
            catch (FormatException formatException)
            {

                HttpWebRequest request = formatException.Request;
                HttpWebResponse response = formatException.Response;

                HttpStatusCode code = response.StatusCode;
                Console.WriteLine("Status code: {0}", code);

                string reasonPhrase = response.StatusDescription;
                Console.WriteLine("Reason Phrase: {0}", reasonPhrase);

                string responseContent = formatException.Content;
                Console.WriteLine("Content : {0}", responseContent);

            }
            catch (BadRequestException badRequestException)
            {

                HttpWebRequest request = badRequestException.Request;
                HttpWebResponse response = badRequestException.Response;

                Error parsedError = badRequestException.Error;

                string errorCode = parsedError.Code;
                string message = parsedError.Message;
                string type = parsedError.Type;

                Dictionary<string, string[]> description = parsedError.Description;

                Console.WriteLine(parsedError.ToString());

            }
        }
        /// <summary>
        /// Gets list of profiles, associated with the particular name-address or name-zip pair.
        /// Throws an exception if response status is 404.
        /// More info at: https://nextcaller.com/platform/documentation/v2.1/#/profiles/get-profile-name-and-address/curl.
        /// </summary>
        /// <param name="nameAddressData">Pair of name and address or name and zip code.</param>
        /// <param name="accountId">Platform account ID.</param>
        /// <returns>Profiles, associated with the particular name-address or name-zip pair.</returns>
        public IList<Profile> GetByNameAddress(NameAddress nameAddressData, string accountId = null)
        {
            Utility.EnsureParameterValid(!(nameAddressData == null), "nameAddressData");

            string response = GetByNameAddressJson(nameAddressData, accountId);

            return JsonSerializer.ParseProfileList(response);
        }
        public void GetProfilesByNameAddress_ValidNA_ProfilesReturned()
        {
            //Arrange
            NameAddress nameAddress = new NameAddress
            {
                AddressLine = "129 West 81st Street",
                FirstName = "Jerry",
                LastName = "Seinfeld",
                City = "New York",
                State = "NY"
            };

            string jsonProfiles = Properties.Resources.JsonProfiles;

            Mock<IHttpTransport> httpTransportMock = new Mock<IHttpTransport>(MockBehavior.Strict);
            httpTransportMock.Setup(httpTransport => httpTransport.Request(It.IsAny<string>(), It.IsAny<ContentType>(),  It.IsIn("GET", "POST"), null, null))
                .Returns(jsonProfiles);

            //Action
            NextCallerClient client = new NextCallerClient(httpTransportMock.Object);
            string profiles = client.GetByNameAddressJson(nameAddress);

            //Assert
            httpTransportMock.Verify(httpTransport => httpTransport.Request(It.IsAny<string>(), It.IsAny<ContentType>(),  It.IsIn("GET", "POST"), null, null), Times.Once);

            Assert.IsNotNull(profiles);
            Assert.AreEqual(jsonProfiles, profiles);
        }