private void ClassifierList_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right && SelectedItem != null)
            {
                Classifier classifier = SelectedItem as Classifier;
                if (classifier == null)
                {
                    throw new NullReferenceException("Failed to cast classifier item from list");
                }

                string updateWindowTitle = "Updating " + classifier.GetType().Name + "...";

                if (classifier is LibLinear)
                {
                    LibLinear   liblinear = classifier as LibLinear;
                    DynamicForm f         = new DynamicForm("Set LibLinear parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddCheckBox("Run feature selection:", ContentAlignment.MiddleRight, liblinear.RunFeatureSelection, "run_feature_selection");
                    f.AddDropDown("Positive weighting:", Enum.GetValues(typeof(LibLinear.PositiveClassWeighting)), liblinear.Weighting, "positive_weighting", true);
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        liblinear.RunFeatureSelection = f.GetValue <bool>("run_feature_selection");
                        liblinear.Weighting           = f.GetValue <LibLinear.PositiveClassWeighting>("positive_weighting");
                    }
                }
                else if (classifier is SvmRank)
                {
                    SvmRank     svmRank = classifier as SvmRank;
                    DynamicForm f       = new DynamicForm("Set SvmRank parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("c:", (decimal)svmRank.C, 3, decimal.MinValue, decimal.MaxValue, (decimal)0.01, "c");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        try { svmRank.C = Convert.ToSingle(f.GetValue <decimal>("c")); }
                        catch (Exception ex) { MessageBox.Show("Invalid value for C:  " + ex.Message); }
                    }
                }
                else if (classifier is RandomForest)
                {
                    RandomForest randomForest = classifier as RandomForest;
                    DynamicForm  f            = new DynamicForm("Set RandomForest parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("Number of trees:", randomForest.NumTrees, 0, 1, decimal.MaxValue, 1, "ntree");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        randomForest.NumTrees = Convert.ToInt32(f.GetValue <decimal>("ntree"));
                    }
                }
                else if (classifier is AdaBoost)
                {
                    AdaBoost    adaBoost = classifier as AdaBoost;
                    DynamicForm f        = new DynamicForm("Set AdaBoost parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("Number of iterations:", adaBoost.Iterations, 0, 1, decimal.MaxValue, 1, "iterations");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        adaBoost.Iterations = Convert.ToInt32(f.GetValue <decimal>("iterations"));
                    }
                }
            }
        }
        private void SmootherList_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                int clickedIndex = IndexFromPoint(e.Location);
                if (clickedIndex >= 0)
                {
                    Smoother smoother = Items[clickedIndex] as Smoother;
                    if (smoother == null)
                        throw new NullReferenceException("Expected Smoother objects in Items");

                    string updateWindowTitle = "Updating " + smoother.GetType().Name + "...";

                    if (smoother is KdeSmoother)
                    {
                        KdeSmoother kdeSmoother = smoother as KdeSmoother;
                        DynamicForm f = new DynamicForm("Set KDE smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Sample size:", kdeSmoother.SampleSize, 0, 1, decimal.MaxValue, 1, "sample_size");
                        f.AddCheckBox("Normalize:", ContentAlignment.MiddleRight, kdeSmoother.Normalize, "normalize");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { kdeSmoother.SampleSize = Convert.ToInt32(f.GetValue<decimal>("sample_size")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for sample size:  " + ex.Message); }

                            kdeSmoother.Normalize = f.GetValue<bool>("normalize");
                        }
                    }
                    else if (smoother is WeightedAverageSmoother)
                    {
                        WeightedAverageSmoother avgSmoother = smoother as WeightedAverageSmoother;
                        DynamicForm f = new DynamicForm("Set weighted average smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Minimum:", (decimal)avgSmoother.Minimum, 0, 0, decimal.MaxValue, 1, "minimum");
                        f.AddNumericUpdown("Maximum:", (decimal)avgSmoother.Maximum, 0, 0, decimal.MaxValue, 1, "maximum");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { avgSmoother.Minimum = Convert.ToDouble(f.GetValue<decimal>("minimum")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for minimum:  " + ex.Message); }

                            try
                            {
                                double value = Convert.ToDouble(f.GetValue<decimal>("maximum"));
                                if (value < avgSmoother.Minimum)
                                {
                                    avgSmoother.Maximum = avgSmoother.Minimum + 500;
                                    throw new Exception("Maximum must be greater than or equal to minimum (" + avgSmoother.Minimum + "). Setting maximum to " + avgSmoother.Maximum + ".");
                                }

                                avgSmoother.Maximum = value;
                            }
                            catch (Exception ex) { MessageBox.Show("Invalid value for maximum:  " + ex.Message); }
                        }
                    }
                    else if (smoother is MarsSmoother)
                    {
                        MarsSmoother marsSmoother = smoother as MarsSmoother;
                        DynamicForm f = new DynamicForm("Set MARS smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Number of considered parent terms (-1 for all):", marsSmoother.ConsideredParentTerms, 0, -1, decimal.MaxValue, 1, "parent");
                        f.AddNumericUpdown("Degree of interaction:", marsSmoother.InteractionDegree, 0, 1, decimal.MaxValue, 1, "interaction");
                        f.AddNumericUpdown("Number of knots (-1 for auto):", marsSmoother.NumberOfKnots, 0, -1, decimal.MaxValue, 1, "knots");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { marsSmoother.ConsideredParentTerms = Convert.ToInt32(f.GetValue<decimal>("parent")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for parent terms:  " + ex.Message); }

                            try { marsSmoother.InteractionDegree = Convert.ToInt32(f.GetValue<decimal>("interaction")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for interaction degree:  " + ex.Message); }

                            try { marsSmoother.NumberOfKnots = Convert.ToInt32(f.GetValue<decimal>("knots")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for number of knots:  " + ex.Message); }
                        }
                    }
                    else
                        throw new NotImplementedException("Unrecognized smoother type:  " + smoother.GetType().FullName);
                }
            }
        }
        private void SmootherList_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                int clickedIndex = IndexFromPoint(e.Location);
                if (clickedIndex >= 0)
                {
                    Smoother smoother = Items[clickedIndex] as Smoother;
                    if (smoother == null)
                    {
                        throw new NullReferenceException("Expected Smoother objects in Items");
                    }

                    string updateWindowTitle = "Updating " + smoother.GetType().Name + "...";

                    if (smoother is KdeSmoother)
                    {
                        KdeSmoother kdeSmoother = smoother as KdeSmoother;
                        DynamicForm f           = new DynamicForm("Set KDE smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Sample size:", kdeSmoother.SampleSize, 0, 1, decimal.MaxValue, 1, "sample_size");
                        f.AddCheckBox("Normalize:", ContentAlignment.MiddleRight, kdeSmoother.Normalize, "normalize");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { kdeSmoother.SampleSize = Convert.ToInt32(f.GetValue <decimal>("sample_size")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for sample size:  " + ex.Message); }

                            kdeSmoother.Normalize = f.GetValue <bool>("normalize");
                        }
                    }
                    else if (smoother is WeightedAverageSmoother)
                    {
                        WeightedAverageSmoother avgSmoother = smoother as WeightedAverageSmoother;
                        DynamicForm             f           = new DynamicForm("Set weighted average smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Minimum:", (decimal)avgSmoother.Minimum, 0, 0, decimal.MaxValue, 1, "minimum");
                        f.AddNumericUpdown("Maximum:", (decimal)avgSmoother.Maximum, 0, 0, decimal.MaxValue, 1, "maximum");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { avgSmoother.Minimum = Convert.ToDouble(f.GetValue <decimal>("minimum")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for minimum:  " + ex.Message); }

                            try
                            {
                                double value = Convert.ToDouble(f.GetValue <decimal>("maximum"));
                                if (value < avgSmoother.Minimum)
                                {
                                    avgSmoother.Maximum = avgSmoother.Minimum + 500;
                                    throw new Exception("Maximum must be greater than or equal to minimum (" + avgSmoother.Minimum + "). Setting maximum to " + avgSmoother.Maximum + ".");
                                }

                                avgSmoother.Maximum = value;
                            }
                            catch (Exception ex) { MessageBox.Show("Invalid value for maximum:  " + ex.Message); }
                        }
                    }
                    else if (smoother is MarsSmoother)
                    {
                        MarsSmoother marsSmoother = smoother as MarsSmoother;
                        DynamicForm  f            = new DynamicForm("Set MARS smoother parameters", DynamicForm.CloseButtons.OkCancel);
                        f.AddNumericUpdown("Number of considered parent terms (-1 for all):", marsSmoother.ConsideredParentTerms, 0, -1, decimal.MaxValue, 1, "parent");
                        f.AddNumericUpdown("Degree of interaction:", marsSmoother.InteractionDegree, 0, 1, decimal.MaxValue, 1, "interaction");
                        f.AddNumericUpdown("Number of knots (-1 for auto):", marsSmoother.NumberOfKnots, 0, -1, decimal.MaxValue, 1, "knots");
                        if (f.ShowDialog() == DialogResult.OK)
                        {
                            try { marsSmoother.ConsideredParentTerms = Convert.ToInt32(f.GetValue <decimal>("parent")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for parent terms:  " + ex.Message); }

                            try { marsSmoother.InteractionDegree = Convert.ToInt32(f.GetValue <decimal>("interaction")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for interaction degree:  " + ex.Message); }

                            try { marsSmoother.NumberOfKnots = Convert.ToInt32(f.GetValue <decimal>("knots")); }
                            catch (Exception ex) { MessageBox.Show("Invalid value for number of knots:  " + ex.Message); }
                        }
                    }
                    else
                    {
                        throw new NotImplementedException("Unrecognized smoother type:  " + smoother.GetType().FullName);
                    }
                }
            }
        }
        public void importIncidentsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Import(ATT.Configuration.IncidentsImportDirectory,

                   new CompleteImporterFormDelegate(f =>
                       {
                           Area[] areas = Area.GetAll().ToArray();
                           if (areas.Length == 0)
                           {
                               MessageBox.Show("No areas available. Import one first.");
                               return null;
                           }

                           f.AddDropDown("Import into area:", areas, null, "area", true);
                           f.AddNumericUpdown("Incident hour offset:", 0, 0, decimal.MinValue, decimal.MaxValue, 1, "offset");

                           return f;
                       }),

                   new CreateImporterDelegate((name, path, sourceURI, importerForm) =>
                       {
                           Area importArea = importerForm.GetValue<Area>("area");
                           int hourOffset = Convert.ToInt32(importerForm.GetValue<decimal>("offset"));

                           string extension = Path.GetExtension(path).ToLower();
                           if (extension == ".xml")
                           {
                               DynamicForm f = new DynamicForm("Location SRID", DynamicForm.CloseButtons.OK);
                               f.AddNumericUpdown("Location SRID:", 0, 0, 0, decimal.MaxValue, 1, "source_srid");
                               f.ShowDialog();
                               int sourceSRID = Convert.ToInt32(f.GetValue<decimal>("source_srid"));

                               Type[] rowInserterTypes = Assembly.GetAssembly(typeof(XmlImporter.XmlRowInserter)).GetTypes().Where(type => !type.IsAbstract && (type == typeof(XmlImporter.IncidentXmlRowInserter) || type.IsSubclassOf(typeof(XmlImporter.IncidentXmlRowInserter)))).ToArray();
                               string[] databaseColumns = new string[] { Incident.Columns.NativeId, Incident.Columns.Time, Incident.Columns.Type, Incident.Columns.X(importArea), Incident.Columns.Y(importArea) };

                               return CreateXmlImporter(name, path, ATT.Configuration.IncidentsImportDirectory, PathRelativizationId.IncidentDirectory, sourceURI, rowInserterTypes, databaseColumns, databaseColumnInputColumn =>
                                                        {
                                                            return new XmlImporter.IncidentXmlRowInserter(databaseColumnInputColumn, importArea, hourOffset, sourceSRID);
                                                        });
                           }
                           else if (extension == ".shp")
                           {
                               int targetSRID = importArea.Shapefile.SRID;
                               ShapefileInfoRetriever shapefileInfoRetriever = new ShapefileInfoRetriever(name, 0, targetSRID);
                               return new IncidentShapefileImporter(name, path, RelativizePath(path, ATT.Configuration.IncidentsImportDirectory, PathRelativizationId.IncidentDirectory), sourceURI, 0, targetSRID, shapefileInfoRetriever, importArea, new IncidentTableShapefileTableMappingRetriever(), hourOffset);
                           }
                           else
                               throw new NotImplementedException("Unrecognized incident import file extension:  " + extension);
                       }),

                   ATT.Configuration.IncidentsImportDirectory,
                   "Incident files (*.shp;*.xml;*.zip)|*.shp;*.xml;*.zip",
                   new string[] { "*.xml", "*.shp" },
                   null);
        }
        private void manageStoredImportersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Importer[] storedImporters = Importer.GetAll().ToArray();

            Thread t = new Thread(new ThreadStart(() =>
                {
                    DialogResult manageDialogResult = System.Windows.Forms.DialogResult.OK;
                    bool refreshStoredImporters = false;
                    while (manageDialogResult == System.Windows.Forms.DialogResult.OK)
                    {
                        if (refreshStoredImporters)
                        {
                            storedImporters = Importer.GetAll().ToArray();
                            refreshStoredImporters = false;
                        }

                        DynamicForm f = new DynamicForm("Stored importers...", DynamicForm.CloseButtons.OkClose);
                        f.AddListBox("Importers:", storedImporters, null, SelectionMode.MultiExtended, "importers", true);
                        f.AddDropDown("Action:", Enum.GetValues(typeof(ManageImporterAction)), null, "action", false);
                        if ((manageDialogResult = f.ShowDialog()) == System.Windows.Forms.DialogResult.OK)
                        {
                            ManageImporterAction action = f.GetValue<ManageImporterAction>("action");

                            if (action == ManageImporterAction.Load)
                            {
                                DynamicForm df = new DynamicForm("Select importer source...", DynamicForm.CloseButtons.OkCancel);
                                df.AddTextBox("Path:", ATT.Configuration.ImportersLoadDirectory, 75, "path", addFileBrowsingButtons: true, fileFilter: "ATT importers|*.attimp", initialBrowsingDirectory: ATT.Configuration.ImportersLoadDirectory);
                                if (df.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                                {
                                    string path = df.GetValue<string>("path");
                                    string[] importerPaths = null;
                                    if (Directory.Exists(path))
                                        importerPaths = Directory.GetFiles(path, "*.attimp", SearchOption.TopDirectoryOnly);
                                    else if (File.Exists(path))
                                        importerPaths = new string[] { path };

                                    if (importerPaths != null)
                                    {
                                        BinaryFormatter bf = new BinaryFormatter();
                                        foreach (string importerPath in importerPaths)
                                            using (FileStream fs = new FileStream(importerPath, FileMode.Open, FileAccess.Read))
                                            {
                                                try
                                                {
                                                    Importer importer = bf.Deserialize(fs) as Importer;

                                                    string absolutePath = importer.Path;
                                                    int relativizationIdEnd = importer.RelativePath.IndexOf('}');
                                                    string relativizationId = importer.RelativePath.Substring(0, relativizationIdEnd + 1).Trim('{', '}');
                                                    if (!string.IsNullOrWhiteSpace(relativizationId))
                                                    {
                                                        PathRelativizationId pathRelativizationId = (PathRelativizationId)Enum.Parse(typeof(PathRelativizationId), relativizationId);
                                                        string relativeTrailingPath = importer.RelativePath.Substring(relativizationIdEnd + 1).Trim(Path.DirectorySeparatorChar);
                                                        if (pathRelativizationId == PathRelativizationId.EventDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.EventsImportDirectory, relativeTrailingPath);
                                                        else if (pathRelativizationId == PathRelativizationId.IncidentDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.IncidentsImportDirectory, relativeTrailingPath);
                                                        else if (pathRelativizationId == PathRelativizationId.ShapefileDirectory)
                                                            absolutePath = Path.Combine(ATT.Configuration.PostGisShapefileDirectory, relativeTrailingPath);
                                                        else
                                                            throw new NotImplementedException("Unrecognized path relativization id:  " + pathRelativizationId);
                                                    }

                                                    importer.Path = absolutePath;
                                                    importer.Save(false);
                                                    fs.Close();
                                                    refreshStoredImporters = true;
                                                }
                                                catch (Exception ex)
                                                {
                                                    Console.Out.WriteLine("Importer import failed:  " + ex.Message);
                                                }
                                            }
                                    }
                                }
                            }
                            else
                            {
                                string exportDirectory = null;
                                foreach (Importer importer in f.GetValue<System.Windows.Forms.ListBox.SelectedObjectCollection>("importers"))
                                    if (action == ManageImporterAction.Delete)
                                    {
                                        importer.Delete();
                                        refreshStoredImporters = true;
                                    }
                                    else if (action == ManageImporterAction.Edit)
                                    {
                                        Dictionary<string, object> updateKeyValue = new Dictionary<string, object>();
                                        DynamicForm updateForm = new DynamicForm("Update importer \"" + importer + "\"...", DynamicForm.CloseButtons.OkCancel);
                                        importer.GetUpdateRequests(new Importer.UpdateRequestDelegate((itemName, currentValue, possibleValues, id) =>
                                            {
                                                itemName += ":";

                                                if (possibleValues != null)
                                                    updateForm.AddDropDown(itemName, possibleValues.ToArray(), currentValue, id, false);
                                                else if (currentValue is string)
                                                    updateForm.AddTextBox(itemName, currentValue as string, -1, id);
                                                else if (currentValue is int)
                                                    updateForm.AddNumericUpdown(itemName, (int)currentValue, 0, int.MinValue, int.MaxValue, 1, id);
                                                else if (currentValue != null)
                                                    throw new NotImplementedException("Cannot dynamically generate form for update request");

                                                updateKeyValue.Add(id, currentValue);
                                            }));

                                        if (updateForm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                                        {
                                            foreach (string updateKey in updateKeyValue.Keys.ToArray())
                                                updateKeyValue[updateKey] = updateForm.GetValue<object>(updateKey);

                                            importer.Update(updateKeyValue);
                                            importer.Save(true);
                                            refreshStoredImporters = true;
                                        }
                                    }
                                    else if (action == ManageImporterAction.Store)
                                    {
                                        if (exportDirectory == null)
                                            exportDirectory = LAIR.IO.Directory.PromptForDirectory("Select export directory...", ATT.Configuration.ImportersLoadDirectory);

                                        if (Directory.Exists(exportDirectory))
                                        {
                                            try
                                            {
                                                BinaryFormatter bf = new BinaryFormatter();
                                                using (FileStream fs = new FileStream(Path.Combine(exportDirectory, ReplaceInvalidFilenameCharacters(importer.ToString() + ".attimp")), FileMode.Create, FileAccess.ReadWrite))
                                                {
                                                    bf.Serialize(fs, importer);
                                                    fs.Close();
                                                    Console.Out.WriteLine("Exported \"" + importer + "\".");
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                Console.Out.WriteLine("Importer export failed:  " + ex.Message);
                                            }
                                        }
                                    }
                                    else if (action == ManageImporterAction.Run)
                                    {
                                        Console.Out.WriteLine("Running importer \"" + importer + "\"...");
                                        try { importer.Import(); }
                                        catch (Exception ex)
                                        {
                                            Console.Out.WriteLine("Import failed:  " + ex.Message);
                                        }
                                    }
                                    else
                                        MessageBox.Show("Unrecognized action:  " + action);
                            }
                        }
                    }

                    // might have imported/created an area
                    RefreshPredictionAreas();
                }));

            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
        private void editPredictionRunToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (SelectedPredictions.Count == 0)
                MessageBox.Show("Select one or more predictions to edit run number for.");
            else
            {
                DynamicForm f = new DynamicForm("", DynamicForm.CloseButtons.OkCancel);
                f.AddNumericUpdown("New run number for " + SelectedPredictions.Count + " prediction(s):", 1, 0, 1, int.MaxValue, 1, "run");
                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    int run = Convert.ToInt32(f.GetValue<decimal>("run"));
                    foreach (Prediction prediction in SelectedPredictions)
                        prediction.RunId = run;

                    RefreshPredictions(SelectedPredictions.ToArray());
                }
            }
        }
        private void copyPredictionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<Prediction> selectedPredictions = SelectedPredictions;
            if (selectedPredictions.Count == 0)
                MessageBox.Show("Select one or more predictions to copy.");
            else if (selectedPredictions.Count == 1 || MessageBox.Show("Are you sure you want to copy " + selectedPredictions.Count + " prediction(s)?", "Confirm copy", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                DynamicForm f = new DynamicForm("Set copy parameters", DynamicForm.CloseButtons.OkCancel);
                f.AddNumericUpdown("Number of copies of each prediction:  ", 1, 0, 1, decimal.MaxValue, 1, "copies");
                if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    int numCopies;
                    try { numCopies = Convert.ToInt32(f.GetValue<decimal>("copies")); }
                    catch (Exception ex) { MessageBox.Show("Invalid number of copies:  " + ex.Message); return; }

                    Thread t = new Thread(new ThreadStart(delegate()
                        {
                            int predictionNum = 0;
                            foreach (Prediction selectedPrediction in selectedPredictions)
                            {
                                ++predictionNum;

                                for (int copyNum = 1; copyNum <= numCopies; ++copyNum)
                                {
                                    Console.Out.WriteLine("Creating copy " + copyNum + " (of " + numCopies + ") of prediction " + predictionNum + " (of " + selectedPredictions.Count + ")");
                                    try
                                    {
                                        Prediction copy = selectedPrediction.Copy("Copy " + copyNum + " of " + selectedPrediction.Name, predictionNum == 1 && copyNum == 1, false);
                                        Point.VacuumTable(copy);
                                        PointPrediction.VacuumTable(copy);
                                    }
                                    catch (Exception ex) { Console.Out.WriteLine("Error while copying prediction:  " + ex.Message); }
                                }
                            }

                            try { Prediction.VacuumTable(); }
                            catch (Exception ex) { Console.Out.WriteLine("Failed to vacuum " + Prediction.Table + ":  " + ex.Message); }

                            string msg = "Done copying predictions";
                            Console.Out.WriteLine(msg);
                            Notify(msg, "");

                            RefreshPredictions(selectedPredictions.ToArray());
                        }));

                    t.Start();
                }
            }
        }
        private void ClassifierList_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right && SelectedItem != null)
            {
                Classifier classifier = SelectedItem as Classifier;
                if (classifier == null)
                    throw new NullReferenceException("Failed to cast classifier item from list");

                string updateWindowTitle = "Updating " + classifier.GetType().Name + "...";

                if (classifier is LibLinear)
                {
                    LibLinear liblinear = classifier as LibLinear;
                    DynamicForm f = new DynamicForm("Set LibLinear parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddCheckBox("Run feature selection:", ContentAlignment.MiddleRight, liblinear.RunFeatureSelection, "run_feature_selection");
                    f.AddDropDown("Positive weighting:", Enum.GetValues(typeof(LibLinear.PositiveClassWeighting)), liblinear.Weighting, "positive_weighting", true);
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        liblinear.RunFeatureSelection = f.GetValue<bool>("run_feature_selection");
                        liblinear.Weighting = f.GetValue<LibLinear.PositiveClassWeighting>("positive_weighting");
                    }
                }
                else if (classifier is SvmRank)
                {
                    SvmRank svmRank = classifier as SvmRank;
                    DynamicForm f = new DynamicForm("Set SvmRank parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("c:", (decimal)svmRank.C, 3, decimal.MinValue, decimal.MaxValue, (decimal)0.01, "c");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        try { svmRank.C = Convert.ToSingle(f.GetValue<decimal>("c")); }
                        catch (Exception ex) { MessageBox.Show("Invalid value for C:  " + ex.Message); }
                    }
                }
                else if (classifier is RandomForest)
                {
                    RandomForest randomForest = classifier as RandomForest;
                    DynamicForm f = new DynamicForm("Set RandomForest parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("Number of trees:", randomForest.NumTrees, 0, 1, decimal.MaxValue, 1, "ntree");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        randomForest.NumTrees = Convert.ToInt32(f.GetValue<decimal>("ntree"));
                    }
                }
                else if (classifier is AdaBoost)
                {
                    AdaBoost adaBoost = classifier as AdaBoost;
                    DynamicForm f = new DynamicForm("Set AdaBoost parameters", DynamicForm.CloseButtons.OkCancel);
                    f.AddNumericUpdown("Number of iterations:", adaBoost.Iterations, 0, 1, decimal.MaxValue, 1, "iterations");
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        adaBoost.Iterations = Convert.ToInt32(f.GetValue<decimal>("iterations"));
                    }
                }
            }
        }