/// <summary>
        /// Construct a list of death records matching a specific record, using a user-definable filter predicate
        /// </summary>
        /// <param name="dB">the database to search</param>
        /// <param name="drMatch">the specific death record to match</param>
        /// <param name="filter">the filter predicate used to determine matches to <paramref name="drMatch"/></param>
        /// <returns></returns>
        public static List<IDeathRecord> Matches(Linq2SqlDataContext dB, IDeathRecord drMatch, Func<IDeathRecord, IDeathRecord, bool> filter)
        {
            List<IDeathRecord> lMatches = new List<IDeathRecord>();

            if (drMatch.DeathDate.Year < 1916)
            {
                var query = from c in dB.IllinoisDeathIndexPre1916s
                            where filter( c, drMatch )
                            select c;

                foreach (IDeathRecord indxNext in query)
                    lMatches.Add(indxNext);
            }
            else
            {
                var query = from c in dB.IllinoisDeathIndexPost1915s
                            where filter( c, drMatch )
                            select c;

                foreach (IDeathRecord indxNext in query)
                    lMatches.Add(indxNext);
            }

            return lMatches;
        }
        /// <summary>
        /// Get the Uniform Resource Locator for a query matching a specified death record
        /// </summary>
        /// <param name="drTarg">the death record to match</param>
        /// <returns>a properly-formatted URL for issuing the web query</returns>
        public static string GetUrl(IDeathRecord drTarg)
        {
            bool bBefore1916 = drTarg.FilingDate.Year < 1916;

            string sUrl = bBefore1916 ? "http://www.ilsos.gov/isavital/deathSearch.do" : "http://www.ilsos.gov/isavital/idphDeathSearch.do";
            sUrl += "?";
            sUrl += bBefore1916 ? "name=" + drTarg.LastName + ", " + drTarg.FirstName + "&county=STATEWIDE" : "firstName=" + drTarg.FirstName + "&lastName=" + drTarg.LastName + "&middleName=&county=STATEWIDE";
            return sUrl;
        }
        /// <summary>
        /// Search the Illinois death indices for a specified individual
        /// </summary>
        /// <param name="drTarg">Death record of the desired individual</param>
        /// <param name="browser"><see cref="WebBrowser"/> control to display results in</param>
        public IllinoisDeathIndexWebQuery(IDeathRecord drTarg, WebBrowser browser)
            : base(browser, QueryMethod.Post)
        {
            bool bBefore1916 = drTarg.FilingDate.Year < 1916;

            _Url = bBefore1916 ? "http://www.ilsos.gov/isavital/deathSearch.do" : "http://www.ilsos.gov/isavital/idphDeathSearch.do";
            // _PostData = bBefore1916 ? "name=" + drTarg.LastName + ", " + drTarg.FirstName + "&county=COOK" : "firstName=" + drTarg.FirstName + "&lastName=" + drTarg.LastName + "&middleName=&county=COOK";
            _PostData = bBefore1916 ? "name=" + drTarg.LastName + ", " + drTarg.FirstName + "&county=STATEWIDE" : "firstName=" + drTarg.FirstName + "&lastName=" + drTarg.LastName + "&middleName=&county=STATEWIDE";
        }
        /// <summary>
        /// Create a copy of a pre-1916 Illinois death record
        /// </summary>
        /// <param name="drSource">the death record to copy</param>
        /// <returns>an exact, but referentially distinct, copy of <paramref name="drSource"/></returns>
        public static IllinoisDeathIndexPre1916 CreatePre1916(IDeathRecord drSource)
        {
            if (drSource.DeathDate.Year > 1915)
                throw new ArgumentException("Death date \"" + drSource.DeathDate.ToShortDateString() + "\" is not pre-1916");

            IllinoisDeathIndexPre1916 drNew = new IllinoisDeathIndexPre1916();
            Initialize(drSource, drNew);
            return drNew;
        }
 /// <summary>
 /// Create a copy of an existing Illinois death record
 /// </summary>
 /// <param name="drSource">the death record to copy</param>
 /// <returns>an exact, but referentially distinct, copy of <paramref name="drSource"/></returns>
 public static IDeathRecord Create(IDeathRecord drSource)
 {
     IDeathRecord drNew;
     if (drSource.DeathDate.Year < 1916)
         drNew = new IllinoisDeathIndexPre1916();
     else
         drNew = new IllinoisDeathIndexPost1915();
     Initialize(drSource, drNew);
     return drNew;
 }
        /// <summary>
        /// Construct a Family Search Web query against a specified death record
        /// </summary>
        /// <param name="drTarg">the death record to query for matching records on the Family Search Web site</param>
        /// <param name="browser">the web browser to use in processing the query</param>
        public FamilySearchWebQuery(IDeathRecord drTarg, WebBrowser browser)
            : base(browser, QueryMethod.Get)
        {
            string sYear = drTarg.DeathDate.Year.ToString(CultureInfo.InvariantCulture);

            // https://familysearch.org/search/records/index#count=20&query=%2Bgivenname%3AFrank~%20%2Bsurname%3AUlcek~%20%2Bdeath_place%3AIllinois~%20%2Bdeath_year%3A1918-1918
            // _Url = "https://www.familysearch.org/search/records/index#count=20&query=%2B";
            // _PostData = "givenname%3A" + drTarg.FirstName + "~%20%2Bsurname%3A" + drTarg.LastName + "~%20%2Bdeath_place%3AIllinois~%20%2Bdeath_year%3A" + sYear + "-" + sYear;
            _Url = "https://www.familysearch.org/search/records/index#count=20&query=+";
            _PostData = "givenname:" + drTarg.FirstName + "~ +surname:" + drTarg.LastName + "~ +death_place:Illinois~ +death_year:" + sYear + "-" + sYear;
            // _Url = "https://www.familysearch.org/search/index/record-search";
            // _PostData = "searchType=records&filtered=false&fed=true&collectionId=&collectionName=&givenname=" + drTarg.FirstName + "&surname=" + drTarg.LastName;
            // System.Net.Security.RemoteCertificateValidationCallback ServerCertificateValidationCallback = delegate { return true; };
        }
 /// <summary>
 /// Create a new Denni Hlasatel death index record by copying an existing, generic death record
 /// </summary>
 /// <param name="drSource">the existing death record to copy</param>
 /// <returns>A Denni Hlasatel death index record containing the supported vital statistics from <paramref name="drSource"/></returns>
 public static DenniHlasatelDeathRecord Create(IDeathRecord drSource)
 {
     var drNew = new DenniHlasatelDeathRecord();
     Initialize(drSource, drNew);
     return drNew;
 }
 /// <summary>
 /// Copies pertinent fields from a generic death record to a Denni Hlasatel death index record
 /// </summary>
 /// <param name="drSource">the (generic) death record to copy</param>
 /// <param name="drTarg">the Denni Hlasatel death index record <paramref name="drSource"/> is to be copied into</param>
 /// <remarks>This method copies only the <see cref="FilingDate"/>, <see cref="FirstName"/>, <see cref="MiddleName"/> and <see cref="LastName"/> properties.
 /// These are all that are supported by records in the Denni Hlasatel death index database.</remarks>
 private static void Initialize(IDeathRecord drSource, IDeathRecord drTarg)
 {
     // The commented-out properties simply don't exist in the Denni Hlasatel index
     //drTarg.AgeInYears = drSource.AgeInYears;
     //drTarg.CertificateNumber = drSource.CertificateNumber;
     //drTarg.City = drSource.City;
     //drTarg.County = drSource.County;
     //drTarg.DeathDate = drSource.DeathDate;
     drTarg.FilingDate = drSource.FilingDate;
     drTarg.FirstName = drSource.FirstName;
     //drTarg.Gender = drSource.Gender;
     drTarg.LastName = drSource.LastName;
     drTarg.MiddleName = drSource.MiddleName;
     //drTarg.PageNumber = drSource.PageNumber;
     //drTarg.Race = drSource.Race;
     //drTarg.Volume = drSource.Volume;
 }
 /// <summary>
 /// Constructs a list of all Denni Hlasatel death index records
 /// in a queryable table, that match a specified pattern
 /// </summary>
 /// <param name="lIndices">the table whose records are to be searched</param>
 /// <param name="drMatch">a death record containing the <see cref="FirstName"/> and <see cref="LastName"/> to be matched</param>
 /// <param name="dtStart">the earliest date of any matching death record</param>
 /// <param name="dtEnd">the latest date of any matching death record</param>
 /// <returns>a list of matching death records</returns>
 public static List<IDeathRecord> Matches( IQueryable<DenniHlasatelDeathRecord> lIndices, IDeathRecord drMatch, DateTime dtStart, DateTime dtEnd )
 {
     return (from c in lIndices
         where (string.IsNullOrEmpty(drMatch.FirstName) || (c.GivenName.Contains(drMatch.FirstName))) &&
               (string.IsNullOrEmpty(drMatch.LastName) || (c.Surname.Contains(drMatch.LastName))) &&
               ((c.ReportDate >= dtStart) && (c.ReportDate <= dtEnd))
         select (c as IDeathRecord)).ToList();
 }
 /// <summary>
 /// Constructs a list of all Denni Hlasatel death index records,
 /// in an enumerable list, that match a specified pattern
 /// </summary>
 /// <param name="lIndices">the database table to search</param>
 /// <param name="drMatch">a death record containing properties to be matches</param>
 /// <param name="filter">the filter function that tests each record in the table against the matching record <paramref name="drMatch"/></param>
 /// <returns>a list of matching death records</returns>
 public static List<IDeathRecord> Matches( IEnumerable<DenniHlasatelDeathRecord> lIndices, IDeathRecord drMatch, Func<IDeathRecord, IDeathRecord, bool> filter)
 {
     return (from c in lIndices
         where filter(c, drMatch)
         select (c as IDeathRecord)).ToList();
 }
        /// <summary>
        /// Tests a death record for a match to a specified name / filing date pattern.
        /// </summary>
        /// <param name="drQuery">the death record to test for a possible match</param>
        /// <param name="drMatch">a death record containing the fields to be matched (null or empty fields are interpreted as "matches any")</param>
        /// <returns><code>true</code> if <paramref name="drQuery"/> matches the pattern <paramref name="drMatch"/>, otherwise <code>false</code></returns>
        /// <remarks>This method tests only the <see cref="FilingDate"/>, <see cref="FirstName"/> and <see cref="LastName"/> properties for equality.
        /// Name properties that are empty or <code>null</code> in <paramref name="drMatch"/> are treated as "matches any" wildcards.
        /// A reporting date of <see cref="DateTime.MinValue"/> is also treated as a "matches any" wildcard.</remarks>
        public static bool DefaultFilter( IDeathRecord drQuery, IDeathRecord drMatch )
        {
            bool bMatchSurname = true, bMatchGivenName = true, bMatchDate = true;

            if (!string.IsNullOrEmpty(drMatch.LastName))
                bMatchSurname = drQuery.LastName == drMatch.LastName;
            if (!string.IsNullOrEmpty(drMatch.FirstName))
                bMatchGivenName = drQuery.FirstName == drMatch.FirstName;
            if (drMatch.FilingDate > DateTime.MinValue)
                bMatchDate = drQuery.FilingDate == drMatch.FilingDate;

            return bMatchDate && bMatchGivenName && bMatchSurname;
        }
 /// <summary>
 /// Match the full name (first and last) and death date of two death records
 /// </summary>
 /// <param name="dr1">the first of the two death records to compare</param>
 /// <param name="dr2">the second of the two death records to compare</param>
 /// <returns>true if the first name, last name and death date/time of the two records match exactly, otherwise false</returns>
 public static bool MatchNameAndDate(IDeathRecord dr1, IDeathRecord dr2)
 {
     return (dr1.FirstName == dr2.FirstName) &&
         (dr1.LastName == dr2.LastName) &&
         (dr1.DeathDate.Date == dr2.DeathDate.Date);
 }
 public void DisplayRecord(IDeathRecord drTarg, bool bClearBeforeDisplaying = true)
 {
     DisplayRecords(new List<IDeathRecord>(new[] { drTarg }), bClearBeforeDisplaying);
 }
 /// <summary>
 /// Copy one death record to another
 /// </summary>
 /// <param name="drSource">the death record to copy</param>
 /// <param name="drTarg">the copy of the original death record <paramref name="drSource"/></param>
 private static void Initialize( IDeathRecord drSource, IDeathRecord drTarg )
 {
     drTarg.AgeInYears = drSource.AgeInYears;
     drTarg.CertificateNumber = drSource.CertificateNumber;
     drTarg.City = drSource.City;
     drTarg.County = drSource.County;
     drTarg.DeathDate = drSource.DeathDate;
     drTarg.FilingDate = drSource.FilingDate;
     drTarg.FirstName = drSource.FirstName;
     drTarg.Gender = drSource.Gender;
     drTarg.LastName = drSource.LastName;
     drTarg.MiddleName = drSource.MiddleName;
     drTarg.PageNumber = drSource.PageNumber;
     drTarg.Race = drSource.Race;
     drTarg.Volume = drSource.Volume;
 }