private void PrintReport(Notification notification, SubscriptionData data)
        {
            try
            {
                // Debug
                m_sb.Append(System.DateTime.Now + Environment.NewLine);

                // Make sure that the format for rendering to a printer is available
                if (!CanRenderImage)
                {
                    throw new Exception("The IMAGE rendering extension needed for printer delivery is not available.");
                }

                // Correctly format device info strings
                string pageWidth = data.pageWidth + "in";
                string pageHeight = data.pageHeight + "in";
                string deviceInfo;

                // Render each page in the report and store it in a
                // Stream array until a blank page is rendered. This
                // marks the end of the report

                deviceInfo = String.Format(
                        System.Globalization.CultureInfo.InvariantCulture,
                        @"<DeviceInfo><OutputFormat>{0}</OutputFormat><PageHeight>{1}</PageHeight><PageWidth>{2}</PageWidth></DeviceInfo>",
                        "emf", pageHeight, pageWidth);

                // Render report
                m_files = notification.Report.Render("IMAGE", deviceInfo);
                m_numberOfPages = m_files.Length;

                // Write render information to the log entry
                m_sb.Append("Number of pages: " + m_numberOfPages + Environment.NewLine);

                // Configure printer settings
                PrinterSettings printerSettings = new PrinterSettings();
                printerSettings.PrintRange = PrintRange.SomePages;
                printerSettings.FromPage = 1;
                printerSettings.ToPage = m_numberOfPages;

                /* The name of the printer comes from the subscription data.
                 * Validate the printer against known, installed printers on the server.
                 * This is done in the ValidateUserData method as well as now at deliver
                 * time to ensure that a printer has not been uninstalled since the time
                 * The subscription was created and the time the delivery takes place
                 *
                 * Note: In production code, you would want to make this check earlier
                 * because the Render operation can take significant amounts of time
                 * and memory.  It is presented here in the sample flow for clarity.
                */
                if (!IsValidPrinter(data.Printer))
                    throw new Exception("The printer " + data.Printer + " is not currently installed on the server.");

                printerSettings.PrinterName = data.Printer;

                // Create print document and set printer settings
                PrintDocument pd = new PrintDocument();
                m_currentPrintingPage = 1;
                m_lastPrintingPage = m_numberOfPages;
                pd.PrinterSettings = printerSettings;

                // Print pages
                pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
                pd.Print();

                // Set the status if the report pages were successfully sent to the printer
                notification.Status = String.Format(
                    System.Globalization.CultureInfo.InvariantCulture,
                    "Report printed to {0}", data.Printer);
            }
            catch (Exception ex)
            {
                // Set the status of the notification if an error occurs
                notification.Status = ex.Message;
                // Write exception information to a logfile
                m_sb.Append(ex.Message + ": " + ex.StackTrace + Environment.NewLine);
            }
            finally
            {
                WriteLog(m_sb);
                m_sb = null;
            }
        }
        /// <summary>
        /// Delivers the report notification to a user based on the contents of the notification.
        /// </summary>
        /// <param name="notification">A Notification object containing information required by the 
        /// delivery extension to deliver a report.</param>
        /// <returns>A Boolean value indicating whether or not to retry the delivery.</returns>
        bool IDeliveryExtension.Deliver(Notification notification)
        {
            bool success = false;

            // Set the status of the notification to pending
            notification.Status = "Processing...";

            try
            {
                // Build user data
                Setting[] userSettings = notification.UserData;
                SubscriptionData subscriptionData = new SubscriptionData();
                subscriptionData.FromSettings(userSettings);

                // Print the report
                PrintReport(notification, subscriptionData);

                // If delivery is successful return true
                success = true;

            }
            catch (Exception ex)
            {
                // Set the status of the notification if an error occurs
                notification.Status = "Error: " + ex.Message;
                success = false;
            }

            finally
            {
                // Finally, save the notification information
                notification.Save();
            }

            return success;
        }