/// <summary>
        /// Executes a single plugin.
        /// </summary>
        /// <param name="pluginType">The type of the plugin to execute.</param>
        /// <returns>Response containing state about the success/failure of the plugin's execution.</returns>
        protected IPluginResponse ExecutePlugin(Type pluginType)
        {
            string pluginName = pluginType.Name;

            // Setup plugin for execution.
            IPluginRequest request     = CreatePluginRequest(pluginType);
            var            pluginTimer = logsharkRequest.RunContext.CreateTimer("Executed Plugin", pluginName);

            // Execute plugin.
            IPluginResponse pluginResponse = new PluginResponse(pluginName);

            try
            {
                IPlugin plugin = InitializePlugin(pluginType);

                Log.InfoFormat("Execution of {0} plugin started at {1}..", pluginName, DateTime.Now.ToString("h:mm tt", CultureInfo.InvariantCulture));
                pluginResponse = plugin.Execute(request);

                // Flush any workbooks, if this was a workbook creation plugin.
                if (plugin is IWorkbookCreationPlugin)
                {
                    WriteWorkbooksToDisk(plugin as IWorkbookCreationPlugin, pluginResponse);
                }

                // Publish any associated workbooks, if requested.
                if (logsharkRequest.PublishWorkbooks)
                {
                    workbookPublisher.PublishWorkbooks(pluginResponse);
                }
            }
            catch (PluginInitializationException ex)
            {
                string errorMessage = String.Format("Failed to initialize {0} plugin: {1}", pluginName, ex.Message);
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            catch (PublishingException ex)
            {
                string errorMessage = String.Format("Failed to publish workbooks: {0}", ex.Message);
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            catch (Exception ex)
            {
                string errorMessage = String.Format("Encountered uncaught exception while executing plugin '{0}': {1}", pluginName, ex.GetFlattenedMessage());
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            finally
            {
                pluginTimer.Stop();
                pluginResponse.PluginRunTime = pluginTimer.Elapsed;

                logsharkRequest.RunContext.RegisterPluginResponse(pluginResponse);
                PrintExecutionOutcome(pluginResponse);
            }

            return(pluginResponse);
        }
        /// <summary>
        /// Executes a single plugin.
        /// </summary>
        /// <param name="pluginType">The type of the plugin to execute.</param>
        /// <param name="pluginExecutionRequest">Plugin execution options.</param>
        /// <param name="previousPluginResponses">The set of plugin responses associated with the current run. Used for plugin chaining.</param>
        /// <returns>Response containing state about the success/failure of the plugin's execution.</returns>
        protected IPluginResponse ExecutePlugin(Type pluginType, PluginExecutionRequest pluginExecutionRequest, IEnumerable <IPluginResponse> previousPluginResponses)
        {
            string pluginName = pluginType.Name;

            // Setup plugin for execution.
            IPluginRequest pluginRequest = CreatePluginRequest(pluginType, pluginExecutionRequest);
            var            pluginTimer   = new LogsharkTimer("Executed Plugin", pluginName, GlobalEventTimingData.Add);

            // Execute plugin.
            IPluginResponse pluginResponse = new PluginResponse(pluginName);

            try
            {
                string outputDatabaseName = GetOutputDatabaseName(pluginName, pluginRequest, pluginExecutionRequest);

                var plugin = InitializePlugin(pluginType, pluginRequest, pluginExecutionRequest.MongoDatabaseName, outputDatabaseName, previousPluginResponses);

                Log.InfoFormat("Execution of {0} plugin started at {1}..", pluginName, DateTime.Now.ToString("h:mm tt", CultureInfo.InvariantCulture));
                pluginResponse = plugin.Execute();

                // Flush any workbooks, if this was a workbook creation plugin.
                if (plugin is IWorkbookCreationPlugin)
                {
                    IEnumerable <string> workbookFilePaths = WriteWorkbooksToDisk(pluginRequest.OutputDirectory, plugin as IWorkbookCreationPlugin, pluginResponse, outputDatabaseName);
                    pluginResponse.WorkbooksOutput.AddRange(workbookFilePaths);
                }

                // Publish any associated workbooks, if requested.
                if (pluginExecutionRequest.PublishingOptions != null && pluginExecutionRequest.PublishingOptions.PublishWorkbooks)
                {
                    var restApiRequestor  = new RestApiRequestor(tableauConnectionInfo.Uri, tableauConnectionInfo.Username, tableauConnectionInfo.Password, tableauConnectionInfo.Site);
                    var workbookPublisher = new WorkbookPublisher(tableauConnectionInfo, postgresConnectionInfo, pluginExecutionRequest.PublishingOptions, restApiRequestor);

                    ICollection <PublishedWorkbookResult> workbooksPublished = workbookPublisher.PublishWorkbooks(pluginResponse);
                    pluginResponse.WorkbooksPublished.AddRange(workbooksPublished);
                }
            }
            catch (PluginInitializationException ex)
            {
                string errorMessage = String.Format("Failed to initialize {0} plugin: {1}", pluginName, ex.Message);
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            catch (PublishingException ex)
            {
                string errorMessage = String.Format("Failed to publish workbooks: {0}", ex.Message);
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            catch (Exception ex)
            {
                string errorMessage = String.Format("Encountered uncaught exception while executing plugin '{0}': {1}", pluginName, ex.GetFlattenedMessage());
                HandlePluginExecutionFailure(pluginResponse, errorMessage, ex);
            }
            finally
            {
                pluginTimer.Stop();
                pluginResponse.PluginRunTime = pluginTimer.Elapsed;

                LogExecutionOutcome(pluginResponse);
            }

            return(pluginResponse);
        }