private void Run(DbmMode modeCur)
        {
            if (_patNum < 1)
            {
                MsgBox.Show(this, "Select a patient first.");
                return;
            }
            Cursor = Cursors.WaitCursor;
            //Clear out the result column for all rows before every "run"
            for (int i = 0; i < gridMain.Rows.Count; i++)
            {
                gridMain.Rows[i].Cells[2].Text = "";              //Don't use UpdateResultTextForRow here because users will see the rows clearing out one by one.
            }
            bool          verbose = checkShow.Checked;
            StringBuilder logText = new StringBuilder();
            //Create a thread that will show a window and then stay open until the closing phrase is thrown from this form.
            Action actionCloseCheckTableProgress    = ODProgressOld.ShowProgressStatus("CheckTableProgress", this);
            ODTuple <string, bool> tableCheckResult = DatabaseMaintenances.MySQLTables(verbose, modeCur);

            actionCloseCheckTableProgress();
            logText.Append(tableCheckResult.Item1);
            //No database maintenance methods should be run unless this passes.
            if (!tableCheckResult.Item2)
            {
                Cursor = Cursors.Default;
                MsgBoxCopyPaste msgBoxCP = new MsgBoxCopyPaste(tableCheckResult.Item1); //the Tuples result is already translated.
                msgBoxCP.Show();                                                        //Let this window be non-modal so that they can keep it open while they fix their problems.
                return;
            }
            if (gridMain.SelectedIndices.Length < 1)
            {
                //No rows are selected so the user wants to run all checks.
                gridMain.SetSelected(true);
            }
            string result;

            int[] selectedIndices = gridMain.SelectedIndices;
            for (int i = 0; i < selectedIndices.Length; i++)
            {
                long          userNum          = 0;
                DbmMethodAttr methodAttributes = (DbmMethodAttr)Attribute.GetCustomAttribute(_listDbmMethodsGrid[selectedIndices[i]], typeof(DbmMethodAttr));
                //We always send verbose and modeCur into all DBM methods.
                List <object> parameters = new List <object>()
                {
                    verbose, modeCur
                };
                //There are optional paramaters available to some methods and adding them in the following order is very important.
                if (methodAttributes.HasUserNum)
                {
                    parameters.Add(userNum);
                }
                if (methodAttributes.HasPatNum)
                {
                    parameters.Add(_patNum);
                }
                gridMain.ScrollToIndexBottom(selectedIndices[i]);
                UpdateResultTextForRow(selectedIndices[i], Lan.g("FormDatabaseMaintenance", "Running") + "...");
                try {
                    result = (string)_listDbmMethodsGrid[selectedIndices[i]].Invoke(null, parameters.ToArray());
                    if (modeCur == DbmMode.Fix)
                    {
                        DatabaseMaintenances.UpdateDateLastRun(_listDbmMethodsGrid[selectedIndices[i]].Name);
                    }
                }
                catch (Exception ex) {
                    if (ex.InnerException != null)
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();                        //This preserves the stack trace of the InnerException.
                    }
                    throw;
                }
                string status = "";
                if (result == "")               //Only possible if running a check / fix in non-verbose mode and nothing happened or needs to happen.
                {
                    status = Lan.g("FormDatabaseMaintenance", "Done.  No maintenance needed.");
                }
                UpdateResultTextForRow(selectedIndices[i], result + status);
                logText.Append(result);
            }
            gridMain.SetSelected(selectedIndices, true);           //Reselect all rows that were originally selected.
            try {
                DatabaseMaintenances.SaveLogToFile(logText.ToString());
            }
            catch (Exception ex) {
                Cursor = Cursors.Default;
                MessageBox.Show(ex.Message);
            }
            Cursor = Cursors.Default;
            if (modeCur == DbmMode.Fix)
            {
                //_isCacheInvalid=true;//Flag cache to be invalidated on closing.  Some DBM fixes alter cached tables.
            }
        }
        private void Run(ODGrid gridCur, DbmMode modeCur)
        {
            if (_patNum < 1)
            {
                MsgBox.Show(this, "Select a patient first.");
                return;
            }
            Cursor = Cursors.WaitCursor;
            //Clear out the result column for all rows before every "run"
            for (int i = 0; i < gridCur.ListGridRows.Count; i++)
            {
                //gridMain and gridOld have a different number of columns, but their matching columns will be named the same.
                gridCur.ListGridRows[i].Cells[gridCur.ListGridColumns.GetIndex(RESULTS_COLUMN_NAME)].Text = "";              //Don't use UpdateResultTextForRow here because users will see the rows clearing out one by one.
            }
            bool          verbose = checkShow.Checked;
            StringBuilder logText = new StringBuilder();

            //No longer uses a pre-check for tables.
            if (gridCur.SelectedIndices.Length < 1)
            {
                //No rows are selected so the user wants to run all checks.
                gridCur.SetSelected(true);
            }
            string result;

            int[] selectedIndices = gridCur.SelectedIndices;
            for (int i = 0; i < gridCur.SelectedGridRows.Count; i++)
            {
                DbmMethodAttr methodAttributes = (DbmMethodAttr)Attribute.GetCustomAttribute((MethodInfo)gridCur.SelectedGridRows[i].Tag, typeof(DbmMethodAttr));
                //We always send verbose and modeCur into all DBM methods.
                List <object> parameters = new List <object>()
                {
                    verbose, modeCur
                };
                //There are optional paramaters available to some methods and adding them in the following order is very important.
                if (methodAttributes.HasPatNum)
                {
                    parameters.Add(_patNum);
                }

                try {
                    gridCur.ScrollToIndexBottom(i);
                    UpdateResultTextForRow(i, Lan.g("FormDatabaseMaintenance", "Running") + "...", gridCur);
                    gridCur.SetSelected(selectedIndices, true);                   //Reselect all rows that were originally selected.
                    result = (string)((MethodInfo)gridCur.SelectedGridRows[i].Tag).Invoke(null, parameters.ToArray());
                    if (modeCur == DbmMode.Fix)
                    {
                        DatabaseMaintenances.UpdateDateLastRun(((MethodInfo)gridCur.SelectedGridRows[i].Tag).Name);
                    }
                }
                catch (Exception ex) {
                    if (ex.InnerException != null)
                    {
                        ExceptionDispatchInfo.Capture(ex.InnerException).Throw();                        //This preserves the stack trace of the InnerException.
                    }
                    throw;
                }
                string status = "";
                if (result == "")               //Only possible if running a check / fix in non-verbose mode and nothing happened or needs to happen.
                {
                    status = Lan.g("FormDatabaseMaintenance", "Done.  No maintenance needed.");
                }
                UpdateResultTextForRow(i, result + status, gridCur);
                logText.Append(result);
            }
            gridCur.SetSelected(selectedIndices, true);           //Reselect all rows that were originally selected.
            SaveLogToFile(logText.ToString());
            if (modeCur == DbmMode.Fix)
            {
                //_isCacheInvalid=true;//Flag cache to be invalidated on closing.  Some DBM fixes alter cached tables.
            }
        }