/// <summary>
        /// Get all the leads from the database and do stuff with them.  That doesn't sound very good does it.
        /// </summary>
        /// <param name="testLead">(Optional) A test lead to send to rather than DB leads.</param>
        /// <remarks>
        /// This should probably go in ApplicationManager with callbacks and stuff for logging.  Todo.
        /// </remarks>
        private void ProcessNewDatabaseLeads(Lead testLead)
        {
            const string genericTeamName        = "WARRIORS";
            const string defaultTemplateDesc1   = "Football";
            const string defaultTemplateDesc2   = "Baseball";
            const int    customJersyImageWidth  = 150;
            const string imagesSubdir           = "images";
            const string commonSubdir           = "common";
            const string tempSubdir             = "temp";
            const int    maxNumLeadsCommonSense = 5;
            int          sendRetries            = 0;

            //
            // Debugging mode doesn't send emails to leads, but it sends them to a test account.
            //
            bool debugging = _settings.DebuggingMode;

            Log("Processing new leads in db, debugging mode: {0}...", debugging);

            string errMsg          = string.Empty;
            string outputEmailFile = Functions.BuildFilenameFromElements(_settings.EmailSrcDir, "output-temp.htm");
            //
            // Read header row, then read the row we want.
            //
            StreamReader reader            = File.OpenText(Functions.BuildFilenameFromElements(_settings.EmailSrcDir, string.Format("lead-email-{0}.htm", _settings.EmailTemplateNo)));
            string       emailTemplateOrig = reader.ReadToEnd();

            reader.Close();


            //  The mailman object is used for sending and receiving email.
            Chilkat.MailMan mailman = new Chilkat.MailMan();

            // The MHT component can be used to convert an HTML page
            // from a URL, file, or in-memory HTML into an email
            // with embedded images and style sheets.
            Chilkat.Mht mht = new Chilkat.Mht();


            //  Any string argument automatically begins the 30-day trial.
            bool success;

            // success = mailman.UnlockComponent(Config.ChilkatUnlockCodeEmail);
            success = mailman.UnlockComponent(ChilkatRegCodes.ChilkatEmail);
            if (success != true)
            {
                Log("Component unlock failed");
                return;
            }

            // success = mht.UnlockComponent(Config.ChilkatUnlockCodeEmail);
            success = mht.UnlockComponent(ChilkatRegCodes.ChilkatMHT);
            if (success != true)
            {
                Log("Mht component unlock failed");
                return;
            }

            //  Set the SMTP server.
            mailman.SmtpHost = Config.LeadMailboxServer;

            //  Set the SMTP login/password (if required)
            mailman.SmtpUsername = Config.LeadMailboxLoginUID;
            mailman.SmtpPassword = Config.LeadMailboxLoginPW;

            //
            // Set up parameters to append to all the email links so Google Analytics can track the clicks for us.
            //
            Campaign campaign = new Campaign();

            // Todo: grab this from the db & config file
            campaign.Source  = "fundraisingweb";
            campaign.Medium  = (debugging || testLead != null) ? "testing" : "email";
            campaign.Content = _settings.EmailTemplateNo;


            List <Lead> leads;

            if (testLead == null)
            {
                Log("Getting leads from db...");
                leads = DataManager.GetNewFundraisingLeads();
            }
            else
            {
                leads = new List <Lead>();
                leads.Add(testLead);
            }

            if (leads.Count > maxNumLeadsCommonSense)
            {
                string msg = string.Format("An unusually high amount of leads were returned from the db ({0}), do you wish to send emails anyway?", leads.Count);
                if (MessageBox.Show(msg, "Sanity Check", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    // Close the program
                    btnClose_Click(null, null);
                }
            }

            foreach (Lead lead in leads)
            {
                Log("Processing lead: {0}", lead);

                if (!_doingProcessing && testLead == null)
                {
                    //
                    // We were signalled to stop processing
                    //
                    Log("User signalled to quit, exiting...");
                    return;
                }

                string emailTemplate = emailTemplateOrig;

                //Lead lead = leads[0];
                // ApplicationManager.SetFundraisingIdeasProperties(lead);

                // const int totalNumberOfTemplates = 5;

                // string templateDescShort = Functions.FirstNonemptyString(lead.TemplateDescShort, "Football");

                //
                // Otherwise, make it 1 so that we put in two different template graphics.
                //
                // int altTemplate = lead.TemplateDescShort == string.Empty ? 1 : 0;
                string customName;

                if (!Functions.IsEmptyString(lead.LastName) && lead.LastName.Length <= 13)
                {
                    customName = lead.LastName;
                }
                else if (!Functions.IsEmptyString(lead.FirstName) && lead.LastName.Length <= 13)
                {
                    customName = lead.FirstName;
                }
                else
                {
                    customName = "anyname";
                }

                customName = customName.ToUpper();

                string customNumber = string.Format("{0:yy}", DateTime.Now);

                Template template1 = lead.TemplateCurrent;
                Template template2 = lead.TemplateCurrent;

                // If we have a specific template specified, use them both.  Otherwise, use the default and another one.
                if (template1 == null)
                {
                    template1 = DataManager.GetTemplate(defaultTemplateDesc1);
                    // template2 = DataManager.GetTemplate(((template1.TemplateId + 1) % totalNumberOfTemplates + 1) + 1);
                    template2 = DataManager.GetTemplate(defaultTemplateDesc2);
                }

                //Template template1 = DataManager.GetTemplate(templateDescShort);
                //Template template2 = DataManager.GetTemplate((template1.TemplateId + altTemplate) % totalNumberOfTemplates);

                PlayerSeason example1 = new PlayerSeason(customName, customNumber);
                PlayerSeason example2 = new PlayerSeason(genericTeamName, customNumber);

                example1.TemplateCurrent = template1;
                example2.TemplateCurrent = template2;

                string example1File  = string.Format("{0}_{1:000}_{2}_{3}.jpg", template1.TemplateDescShort, template1.TemplateId, customName, customNumber);
                string example1FPath = Functions.BuildFilenameFromElements(
                    _settings.EmailSrcDir,
                    imagesSubdir,
                    tempSubdir,
                    example1File);

                string example2File  = string.Format("{0}_{1:000}_{2}_{3}.jpg", template2.TemplateDescShort, template2.TemplateId, genericTeamName, customNumber);
                string example2FPath = Functions.BuildFilenameFromElements(
                    _settings.EmailSrcDir,
                    imagesSubdir,
                    commonSubdir,
                    example2File);

                Log("Creating image: {0}", example1File);
                ApplicationManager.WritePlayerMarketingGIFFile(example1, customJersyImageWidth, example1FPath, debugging);

                Log("Creating image: {0}", example2File);
                ApplicationManager.WritePlayerMarketingGIFFile(example2, customJersyImageWidth, example2FPath, debugging);

                //
                // Personalize the email.
                //
                Dictionary <string, string> replacements = new Dictionary <string, string>();

                replacements.Add("[cust_fname]", Functions.TitleCase(Functions.FirstNonemptyString(lead.FirstName.ToLower(), lead.LastName.ToLower(), "Hi future fundraiser")));
                replacements.Add("[current_year_2digit]", customNumber);
                replacements.Add("[homepage_href]", ApplicationManager.BuildWebsiteLink(null, campaign));

                string addtlLi = string.Empty;
                if (lead.IsAthletics)
                {
                    addtlLi = string.Format("<li>Your {0} team!</li>", lead.TemplateCurrent.TemplateDescShort);
                }
                replacements.Add("[perfect_for_addtl_li]", addtlLi);

                replacements.Add("[specific_jersey_href]", ApplicationManager.BuildWebsiteLink(example1, campaign));
                replacements.Add("[alternate_jersey_href]", ApplicationManager.BuildWebsiteLink(example2, campaign));

                replacements.Add("[specific_jersey_image]", Functions.BuildUrlFromElements(imagesSubdir, tempSubdir, example1File));
                replacements.Add("[alternate_jersey_image]", Functions.BuildUrlFromElements(imagesSubdir, commonSubdir, example2File));

                replacements.Add("[homepage_href_fundraisingpage]", ApplicationManager.BuildWebsiteLink(null, campaign, Config.WebsiteFundraisingPage));
                replacements.Add("[unsubscribe_url]", string.Format("mailto:{0}?subject=unsubscribe&body=Your%20stickers%20are%20great%20but%20please%20unsubscribe%20me.", Config.LeadMailboxLoginUID));

                replacements.Add("[how_user_entered_info]", "to the \"Fundraising Ideas\" website");

                //
                // Validate the row, all these fields must be there or we're wasting our time.
                //
                foreach (KeyValuePair <string, string> replacement in replacements)
                {
                    if (!emailTemplate.Contains(replacement.Key))
                    {
                        errMsg = string.Format("Cannot find required value in output file: \"{0}\"", replacement.Key);
                        throw new ApplicationException(errMsg);

                        //
                        // Do something with the error here.
                        //
                    }
                    else
                    {
                        emailTemplate = emailTemplate.Replace(replacement.Key, replacement.Value);
                    }
                }

                MatchCollection leftovers1 = Regex.Matches(emailTemplate, "(\\[.*\\])");

                if (leftovers1.Count > 0)
                {
                    string msg = "You need to implement the following tokens:\r\n\r\n";

                    foreach (Match token in leftovers1)
                    {
                        msg = Functions.BuildStringFromElementsWithDelimiter(msg, token.Groups[0].ToString(), "\r\n");
                    }

                    MessageBox.Show(msg, "Fix These", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    return;
                }

                string emailSubject = Functions.GetValueFromText(emailTemplate, "<title>(.*)</title>");


                Functions.WriteStringAsFile(emailTemplate, outputEmailFile);

                Log("Done creating email, now gonna email it.");

                //  Create a new email object
                Chilkat.Email email = new Chilkat.Email();

                // Embed the images in the email - Outlook friendly.
                mht.UseCids = true;

                // Create an email from an HTML file.
                email = mht.GetEmail(outputEmailFile);
                if (email == null)
                {
                    MessageBox.Show(mht.LastErrorText);
                    return;
                }

                email.Subject = emailSubject;
                // email.Body = "This is a test";
                email.From    = string.Format("Fan Favorite Designs <{0}>", Config.LeadMailboxLoginUID);
                email.ReplyTo = Config.LeadMailboxLoginUID;

                if (debugging)
                {
                    email.AddTo("Lead Monitor", "*****@*****.**");
                }
                else
                {
                    email.AddTo(lead.BuildFullName(), lead.EmailAddress);
                    // email.AddBcc("Lead Monitor", "*****@*****.**");
                }

                Chilkat.HtmlToText h2t = new Chilkat.HtmlToText();
                // success = h2t.UnlockComponent(Config.ChilkatUnlockCodeEmail);
                success = h2t.UnlockComponent(ChilkatRegCodes.ChilkatHTMLtoXML);
                if (success != true)
                {
                    MessageBox.Show(h2t.LastErrorText);
                    return;
                }

                //  Get the email's HTML body.
                string html;
                html = email.GetHtmlBody();

                //  Convert it to plain text:
                string plainText;
                plainText = h2t.ToText(html);

                // Add a few things so the email makes sense.
                plainText = string.Format("This email was meant to be viewed in HTML mode.  You can visit \r\nour website here to get a better look at our product.\r\n\r\n    {0}\r\n{1}", ApplicationManager.BuildWebsiteLink(null, campaign), plainText);

                //  Add a plain-text alternative to the email:
                email.AddPlainTextAlternativeBody(plainText);

                //  Call SendEmail to connect to the SMTP server and send.
                //  The connection (i.e. session) to the SMTP server remains
                //  open so that subsequent SendEmail calls may use the
                //  same connection.
                Log("Sending SMTP mail...");
                success = mailman.SendEmail(email);
                if (success != true)
                {
                    sendRetries++;

                    if (sendRetries < 5)
                    {
                        Log("Can't send email, gonna hang out for a bit, and try again.");
                        Thread.Sleep(20000);
                    }
                    else
                    {
                        throw new ApplicationException("Cannot send email - cannot continue.");
                    }
                }
                else if (!debugging && testLead == null)
                {
                    //
                    // Update the DB indicating that we sent the email so we don't do it again.
                    //
                    bool res = DataManager.AddLeadStatusLog(lead, Lead.LeadStatusCode.lscEmailSent, string.Format("lead-email-{0}.htm", _settings.EmailTemplateNo));

                    if (res)
                    {
                        Log("Updated status log - all good.");
                    }
                    else
                    {
                        Log("Yikes, can't update status log that we emailed!  Bombing out.");
                        throw new ApplicationException("Cannot update status log - cannot continue.");
                    }
                    sendRetries = 0;
                }
                else
                {
                    Log("Email success; debug mode - not updating DB");
                    sendRetries = 0;
                }

                //  Some SMTP servers do not actually send the email until
                //  the connection is closed.  In these cases, it is necessary to
                //  call CloseSmtpConnection for the mail to be  sent.
                //  Most SMTP servers send the email immediately, and it is
                //  not required to close the connection.  We'll close it here
                //  for the example:
                success = mailman.CloseSmtpConnection();
                if (success != true)
                {
                    Log("Connection to SMTP server not closed cleanly.");
                    throw new ApplicationException("Cannot disconnect from SMTP server cleanly - cannot continue.");
                }
            }

            Log("Cleaning up temp files, if any.");
            string tempDirPath = Functions.BuildFilenameFromElements(
                _settings.EmailSrcDir,
                imagesSubdir,
                tempSubdir);

            string[] tempFiles = Directory.GetFiles(tempDirPath);
            foreach (string file in tempFiles)
            {
                File.Delete(file);
            }

            // todo: add icon to exe

            // todo: buy chilkat components

            Log("Processing of db leads completed");
        }