public void OpenDatabase(string path)
        {
            if (!File.Exists(path))
            {
                MessageDlg.Show(this, String.Format(Resources.EditIonMobilityLibraryDlg_OpenDatabase_The_file__0__does_not_exist__Click_the_Create_button_to_create_a_new_ion_mobility_library_or_click_the_Open_button_to_find_the_missing_file_,
                                                    path));
                return;
            }

            try
            {
                IonMobilityDb db         = IonMobilityDb.GetIonMobilityDb(path, null); // TODO: (copied from iRT code) LongWaitDlg
                var           dbPeptides = db.GetPeptides().ToArray();

                LoadLibrary(dbPeptides);

                // Clone all of the peptides to use for comparison in OkDialog
                _originalPeptides = dbPeptides.Select(p => new ValidatingIonMobilityPeptide(p.Sequence, p.CollisionalCrossSection, p.HighEnergyDriftTimeOffsetMsec)).ToArray();

                textDatabase.Text = path;
            }
            catch (DatabaseOpeningException e)
            {
                MessageDlg.ShowException(this, e);
            }
        }
        /// <summary>
        /// Test various error conditions in IonMobilityDb.cs
        /// </summary>
        public void TestGetIonMobilityDBErrorHandling(TestFilesDir testFilesDir)
        {
            AssertEx.ThrowsException <DatabaseOpeningException>(() => IonMobilityDb.GetIonMobilityDb(null, null),
                                                                Resources.IonMobilityDb_GetIonMobilityDb_Please_provide_a_path_to_an_existing_ion_mobility_library_);

            const string badfilename = "nonexistent_file.imdb";

            AssertEx.ThrowsException <DatabaseOpeningException>(
                () => IonMobilityDb.GetIonMobilityDb(badfilename, null),
                String.Format(
                    Resources.IonMobilityDb_GetIonMobilityDb_The_ion_mobility_library_file__0__could_not_be_found__Perhaps_you_did_not_have_sufficient_privileges_to_create_it_,
                    badfilename));

            string bogusfile = testFilesDir.GetTestPath("bogus.imdb");

            using (FileStream fs = File.Create(bogusfile))
            {
                Byte[] info = new UTF8Encoding(true).GetBytes("This is a bogus file.");
                fs.Write(info, 0, info.Length);
            }
            AssertEx.ThrowsException <DatabaseOpeningException>(
                () => IonMobilityDb.GetIonMobilityDb(bogusfile, null),
                String.Format(
                    Resources.IonMobilityDb_GetIonMobilityDb_The_file__0__is_not_a_valid_ion_mobility_library_file_,
                    bogusfile));
        }
        public void OkDialog()
        {
            if (string.IsNullOrEmpty(textLibraryName.Text))
            {
                MessageDlg.Show(this, Resources.EditIonMobilityLibraryDlg_OkDialog_Please_enter_a_name_for_the_ion_mobility_library_);
                textLibraryName.Focus();
                return;
            }

            if (_existingLibs != null)
            {
                foreach (var existingLib in _existingLibs)
                {
                    if (Equals(existingLib.Name, textLibraryName.Text) && !Equals(existingLib.Name, _editingName))
                    {
                        if (MessageBox.Show(this, string.Format(Resources.EditIonMobilityLibraryDlg_OkDialog_An_ion_mobility_library_with_the_name__0__already_exists__Do_you_want_to_overwrite_it_,
                                                                textLibraryName.Text),
                                            Program.Name, MessageBoxButtons.YesNo) != DialogResult.Yes)
                        {
                            textLibraryName.Focus();
                            return;
                        }
                    }
                }
            }

            string message;

            if (string.IsNullOrEmpty(textDatabase.Text))
            {
                message = TextUtil.LineSeparate(Resources.EditIonMobilityLibraryDlg_OkDialog_Please_choose_a_file_for_the_ion_mobility_library,
                                                Resources.EditIonMobilityLibraryDlg_OkDialog_Click_the_Create_button_to_create_a_new_library_or_the_Open_button_to_open_an_existing_library_file_);
                MessageDlg.Show(this, message);
                textDatabase.Focus();
                return;
            }
            string path = Path.GetFullPath(textDatabase.Text);

            if (!Equals(path, textDatabase.Text))
            {
                message = TextUtil.LineSeparate(Resources.EditIonMobilityLibraryDlg_OkDialog_Please_use_a_full_path_to_a_file_for_the_ion_mobility_library_,
                                                Resources.EditIonMobilityLibraryDlg_OkDialog_Click_the_Create_button_to_create_a_new_library_or_the_Open_button_to_open_an_existing_library_file_);
                MessageDlg.Show(this, message);
                textDatabase.Focus();
                return;
            }
            if (!string.Equals(Path.GetExtension(path), IonMobilityDb.EXT))
            {
                path += IonMobilityDb.EXT;
            }

            // This function MessageBox.Show's error messages
            if (!ValidatePeptideList(LibraryPeptideList, textLibraryName.Text ?? string.Empty))
            {
                gridViewMeasuredPeptides.Focus();
                return;
            }

            try
            {
                var calculator = new IonMobilityLibrary(textLibraryName.Text, path);

                IonMobilityDb db = File.Exists(path)
                               ? IonMobilityDb.GetIonMobilityDb(path, null)
                               : IonMobilityDb.CreateIonMobilityDb(path);

                db = db.UpdatePeptides(LibraryPeptides.ToArray(), _originalPeptides ?? new ValidatingIonMobilityPeptide[0]);

                IonMobilityLibrary = calculator.ChangeDatabase(db);
            }
            catch (DatabaseOpeningException x)
            {
                MessageDlg.Show(this, x.Message);
                textDatabase.Focus();
                return;
            }
            catch (StaleStateException staleStateException)
            {
                // CONSIDER: (copied from iRT code) Not sure if this is the right thing to do.  It would
                //           be nice to solve whatever is causing this, but this is
                //           better than showing an unexpected error form with stack trace.
                MessageDlg.ShowWithException(this, Resources.EditIonMobilityLibraryDlg_OkDialog_Failure_updating_peptides_in_the_ion_mobility_library__The_library_may_be_out_of_synch_, staleStateException);
                return;
            }

            DialogResult = DialogResult.OK;
        }
        protected override void DoTest()
        {
            using (var testFilesDir = new TestFilesDir(TestContext, TestFilesZip))
            {
                const double HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC = -.1;

                // do a few unit tests on the UI error handlers
                TestGetIonMobilityDBErrorHandling(testFilesDir);
                TestImportIonMobilityFromSpectralLibraryErrorHandling();
                TestEditIonMobilityLibraryDlgErrorHandling();
                TestEditDriftTimePredictorDlgErrorHandling();

                // Now exercise the UI

                var goodPeptide = new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC);
                Assert.IsNull(goodPeptide.Validate());
                var badPeptides = new[]
                {
                    new ValidatingIonMobilityPeptide("@#$!", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 0, 0),
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", -133.3210342, -HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                };
                foreach (var badPeptide in badPeptides)
                {
                    Assert.IsNotNull(badPeptide.Validate());
                }

                var ionMobilityPeptides = new[]
                {
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),  // These are made-up values
                    new ValidatingIonMobilityPeptide("SISIVGSYVGNR", 133.3210342, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("CCSDVFNQVVK", 131.2405487, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("CCSDVFNQVVK", 131.2405487, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANELLINVK", 119.2825783, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANELLINVK", 119.2825783, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GVIFYESHGK", 123.7844632, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GVIFYESHGK", 123.7844632, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EKDIVGAVLK", 124.3414249, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EKDIVGAVLK", 124.3414249, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("VVGLSTLPEIYEK", 149.857687, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANGTTVLVGMPAGAK", 144.7461979, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("ANGTTVLVGMPAGAK", 144.7461979, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IGDYAGIK", 102.2694763, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IGDYAGIK", 102.2694763, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GDYAGIK", 91.09155861, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("GDYAGIK", 91.09155861, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("IFYESHGK", 111.2756406, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                    new ValidatingIonMobilityPeptide("EALDFFAR", 110.6867676, HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC),
                };
                List <ValidatingIonMobilityPeptide> minimalSet;
                var message = EditIonMobilityLibraryDlg.ValidateUniqueChargedPeptides(ionMobilityPeptides, out minimalSet); // Check for conflicts, strip out dupes
                Assert.IsNull(message, "known good data set failed import");
                Assert.AreEqual(11, minimalSet.Count, "known good data imported but with wrong result count");

                var save = ionMobilityPeptides[0].CollisionalCrossSection;
                ionMobilityPeptides[0].CollisionalCrossSection += 1.0;                                                  // Same sequence and charge, different cross section
                message = EditIonMobilityLibraryDlg.ValidateUniqueChargedPeptides(ionMobilityPeptides, out minimalSet); // Check for conflicts, strip out dupes
                Assert.IsNotNull(message, message);
                Assert.IsNull(minimalSet, "bad inputs to drift time library paste should be rejected wholesale");
                ionMobilityPeptides[0].CollisionalCrossSection = save; // restore

                // Present the Prediction tab of the peptide settings dialog
                var peptideSettingsDlg1 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));

                // Simulate picking "Add..." from the Ion Mobility Libraries button context menu
                var ionMobilityLibDlg1 = ShowDialog <EditIonMobilityLibraryDlg>(peptideSettingsDlg1.AddIonMobilityLibrary);
                // Simulate user pasting in collisional cross section data to create a new drift time library
                const string testlibName  = "testlib";
                string       databasePath = testFilesDir.GetTestPath(testlibName + IonMobilityDb.EXT);
                RunUI(() =>
                {
                    string libraryText             = BuildPasteLibraryText(ionMobilityPeptides, seq => seq.Substring(0, seq.Length - 1));
                    ionMobilityLibDlg1.LibraryName = testlibName;
                    ionMobilityLibDlg1.CreateDatabase(databasePath);
                    SetClipboardText(libraryText);
                    ionMobilityLibDlg1.DoPasteLibrary();
                    ionMobilityLibDlg1.OkDialog();
                });
                WaitForClosedForm(ionMobilityLibDlg1);
                RunUI(peptideSettingsDlg1.OkDialog);
                WaitForClosedForm(peptideSettingsDlg1);

                // Use that drift time database in a differently named library
                const string testlibName2        = "testlib2";
                var          peptideSettingsDlg2 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate user picking Add... from the Drift Time Predictor combo control
                var driftTimePredictorDlg = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg2.AddDriftTimePredictor);
                // ... and reopening an existing drift time database
                var ionMobility = ShowDialog <EditIonMobilityLibraryDlg>(driftTimePredictorDlg.AddIonMobilityLibrary);
                RunUI(() =>
                {
                    ionMobility.LibraryName = testlibName2;
                    ionMobility.OpenDatabase(databasePath);
                    ionMobility.OkDialog();
                });
                WaitForClosedForm(ionMobility);

                // Set other parameters - name, resolving power, per-charge slope+intercept
                const string predictorName  = "test";
                const double resolvingPower = 123.4;
                RunUI(() =>
                {
                    driftTimePredictorDlg.SetResolvingPower(resolvingPower);
                    driftTimePredictorDlg.SetPredictorName(predictorName);
                    SetClipboardText("1\t2\t3\n2\t4\t5"); // Silly values: z=1 s=2 i=3, z=2 s=4 i=5
                    driftTimePredictorDlg.PasteRegressionValues();
                });
                var olddoc = SkylineWindow.Document;
                RunUI(() =>
                {
                    // Go back to the first library we created
                    driftTimePredictorDlg.ChooseIonMobilityLibrary(testlibName);
                    driftTimePredictorDlg.OkDialog();
                    var docUI = SkylineWindow.DocumentUI;
                    if (docUI != null)
                    {
                        SetUiDocument(docUI.ChangeSettings(docUI.Settings.ChangePeptideSettings(
                                                               docUI.Settings.PeptideSettings.ChangePrediction(
                                                                   docUI.Settings.PeptideSettings.Prediction.ChangeDriftTimePredictor(driftTimePredictorDlg.Predictor)))));
                    }
                });

                WaitForClosedForm(driftTimePredictorDlg);
                RunUI(peptideSettingsDlg2.OkDialog);

                /*
                 * Check that the database was created successfully
                 * Check that it has the correct number peptides
                 */
                IonMobilityDb db = IonMobilityDb.GetIonMobilityDb(databasePath, null);
                Assert.AreEqual(11, db.GetPeptides().Count());
                WaitForDocumentChange(olddoc);

                // Check serialization and background loader
                WaitForDocumentLoaded();
                RunUI(() =>
                {
                    SkylineWindow.SaveDocument(TestContext.GetTestPath("test.sky"));
                    SkylineWindow.NewDocument();
                    SkylineWindow.OpenFile(TestContext.GetTestPath("test.sky"));
                });

                var doc = WaitForDocumentLoaded();

                // Verify that the schema has been updated to include these new settings
                AssertEx.ValidatesAgainstSchema(doc);

                // Do some DT calculations
                double        windowDT;
                DriftTimeInfo centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANELLINV", 2), null, out windowDT);
                Assert.AreEqual((4 * (119.2825783)) + 5, centerDriftTime.DriftTimeMsec(false));
                Assert.AreEqual(2 * ((4 * (119.2825783)) + 5) / resolvingPower, windowDT);
                Assert.AreEqual((4 * (119.2825783)) + 5 + HIGH_ENERGY_DRIFT_TIME_OFFSET_MSEC, centerDriftTime.DriftTimeMsec(true));

                //
                // Test importing collisional cross sections from a spectral lib that has drift times but no high energy offset info
                //
                var          peptideSettingsUI = ShowDialog <PeptideSettingsUI>(SkylineWindow.ShowPeptideSettingsUI);
                const string libname           = "libIMS";
                var          blibPath          = TestContext.GetTestPath("IonMobilityTest\\mse-mobility.filtered-scaled.blib");
                var          editListUI        =
                    ShowDialog <EditListDlg <SettingsListBase <LibrarySpec>, LibrarySpec> >(peptideSettingsUI.EditLibraryList);
                RunDlg <EditLibraryDlg>(editListUI.AddItem, editLibraryDlg =>
                {
                    editLibraryDlg.LibrarySpec = new BiblioSpecLibSpec(libname, blibPath);
                    editLibraryDlg.OkDialog();
                });
                OkDialog(editListUI, editListUI.OkDialog);
                RunUI(() => peptideSettingsUI.PickedLibraries = new[] { libname });

                // Check error cases for resolving power (caused unexpected excption)
                RunUI(() =>
                {
                    peptideSettingsUI.IsUseSpectralLibraryDriftTimes         = true;
                    peptideSettingsUI.SpectralLibraryDriftTimeResolvingPower = null;
                });
                RunDlg <MessageDlg>(peptideSettingsUI.OkDialog, dlg =>
                {
                    AssertEx.AreComparableStrings(Resources.MessageBoxHelper_ValidateDecimalTextBox__0__must_contain_a_decimal_value, dlg.Message);
                    dlg.OkDialog();
                });
                RunUI(() => peptideSettingsUI.SpectralLibraryDriftTimeResolvingPower = 0);
                RunDlg <MessageDlg>(peptideSettingsUI.OkDialog, dlg =>
                {
                    Assert.AreEqual(Resources.EditDriftTimePredictorDlg_ValidateResolvingPower_Resolving_power_must_be_greater_than_0_, dlg.Message);
                    dlg.OkDialog();
                });

                RunUI(() => peptideSettingsUI.IsUseSpectralLibraryDriftTimes = false);

                OkDialog(peptideSettingsUI, peptideSettingsUI.OkDialog);
                WaitForDocumentLoaded(); // Let that library load

                // In this lib: ANGTTVLVGMPAGAK at z=2, with drift time 4.99820623749102
                // and, a single CCS value, for ANELLINVK, which is 3.8612432898618

                // Present the Prediction tab of the peptide settings dialog
                var peptideSettingsDlg3 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Add..." from the Drift Time Predictor combo control
                var          driftTimePredictorDlg3     = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg3.AddDriftTimePredictor);
                const double deadeelsDT                 = 3.456;
                const double deadeelsDTHighEnergyOffset = -0.1;
                var          threeCols = "DEADEELS\t5\t" + deadeelsDT.ToString(CultureInfo.CurrentCulture);
                var          fourCols  = "DEADEELS\t5\t" + deadeelsDT.ToString(CultureInfo.CurrentCulture) + "\t" +
                                         deadeelsDTHighEnergyOffset.ToString(CultureInfo.CurrentCulture);
                RunUI(() =>
                {
                    driftTimePredictorDlg3.SetResolvingPower(resolvingPower);
                    driftTimePredictorDlg3.SetPredictorName("test3");
                    SetClipboardText("1\t2\t3\n2\t4\t5"); // Silly values: z=1 s=2 i=3, z=2 s=4 i=5
                    driftTimePredictorDlg3.PasteRegressionValues();
                    // Simulate user pasting in some measured drift time info without high energy offset, even though its enabled - should not throw
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(true);
                    SetClipboardText(threeCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                    // Simulate user pasting in some measured drift time info with high energy offset
                    SetClipboardText(fourCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                    // Now turn off the high energy column and paste in four columns - should fail
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(false);
                    SetClipboardText(fourCols);
                });
                // An error will appear because the column count is wrong
                ShowDialog <MessageDlg>(driftTimePredictorDlg3.PasteMeasuredDriftTimes);
                var errorDlg = WaitForOpenForm <MessageDlg>();
                Assert.AreEqual(string.Format(Resources.SettingsUIUtil_DoPasteText_Incorrect_number_of_columns__0__found_on_line__1__, 4, 1), errorDlg.Message);
                errorDlg.OkDialog();
                RunUI(() =>
                {
                    // And now paste in three columns, should be OK
                    SetClipboardText(threeCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();

                    // Finally turn the high energy column back on, and put in a value
                    driftTimePredictorDlg3.SetOffsetHighEnergySpectraCheckbox(true);
                    SetClipboardText(fourCols);
                    driftTimePredictorDlg3.PasteMeasuredDriftTimes();
                });
                // Simulate picking "Add..." from the Ion Mobility Library combo control
                var          ionMobilityLibDlg3 = ShowDialog <EditIonMobilityLibraryDlg>(driftTimePredictorDlg3.AddIonMobilityLibrary);
                const string testlibName3       = "testlib3";
                string       databasePath3      = testFilesDir.GetTestPath(testlibName3 + IonMobilityDb.EXT);
                RunUI(() =>
                {
                    ionMobilityLibDlg3.LibraryName = testlibName3;
                    ionMobilityLibDlg3.CreateDatabase(databasePath3);
                });
                // Simulate pressing "Import" button from the Edit Ion Mobility Library dialog
                var importSpectralLibDlg =
                    ShowDialog <ImportIonMobilityFromSpectralLibraryDlg>(ionMobilityLibDlg3.ImportFromSpectralLibrary);
                RunUI(() =>
                {
                    // Set up to fail - don't provide z=2 info
                    importSpectralLibDlg.Source = SpectralLibrarySource.settings; // Simulate user selecting 1st radio button
                    SetClipboardText("1\t1\t0");                                  // This will fail - no z=2 information
                    importSpectralLibDlg.PasteRegressionValues();
                });
                importSpectralLibDlg.BeginInvoke(new Action(importSpectralLibDlg.OkDialog)); // User clicks OK - we expect an error dialog to follow
                WaitForOpenForm <MessageDlg>().OkDialog();                                   // Dismiss the error message, we'll be dropped back into the dialog
                RunUI(() =>
                {
                    importSpectralLibDlg.Source   = SpectralLibrarySource.file; // Simulate user selecting 2nd radio button
                    importSpectralLibDlg.FilePath = blibPath;                   // Simulate user entering filename
                    SetClipboardText("1\t1\t0\n2\t2\t2");                       // Note non-unity slope and charge for z=2, for test purposes
                    importSpectralLibDlg.PasteRegressionValues();
                    importSpectralLibDlg.OkDialog();
                });
                WaitForClosedForm(importSpectralLibDlg);
                WaitForCondition(() => ionMobilityLibDlg3.LibraryPeptideCount > 8); // Let that library load
                RunUI(ionMobilityLibDlg3.OkDialog);
                WaitForClosedForm(ionMobilityLibDlg3);
                RunUI(driftTimePredictorDlg3.OkDialog);
                WaitForClosedForm(driftTimePredictorDlg3);
                RunUI(peptideSettingsDlg3.OkDialog);
                WaitForClosedForm(peptideSettingsDlg3);
                doc = WaitForDocumentChangeLoaded(doc); // Let that library load

                // Do some DT calculations with this new library
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANELLINVK", 2), null, out windowDT);
                double ccs = 3.8612432898618; // should have imported CCS without any transformation
                Assert.AreEqual((4 * (ccs)) + 5, centerDriftTime.DriftTimeMsec(false) ?? ccs, .000001);
                Assert.AreEqual(2 * ((4 * (ccs)) + 5) / resolvingPower, windowDT, .000001);
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("ANGTTVLVGMPAGAK", 2), null, out windowDT);
                ccs = (4.99820623749102 - 2) / 2; // should have imported CCS as a converted drift time
                Assert.AreEqual((4 * (ccs)) + 5, centerDriftTime.DriftTimeMsec(false) ?? ccs, .000001);
                Assert.AreEqual(2 * ((4 * (ccs)) + 5) / resolvingPower, windowDT, .000001);

                // Do some DT calculations with the measured drift time
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 3), null, out windowDT); // Should fail
                Assert.AreEqual(windowDT, 0);
                Assert.IsFalse(centerDriftTime.DriftTimeMsec(false).HasValue);

                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 5), null, out windowDT);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(false) ?? -1, .000001);
                Assert.AreEqual(deadeelsDT + deadeelsDTHighEnergyOffset, centerDriftTime.DriftTimeMsec(true) ?? -1, .000001);
                Assert.AreEqual(2 * (deadeelsDT / resolvingPower), windowDT, .0001); // Directly measured, should match

                // Now check handling of scenario where user pastes in high energy offsets then unchecks the "Use High Energy Offsets" box
                var peptideSettingsDlg4 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Edit Current..." from the Drift Time Predictor combo control
                var driftTimePredictorDlg4 = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg4.EditDriftTimePredictor);
                RunUI(() =>
                {
                    Assert.IsTrue(driftTimePredictorDlg4.GetOffsetHighEnergySpectraCheckbox()); // Should start out enabled if we have offsets
                    driftTimePredictorDlg4.SetOffsetHighEnergySpectraCheckbox(false);           // Turn off the high energy offset column
                    driftTimePredictorDlg4.SetPredictorName("test4");
                });
                RunUI(driftTimePredictorDlg4.OkDialog);
                WaitForClosedForm(driftTimePredictorDlg4);
                RunUI(peptideSettingsDlg4.OkDialog);
                WaitForClosedForm(peptideSettingsDlg4);
                doc             = WaitForDocumentChangeLoaded(doc);
                centerDriftTime = doc.Settings.PeptideSettings.Prediction.GetDriftTimeHelper(
                    new LibKey("DEADEELS", 5), null, out windowDT);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(false) ?? -1, .000001);
                Assert.AreEqual(deadeelsDT, centerDriftTime.DriftTimeMsec(true) ?? -1, .000001); // High energy value should now be same as low energy value
                Assert.AreEqual(2 * (deadeelsDT / resolvingPower), windowDT, .0001);             // Directly measured, should match

                // Now make sure that high energy checkbox initial state is as we expect
                var peptideSettingsDlg5 = ShowDialog <PeptideSettingsUI>(
                    () => SkylineWindow.ShowPeptideSettingsUI(PeptideSettingsUI.TABS.Prediction));
                // Simulate picking "Edit Current..." from the Drift Time Predictor combo control
                var driftTimePredictorDlg5 = ShowDialog <EditDriftTimePredictorDlg>(peptideSettingsDlg5.EditDriftTimePredictor);
                RunUI(() => Assert.IsFalse(driftTimePredictorDlg5.GetOffsetHighEnergySpectraCheckbox()));
                RunUI(driftTimePredictorDlg5.CancelDialog);
                WaitForClosedForm(driftTimePredictorDlg5);
                RunUI(peptideSettingsDlg5.OkDialog);
                WaitForClosedForm(peptideSettingsDlg5);
            }
            TestMeasuredDriftTimes();
        }