/// <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);
        }