public IndividualClass DecodeIndividual(HttpPerson person)
        {
            if (person != null)
            {
                IndividualClass   individual = new IndividualClass();
                PersonalNameClass name       = new PersonalNameClass();

                if (person.id != null)
                {
                    individual.SetXrefName(person.id.Substring(8)); // skip "profile-"
                }
                if (person.first_name != null)
                {
                    name.SetName(PersonalNameClass.PartialNameType.GivenName, person.first_name);
                }
                if (person.last_name != null)
                {
                    name.SetName(PersonalNameClass.PartialNameType.Surname, person.last_name);
                }
                if (person.former_name != null)
                {
                    name.SetName(PersonalNameClass.PartialNameType.BirthSurname, person.former_name);
                }

                name.SanityCheck();

                individual.SetPersonalName(name);
                if (person.gender != null)
                {
                    switch (person.gender)
                    {
                    case "male":
                        individual.SetSex(IndividualClass.IndividualSexType.Male);
                        break;

                    case "female":
                        individual.SetSex(IndividualClass.IndividualSexType.Female);
                        break;
                    }
                }

                if (person.birth_date != null)
                {
                    FamilyDateTimeClass birthDate = new FamilyDateTimeClass(
                        person.birth_date.gedcom);
                    individual.AddEvent(new IndividualEventClass(IndividualEventClass.EventType.Birth, birthDate));
                }
                if (person.death_date != null)
                {
                    FamilyDateTimeClass deathDate = new FamilyDateTimeClass(
                        person.death_date.gedcom);
                    individual.AddEvent(new IndividualEventClass(IndividualEventClass.EventType.Death, deathDate));
                }

                return(individual);
            }

            return(null);
        }
        bool UpdateRelations(IDictionary <string, HttpPerson> personList, ref IndividualClass individual)
        {
            bool updated = false;

            foreach (KeyValuePair <string, HttpPerson> nodePersonPair in personList)
            {
                if ((nodePersonPair.Key.IndexOf("profile-") == 0) && (nodePersonPair.Key.Substring(8) == individual.GetXrefName()))
                {
                    if (nodePersonPair.Value != null)
                    {
                        HttpPerson nodePerson = (HttpPerson)nodePersonPair.Value;

                        /*if (nodePerson.edges != null)
                         * {
                         * foreach (KeyValuePair<string, HttpUnion> edgePair in nodePerson.edges)
                         * {
                         *  if (edgePair.Value != null)
                         *  {
                         *    HttpUnion union = (HttpUnion)edgePair.Value;
                         *
                         *    if (union.rel == "child")
                         *    {
                         *      individual.AddRelation(new FamilyXrefClass(edgePair.Key.Substring(6)), IndividualClass.RelationType.Child);
                         *      updated = true;
                         *    }
                         *    else if (union.rel == "partner")
                         *    {
                         *      individual.AddRelation(new FamilyXrefClass(edgePair.Key.Substring(6)), IndividualClass.RelationType.Spouse);
                         *      updated = true;
                         *    }
                         *  }
                         * }
                         * }*/
                    }
                }
            }
            return(updated);
        }
        public IndividualClass GetIndividual(String xrefName, uint index = (uint)SelectIndex.NoIndex, PersonDetail detailLevel = PersonDetail.PersonDetail_All)
        {
            if (xrefName == null)
            {
                trace.TraceInformation("GetIndividual(root)");
                rootPersonXref = FetchRootPerson();
                xrefName       = rootPersonXref;
            }
            if (xrefName == null)
            {
                trace.TraceInformation("GetIndividual(null)!!!" + DateTime.Now);
                return(null);
            }

            if (cache.individuals.ContainsKey(xrefName))
            {
                if (printDecode)
                {
                    trace.TraceInformation("GetIndividual(" + xrefName + ") cached");
                }
                return(cache.individuals[xrefName]);
            }
            if (printDecode)
            {
                trace.TraceInformation("GetIndividual(" + xrefName + ") start " + DateTime.Now);
            }

            if (!authenticated)
            {
                Authenticate();
                GetTreeStats();
            }

            string sLine = null;;

            try
            {
                string sURL = "https://www.geni.com/api/profile-" + xrefName + "/immediate-family?only_ids=true&fields=first_name,middle_name,nicknames,last_name,maiden_name,gender,birth,death,id";

                WebRequest wrGETURL;
                wrGETURL = WebRequest.Create(sURL);
                if (authenticationToken != null)
                {
                    wrGETURL.Headers.Add("Authorization", String.Format("Bearer {0}", Uri.EscapeDataString(authenticationToken)));
                }
                if (printDecode)
                {
                    trace.TraceInformation("GetIndividual(" + xrefName + ") = " + sURL + " " + DateTime.Now);
                }
                Stream objStream = wrGETURL.GetResponse().GetResponseStream();

                StreamReader objReader = new StreamReader(objStream);

                sLine = objReader.ReadToEnd();
            }
            catch
            {
                return(null);
            }

            if (sLine != null)
            {
                IndividualClass focusPerson;

                if (printDecode)
                {
                    trace.TraceInformation("**********************************************************-start");
                    trace.TraceInformation("{0}:{1}", sLine.Length, sLine);
                    trace.TraceInformation("**********************************************************-end");
                }
                if ((sLine.StartsWith("<!DOCTYPE") || sLine.StartsWith("<HTML") || sLine.StartsWith("<html")))
                {
                    trace.TraceInformation("Bad format. Don't parse.");
                    trace.TraceInformation("**********************************************************-start");
                    trace.TraceInformation("{0}:{1}", sLine.Length, sLine);
                    trace.TraceInformation("**********************************************************-end");
                    return(null);
                }

                getIndividualResult = serializer.Deserialize <HttpGetIndividualResult>(sLine);

                if (getIndividualResult.focus != null)
                {
                    focusPerson = DecodeIndividual(getIndividualResult.focus);

                    if (focusPerson != null)
                    {
                        if (!UpdateRelations(getIndividualResult.nodes, ref focusPerson))
                        {
                            if (printDecode)
                            {
                                trace.TraceInformation("focusperson added " + focusPerson.GetXrefName() + " no relation updates..");
                            }
                        }
                        cache.individuals.Add(focusPerson.GetXrefName(), focusPerson);
                    }

                    foreach (KeyValuePair <string, HttpPerson> nodePersonPair in getIndividualResult.nodes)
                    {
                        if (nodePersonPair.Key.IndexOf("profile-") == 0)
                        {
                            if (!cache.individuals.ContainsKey(nodePersonPair.Key.Substring(8)))
                            {
                                if (nodePersonPair.Value != null)
                                {
                                    HttpPerson nodePerson = (HttpPerson)nodePersonPair.Value;

                                    IndividualClass nodeIndividual = DecodeIndividual(nodePerson);

                                    if (nodeIndividual != null)
                                    {
                                        if (printDecode)
                                        {
                                            trace.TraceInformation(" Cache person:" + nodePersonPair.Key.Substring(8) + "=" + nodeIndividual.GetName());
                                        }
                                        if (!UpdateRelations(getIndividualResult.nodes, ref nodeIndividual))
                                        {
                                            trace.TraceInformation(" Added " + nodeIndividual.GetXrefName() + " no relation updates..");
                                        }

                                        /*if (printDecode)
                                         * {
                                         * nodeIndividual.Print();
                                         * }*/
                                        cache.individuals.Add(nodeIndividual.GetXrefName(), nodeIndividual);
                                    }
                                }
                            }
                            else
                            {
                                if (printDecode)
                                {
                                    trace.TraceInformation(" Person " + nodePersonPair.Key.Substring(8) + " skipped, already cached");
                                }
                            }
                        }
                    }

                    if (printDecode)
                    {
                        trace.TraceInformation("GetIndividual() done " + DateTime.Now);
                    }
                    return(focusPerson);
                }
            }

            return(null);
        }