public static void ReportBuilder(int cropYear, int contractNumber, string logoUrl, System.IO.FileStream fs)
        {
            const string METHOD_NAME             = "ReportBuilder";
            Document     document                = null;
            PdfWriter    writer                  = null;
            PdfPTable    table                   = null;
            ContractDeliverySummaryEvent pgEvent = null;

            iTextSharp.text.Image imgLogo = null;

            int contractID = 0;
            int stationNo  = 0;
            int factoryNo  = 0;

            int acresContracted = 0;
            int acresHarvested  = 0;
            int acresLost       = 0;
            int acresPlanted    = 0;

            try {
                if (document == null)
                {
                    // IF YOU CHANGE MARGINS, CHANGE YOUR TABLE LAYOUTS !!!
                    //  ***  US LETTER: 612 X 792  ***  // margins: L, R, T, B
                    //document = new Document(iTextSharp.text.PageSize.LETTER, 36, 36, 54, 72);
                    document = new Document(PortraitPageSize.PgPageSize, PortraitPageSize.PgLeftMargin,
                                            PortraitPageSize.PgRightMargin, PortraitPageSize.PgTopMargin, PortraitPageSize.PgBottomMargin);

                    // we create a writer that listens to the document
                    // and directs a PDF-stream to a file
                    writer = PdfWriter.GetInstance(document, fs);

                    imgLogo = PdfReports.GetImage(logoUrl, 127, 50, iTextSharp.text.Element.ALIGN_CENTER);

                    // Attach my override event handler(s)
                    pgEvent = new ContractDeliverySummaryEvent();
                    pgEvent.FillEvent(imgLogo, cropYear.ToString());
                    writer.PageEvent = pgEvent;

                    // Open the document
                    document.Open();
                }

                // =======================================================
                // Build Report
                // =======================================================

                int       staExSugar             = 0;
                int       ftyExSugar             = 0;
                decimal   extractableSugarPerTon = 0;
                PdfPTable addrTable = null;

                List <ContractGorwerLandownerItem> stateList = WSCReportsExec.ContractDeliverySummary1(cropYear, contractNumber);

                float[] addrLayout = new float[] { 9.3F, 67.6F, 23.1F };

                addrTable = PdfReports.CreateTable(addrLayout, 0);

                if (stateList.Count > 0)
                {
                    ContractGorwerLandownerItem item = stateList[0];

                    PdfReports.AddText2Table(addrTable, "Contract", _normalFont);
                    PdfReports.AddText2Table(addrTable,
                                             "Grower#: " + item.Gro_Address_Number, _normalFont);
                    PdfReports.AddText2Table(addrTable,
                                             "Landowner#: " + item.Ldo_Address_Number, _normalFont);

                    PdfReports.AddText2Table(addrTable, item.Contract_Number, _normalFont);

                    Paragraph p = PdfReports.GetAddressBlock(item.Grower_Name,
                                                             item.Gro_Address_1,
                                                             item.Gro_Address_2,
                                                             item.Grower_City + ", " +
                                                             item.Grower_State + " " +
                                                             item.Grower_Zip,
                                                             0F, 12F, iTextSharp.text.Element.ALIGN_LEFT, _uspsFont);
                    PdfReports.AddText2Table(addrTable, p);

                    p = PdfReports.GetAddressBlock(item.Landowner_Name,
                                                   item.Ldo_Address_1,
                                                   item.Ldo_Address_2,
                                                   item.Ldo_City + ", " +
                                                   item.Ldo_State + " " +
                                                   item.Ldo_Zip,
                                                   0F, 12F, iTextSharp.text.Element.ALIGN_LEFT, _normalFont);
                    PdfReports.AddText2Table(addrTable, p);

                    PdfReports.AddText2Table(addrTable, " ", _normalFont, 3);
                    PdfReports.AddText2Table(addrTable, " ", _normalFont, 3);

                    PdfReports.AddTableNoSplit(document, pgEvent, addrTable);

                    acresContracted = item.Contract_Acres;
                    acresHarvested  = item.Harvest_Acres;
                    acresPlanted    = item.Planted_Acres;
                    acresLost       = acresPlanted - acresHarvested;

                    contractID = item.cnt_contract_id;
                    stationNo  = Convert.ToInt32(item.Station_Number);
                    factoryNo  = Convert.ToInt32(item.Factory_Number);
                }

                table = PdfReports.CreateTable(_primaryTableLayout, 0);

                List <ContractDeliverySummary2Item> cntDelSumList = WSCReportsExec.ContractDeliverySummary2(contractID);

                if (cntDelSumList.Count > 0)
                {
                    ContractDeliverySummary2Item cntdsItem = cntDelSumList[0];

                    PdfReports.AddText2Table(table, "Contract Tons: " + cntdsItem.ContractTons.ToString("#,###.0000"),
                                             _normalFont, 3);
                    PdfReports.AddText2Table(table, "Contract % Sugar: " + cntdsItem.SugarPct.ToString("0.00") + "%",
                                             _normalFont, 3);
                    PdfReports.AddText2Table(table, "Contract % SLM: " + cntdsItem.SLMPct.ToString("0.0000") + "%",
                                             _normalFont, 3);

                    string tonsPerAcre = null;
                    if (acresHarvested == 0)
                    {
                        tonsPerAcre = String.Format("{0:#,##0.00}", 0);
                    }
                    else
                    {
                        tonsPerAcre = (cntdsItem.ContractTons / acresHarvested).ToString("#,###.00");
                    }
                    PdfReports.AddText2Table(table, "Tons Per Acre: " + tonsPerAcre, _normalFont, 3);

                    PdfReports.AddText2Table(table, " ", _normalFont, 3);

                    extractableSugarPerTon = cntdsItem.ExtractableSugarPerTon;
                    PdfReports.AddText2Table(table, "Pounds Extractable Sugar Per Ton Contract: " +
                                             extractableSugarPerTon.ToString("#,##0"),
                                             _normalFont, 3);
                }


                int factoryExtSugarAvg, stationExtSugarAvg;

                WSCReportsExec.FactoryStationGetExtractSugarAvg(factoryNo, stationNo, cropYear, out factoryExtSugarAvg, out stationExtSugarAvg);

                if (stationExtSugarAvg != 0)
                {
                    PdfReports.AddText2Table(table, "Pounds Extractable Sugar Per Ton Receiving Station: " +
                                             stationExtSugarAvg.ToString("#,##0"), _normalFont, 3);
                }

                if (factoryExtSugarAvg != 0)
                {
                    PdfReports.AddText2Table(table, "Pounds Extractable Sugar Per Ton Factory: " +
                                             factoryExtSugarAvg.ToString("#,##0"), _normalFont, 3);
                }

                string percentOfStation = String.Format("{0:##0.00}", 0);
                string percentOfFactory = String.Format("{0:##0.00}", 0);

                if (stationExtSugarAvg != 0)
                {
                    percentOfStation = String.Format("{0:##0.00}", (extractableSugarPerTon / stationExtSugarAvg) * 100);
                }
                if (factoryExtSugarAvg != 0)
                {
                    percentOfFactory = String.Format("{0:##0.00}", (extractableSugarPerTon / factoryExtSugarAvg) * 100);
                }

                PdfReports.AddText2Table(table, "Percent of Station: " +
                                         percentOfStation + "%", _normalFont, 3);

                PdfReports.AddText2Table(table, "Percent of Factory: " +
                                         percentOfFactory + "%", _normalFont, 3);

                PdfReports.AddText2Table(table, " ", _normalFont, 3);

                PdfReports.AddText2Table(table, "Acres Contracted: " + acresContracted.ToString("#,##0"),
                                         _normalFont, 3);
                PdfReports.AddText2Table(table, "Acres Planted: " + acresPlanted.ToString("#,##0"),
                                         _normalFont, 3);
                PdfReports.AddText2Table(table, "Acres Lost: " + acresLost.ToString("#,##0"),
                                         _normalFont, 3);
                PdfReports.AddText2Table(table, "Acres Harvested: " + acresHarvested.ToString("#,##0"),
                                         _normalFont, 3);

                PdfReports.AddTableNoSplit(document, pgEvent, table);

                // ======================================================
                // Close document
                // ======================================================
                if (document != null)
                {
                    pgEvent.IsDocumentClosing = true;
                    document.Close();
                    document = null;
                }
                if (addrTable == null)
                {
                    // Warn that we have no data.
                    WSCIEMP.Common.CWarning warn = new WSCIEMP.Common.CWarning("No records matched your report criteria.");
                    throw (warn);
                }
            }
            catch (Exception ex) {
                string errMsg = "document is null: " + (document == null).ToString() + "; " +
                                "writer is null: " + (writer == null).ToString();
                WSCIEMP.Common.CException wscex = new WSCIEMP.Common.CException(METHOD_NAME + errMsg, ex);
                throw (wscex);
            }
            finally {
                if (document != null)
                {
                    pgEvent.IsDocumentClosing = true;
                    document.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }