/// <summary>
        /// This method is the delegate called when an export is to be handled using a plugin.
        /// </summary>
        /// <returns>True if the operation succeeded, False otherwise.</returns>
        private void ExportResults(WatcherOutputPlugin plugin, WatcherResultCollection results, String filename)
        {
            // Perform the Save operation.  Not every save operation will return a
            // stream; therefore, a null return value is not necessarily an error.
            //
            // TODO: This class is a candidate for redesign as it handles exports with different semantics (e.g., TFS)
            Stream outputStream = plugin.SaveResult(results);

            if (outputStream != null)
            {
                using (FileStream fs = new FileStream(filename, FileMode.Create))
                {
                    Utility.ReadWriteStream(outputStream, fs);
                }
            }
        }
        /// <summary>
        /// Get a configuration item and return the specified default value if not already present.
        /// </summary>
        /// <param name="check">The Watcher check whose configuration option is to be retrieved.</param>
        /// <param name="configOption">The configuration option to retrieve.</param>
        /// <param name="defaultValue">The value to return if not already set in the configuration.</param>
        /// <returns>The value of the specified check's configuration option.</returns>
        public String GetConfigItem(WatcherOutputPlugin plugin, String configOption, String defaultValue)
        {
            // The name of the check as it is stored in the application configuration
            String configurationName = plugin.GetName();

            if (configurationName.Length > 0)
            {
                // Prepend Plugin Class to KeyName
                String pluginOptionName = configurationName + '\\' + configOption;
                if (!String.IsNullOrEmpty(configurationName))
                {
                    String setting = String.Empty;

                    try
                    {
                        // Load the check configuration from the application configuration
                        setting = Get(pluginOptionName);// ConfigurationManager.AppSettings[checkOptionName];
                    }

                    catch (ConfigurationErrorsException e)
                    {
                        // Thrown if a failure occurs when reading the application configuration
                        String errorMessage = String.Format("Error: ConfigurationErrorsException: {0}", e.Message);
                        Trace.TraceError("Error: {0}", errorMessage);
                        Debug.Assert(false, errorMessage);
                    }

                    // If the configuration entry for the check does not exist, use the default value
                    if (String.IsNullOrEmpty(setting))
                    {
                        // Set the default value if it was specified
                        if (!String.IsNullOrEmpty(defaultValue))
                        {
                            SetConfigItem(plugin, configOption, defaultValue);
                        }

                        return(defaultValue);
                    }

                    // Note: checking a second time does not get an updated setting
                    return(setting);
                }
            }

            return(String.Empty);
        }
        /// <summary>
        /// Set a configuration option for the specified check.  An entry will be created if it doesn't already exist.
        /// </summary>
        /// <param name="check">The Watcher check whose configuration option is to be set.</param>
        /// <param name="configOption">The configuration option to set.</param>
        /// <param name="value">The configuration value to set.</param>
        public void SetConfigItem(WatcherOutputPlugin plugin, String configOption, String value)
        {
            String configurationName = plugin.GetName();

            if (configurationName.Length > 0)
            {
                String pluginOptionName = configurationName + "\\" + configOption;
                if (!String.IsNullOrEmpty(configurationName))
                {
                    Remove(pluginOptionName);
                    Add(pluginOptionName, value);
                    if (_autosave)
                    {
                        Save();
                    }
                }
            }
            // TODO: return a bool for success
        }
        /// <summary>
        /// This method initializes the control values prior to displaying the control.
        /// </summary>
        /// <remarks>
        /// This event occurs before the control becomes visible for the first time (ref: MSDN).
        /// </remarks>
        protected override void OnLoad(EventArgs e)
        {
            // Don't load the configuration in design mode
            if (this.Site == null || this.Site.DesignMode == false)
            {
                //Initialize Save Method
                //String savetoXML = "XML File";
                //this.cbExportMethod.Items.Add(savetoXML);

                foreach (WatcherOutputPlugin plugin in WatcherEngine.OutputPluginManager.OutputPlugins)
                {
                    this.cbExportMethod.Items.Add(plugin);
                }

                String SaveMethod = WatcherEngine.Configuration.Get("DefaultSaveMethod");

                if (!String.IsNullOrEmpty(SaveMethod))
                {
                    SaveMethod = Utility.Base64Decode(SaveMethod);
                    //Store with Base64 since plugins may use dangerous characters
                    for (int i = 0; i < cbExportMethod.Items.Count; i++)
                    {
                        WatcherOutputPlugin OutPlugin = (WatcherOutputPlugin)this.cbExportMethod.Items[i];
                        if (SaveMethod == OutPlugin.GetName())
                        {
                            this.cbExportMethod.SelectedItem = this.cbExportMethod.Items[i];
                            break;
                        }
                    }
                }

                // Reduce flicker
                ListViewHelper.EnableDoubleBuffer(this.alertListView);

                // Instantiate the list view comparison class
                alvwColumnSorter = new AlertListViewColumnSorter();
                this.alertListView.ListViewItemSorter = alvwColumnSorter;

                // Set the default filter level for check alerts
                this.noisereduction = WatcherResultSeverity.Informational;

                // TODO: Use custom Watcher configuration section
                // Use the filter level from the configuration, if it exists
                if (!String.IsNullOrEmpty(WatcherEngine.Configuration.Get("DefaultFilter")))
                {
                    this.noisereductioncomboBox.SelectedItem = WatcherEngine.Configuration.Get("DefaultFilter");
                }
                else
                {
                    //Update the Selected Item since the configuration item did not exist.
                    this.noisereductioncomboBox.SelectedItem = "Informational";
                }

                // Determine whether to auto-scroll alerts
                if (!String.IsNullOrEmpty(WatcherEngine.Configuration.Get("AutoScroll")))
                {
                    string temp = WatcherEngine.Configuration.Get("AutoScroll");
                    this.autoscrollcheckBox.Checked = Boolean.Parse(temp);
                }
                int     index      = this.label3.Text.IndexOf(",");
                Version currentver = new UpdateManager().CurrentVersionEngine;
                this.label3.Text = this.label3.Text.Insert(index, " v" + currentver.ToString());
            }

            textBoxSearchResults.TextChanged += new EventHandler(textBoxSearchResults_TextChanged);

            base.OnLoad(e);
        }
        /// <summary>
        /// This is an event handler called when the user clicks the Export button.
        /// </summary>
        private void FileSaveButton_Click(object sender, EventArgs e)
        {
            // If no export method is selected, bail.
            if (cbExportMethod.SelectedItem == null)
            {
                MessageBox.Show("No export method selected.  Please select an export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Gather the selected results
            WatcherResultCollection selectedResults = new WatcherResultCollection();

            foreach (AlertListViewItem item in alertListView.Items)
            {
                WatcherResult result = new WatcherResult();
                result.Description = item.Description;
                result.Severity    = item.Severity;
                result.Title       = item.TypeX;
                result.URL         = item.URL;

                selectedResults.Add(result);
            }

            // The export method refers to an instance of the output plugin
            WatcherOutputPlugin outputPlugin = cbExportMethod.SelectedItem as WatcherOutputPlugin;

            if (outputPlugin == null)
            {
                Trace.TraceError("WatcherResultsControl: Invalid export method selected.");
                MessageBox.Show("Unable to use the selected export method.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            String filename = String.Empty;
            String filter   = String.Empty;

            // If this plugin is a file-based export, open a file save dialog and allow
            // the user to select the output filename.  Use the default values provided
            // by the plugin.
            //
            // TODO: Plugin should be interface-based or provide a property to tell whether it is a file-based export or not
            if (outputPlugin.GetExportDefaults(ref filename, ref filter))
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.FileName         = filename;
                dlg.Filter           = filter;
                dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                dlg.FilterIndex      = 1;
                dlg.RestoreDirectory = true;

                // Display the dialog, and if canceled, abort.
                if (dlg.ShowDialog() != DialogResult.OK)
                {
                    Trace.TraceInformation("User canceled export.");
                    return;
                }

                // Update the filename selected by the user
                filename = dlg.FileName;
            }

            // This is the export progress dialog shown during the export process

            // CHANGE - potentially breaking change, removing progress dialog
            // which seems to be dreadfully slowing down real work.
            WatcherEngine.ProgressDialog.Show();
            WatcherEngine.ProgressDialog.Title = "Export Data";

            // Perform the export asynchronously
            ExportResultsCallback callback = new ExportResultsCallback(ExportResults);

            callback.BeginInvoke(outputPlugin, selectedResults, filename,

                                 // This is the anonymous callback method
                                 delegate(IAsyncResult ar)
            {
                try
                {
                    // Tidy up after the export
                    ExportResultsCallback _callback = (ExportResultsCallback)ar.AsyncState;
                    _callback.EndInvoke(ar);     // NOTE: This will throw any unhandled exceptions that happened during the call
                }

                catch (WatcherException ex)
                {
                    Trace.TraceError("Exception: {0}", ex.Message);
                    if (ex.Data.Contains("UserAbortedOperation") == false)
                    {
                        // Only show a message box if the user hasn't already seen one (i.e., they've elected to abort the operation)
                        MessageBox.Show(this, String.Format("{0}", ex.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    return;
                }

                finally
                {
                    // CHANGE - see above breaking change, removing progress dialog.
                    WatcherEngine.ProgressDialog.Hide();
                }

                MessageBox.Show(this, "Items successfully exported.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
            },

                                 // Pass the callback as user data so we can call EndInvoke() when the operation completes
                                 // to retrieve the result.
                                 callback);
        }
 /// <summary>
 /// Get a configuration item with no default value set.
 /// </summary>
 /// <param name="check">The Watcher plugin whose configuration option is to be retrieved.</param>
 /// <param name="configOption">The configuration option to retrieve.</param>
 /// <returns>The value of the specified option.</returns>
 public String GetConfigItem(WatcherOutputPlugin plugin, String configOption)
 {
     return(GetConfigItem(plugin, configOption, String.Empty));
 }