/// <summary>
        /// Capture the click event for the solve button. This button will run the solution method for the
        /// selected problem.
        /// </summary>
        /// <param name="sender">Built-in parameter.</param>
        /// <param name="e">Built-in parameter.</param>
        private void buttonSolve_Click(object sender, EventArgs e)
        {
            // Gather the input file string if necessary
            ProjectEulerProblem myProblem = this.MyCurrentProblem();
            string inputFile = null;

            if (myProblem.RequiresInputFile)
            {
                inputFile = this.linkLabelInput.Text;
                if (inputFile.Equals(InitialFileString))
                {
                    inputFile = null;
                }
            }

            // Run the solution algorithm
            double timeToSolve;
            string sol = myProblem.RunSolution(out timeToSolve, inputFile);

            // Display solution
            if (sol == null)
            {
                this.labelSolution.Text    = InitialSolutionString;
                this.labelTimeElapsed.Text = InitialSolutionString;
            }
            else
            {
                this.labelSolution.Text    = sol;
                this.labelTimeElapsed.Text = timeToSolve.ToString();
            }
        }
        /// <summary>
        /// Capture the selected index change event for the problem combobox. This will update the display
        /// for controls below the combobox.
        /// </summary>
        /// <param name="sender">Built-in parameter.</param>
        /// <param name="e">Built-in parameter.</param>
        private void comboBoxProblem_SelectedIndexChanged(object sender, EventArgs e)
        {
            ProjectEulerProblem myProblem = this.MyCurrentProblem();

            // Show/hide input file controls
            bool showInput = myProblem.RequiresInputFile;

            this.linkLabelInput.Visible   = showInput;
            this.labelStaticInput.Visible = showInput;
            this.buttonInputFile.Visible  = showInput;

            this.linkLabelHyperlink.Text = myProblem.Hyperlink(); // Update hyperlink

            // Update solution controls
            this.labelSolution.Text    = InitialSolutionString;
            this.labelTimeElapsed.Text = InitialSolutionString;
        }
        /// <summary>
        /// Capture the click event for the select input file button. This button allows the user to select
        /// a new text file to be used as the input file for the selected problem.
        /// </summary>
        /// <param name="sender">Built-in parameter.</param>
        /// <param name="e">Built-in parameter.</param>
        private void buttonInputFile_Click(object sender, EventArgs e)
        {
            ProjectEulerProblem myProblem = this.MyCurrentProblem();

            if (myProblem.RequiresInputFile) // Need user to select a file
            {
                // Set open file dialog properties
                OpenFileDialog myOpenFileDialog = new OpenFileDialog();
                if (this.linkLabelInput.Enabled) // already have a file selected so start there
                {
                    myOpenFileDialog.InitialDirectory = Path.GetDirectoryName(this.linkLabelInput.Text);
                }
                myOpenFileDialog.Filter      = "Text Files|*.txt"; // All inputs are text files
                myOpenFileDialog.Multiselect = false;
                myOpenFileDialog.Title       = "Select Problem " + myProblem.ProblemNumber + " Input File";

                // Show the dialog and check if user clicked OK.
                if (myOpenFileDialog.ShowDialog() == DialogResult.OK)
                {
                    this.linkLabelInput.Text    = myOpenFileDialog.FileName;
                    this.linkLabelInput.Enabled = true; // Allow hyperlink
                }
            }
        }
        /// <summary>
        /// Capture the click event for the file output button. This button exports the current solution to a .csv file.
        /// </summary>
        /// <param name="sender">Built-in parameter.</param>
        /// <param name="e">Built-in parameter.</param>
        private void buttonOutputFile_Click(object sender, EventArgs e)
        {
            // Set file dialog properties
            OpenFileDialog myOpenFileDialog = new OpenFileDialog();

            myOpenFileDialog.Filter      = "Comma-Separated Values Files|*.csv"; // Only write CSV
            myOpenFileDialog.Title       = "Select Output File";
            myOpenFileDialog.Multiselect = false;

            // Show the dialog and check if user clicked OK.
            if (myOpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                // Determine whether to append or overwrite
                bool append = false;
                if (File.Exists(myOpenFileDialog.FileName))
                {
                    DialogResult result = MessageBox.Show("Append to existing file contents? (Otherwise, file contents will be overwritten.)",
                                                          "File Append", MessageBoxButtons.YesNoCancel);
                    if (result == DialogResult.Yes)
                    {
                        append = true;
                    }
                    else if (result == DialogResult.No)
                    {
                        append = false;
                    }
                    else
                    {
                        return; // Early return
                    }
                }
                else
                {
                    append = false;
                }

                // Write problem information to file
                ProjectEulerProblem myProblem = this.MyCurrentProblem();
                List <string>       lines     = new List <string>();
                if (!append) // Write headers
                {
                    lines.Add(string.Join(",", "Full Description", "Number", "Title", "Link",
                                          "Solution", "Time To Solve"));
                }
                lines.Add(string.Join(",", myProblem.ToString(), myProblem.ProblemNumber, myProblem.Title,
                                      this.linkLabelHyperlink.Text, this.labelSolution.Text, this.labelTimeElapsed.Text));
                try
                {
                    if (append)
                    {
                        File.AppendAllLines(myOpenFileDialog.FileName, lines);
                    }
                    else
                    {
                        File.WriteAllLines(myOpenFileDialog.FileName, lines);
                    }
                }
                catch // catch any IO exception - could make more specific in future iterations
                {
                    MessageBox.Show("Unexpected error writing to file. Check file permissions and try again.", "Unexpected Error",
                                    MessageBoxButtons.OK);
                }
            }
        }