Inheritance: FieldsContainer
 /**
  * @param query              A Person object with the query as interpreted by Pipl.
  * @param person             A Person object with data about the person in the query.
  * @param possible_persons   PossiblePersons
  * @param sources            A list of Source objects with full/partial match to the
  *                           query.
  * @param warnings           A list of strings. A warning is returned when the query
  *                           contains a non-critical error and the search can still run.
  * @param @search_id         string
  *
  * @param @persons_count     int. The number of persons in this response.
  */
 public SearchAPIResponse(Person query = null, Person person = null, List<Person> possible_Persons = null, List<Source> sources = null,
                          List<string> warnings = null, string searchId = null, int? personsCount = null)
 {
     this.Query = query;
     this.Person = person;
     this.PossiblePersons = possible_Persons;
     this.Sources = sources;
     this.Warnings = warnings;
     this.SearchId = searchId;
     if (personsCount == null)
     {
         if (this.Person != null) {
             personsCount = 1;
         } else {
             personsCount = this.PossiblePersons == null ? 0 : this.PossiblePersons.Count();
         }
     }
     this.PersonsCount = (int)personsCount;
     this.RawJSON = null;
     this.QpsAllotted = null;
     this.QpsCurrent = null;
     this.QuotaAllotted = null;
     this.QuotaCurrent = null;
     this.QuotaReset = null;
 }
        /**
         * Initiate a new request object with given query params.
         * Each request must have at least one searchable parameter, meaning
         * a name (at least first and last name), email, phone or username.
         * Multiple query params are possible (for example querying by both email
         * and phone of the Person).
         *
         * @param firstName         First name, minimum 2 chars
         * @param middleName        Middle name
         * @param lastName          Last name, minimum 2 chars
         * @param rawName           An unparsed name containing at least a first name
         *                          and a last name.
         * @param email             email
         * @param phone             a String that will be striped from all non-digit characters
         *                          and converted to Long. IMPORTANT: Currently only US/Canada
         *                          phones can be searched by so country code is assumed to be 1,
         *                          phones with different country codes are considered invalid and
         *                          will be ignored.
         *                          IMPORTANT: Currently only US/Canada phones can be searched by
         *                          so country code is assumed to be 1, phones with different
         *                          country codes are considered invalid and will be ignored.
         * @param username          username, minimum 4 chars
         * @param country           a 2 letter country code from:
         *                          http://en.wikipedia.org/wiki/ISO_3166-2
         * @param state             a state code from:
         *                          http://en.wikipedia.org/wiki/ISO_3166-2%3AUS
         *                          http://en.wikipedia.org/wiki/ISO_3166-2%3ACA
         * @param city              city
         * @param zip_code          zipCode
         * @param rawAddress        An unparsed address
         * @param fromAge           fromAge
         * @param toAge             toAge
         * @param person            A Person object (Pipl.APIs.Data.Person).
         *                          The Person can contain every field allowed by the data-model
         *                          (see Pipl.APIs.Data.Fields) and can hold multiple fields of
         *                          the same type (for example: two emails, three addresses etc.)
         * @param searchPointer     A search pointer (from a Possible Person object), to be used for drill-down searches.
         * @param requestConfiguration      RequestConfiguration object. If null, the default RequestConfiguration object is used
         */
        public SearchAPIRequest(string firstName = null, string middleName = null,
                                string lastName = null, string rawName = null, string email = null, string phone = null,
                                string username = null, string country = null, string state = null, string city = null, string zipCode = null,
                                string rawAddress = null, int? fromAge = null, int? toAge = null, Person person = null, 
                                string searchPointer = null, SearchConfiguration requestConfiguration = null)
        {
            Configuration = requestConfiguration;

            List<Field> fields = new List<Field>();

            if (!String.IsNullOrEmpty(firstName) || !String.IsNullOrEmpty(middleName) || !String.IsNullOrEmpty(lastName))
            {
                fields.Add(new Data.Fields.Name(first: firstName, middle: middleName, last: lastName));
            }
            if (!String.IsNullOrEmpty(rawName))
            {
                fields.Add(new Data.Fields.Name(raw: rawName));
            }
            if (!String.IsNullOrEmpty(email))
            {
                fields.Add(new Email(address: email));
            }
            if (!String.IsNullOrEmpty(phone))
            {
                fields.Add(new Phone(raw: phone));
            }
            if (!String.IsNullOrEmpty(username))
            {
                fields.Add(new Username(username));
            }
            if (!String.IsNullOrEmpty(country) || !String.IsNullOrEmpty(state) || !String.IsNullOrEmpty(city) || !String.IsNullOrEmpty(zipCode))
            {
                fields.Add(new Address(country: country, state: state, city: city, zip_code: zipCode));
            }
            if (!String.IsNullOrEmpty(rawAddress))
            {
                fields.Add(new Address(raw: rawAddress));
            }
            if ((fromAge != null) || (toAge != null))
            {
                fields.Add(DOB.FromAgeRange((fromAge == null) ? 0 : (int)fromAge,
                                            (toAge == null) ? 1000 : (int)toAge));
            }
            if (person == null)
            {
                person = new Person();
            }
            if (searchPointer != null)
            {
                person.SearchPointer = searchPointer;
            }
            this.Person = person;
            Person.AddFields(fields);

            if (String.IsNullOrEmpty(EffectiveConfiguration.Url))
            {
                Url = (EffectiveConfiguration.UseHttps) ? BaseUrlHttpS : BaseUrlHttp;
            }
            else
            {
                Url = EffectiveConfiguration.Url;
            }
        }