/// <summary>
        /// Fills the AccountAddress object.
        /// </summary>
        /// <param name="baseResponse"></param>
        public void Fill(Account account)
        {
            try
            {
                // get address.
                this.Fill((AccountAddress)account);
                DalAccount dalAccount = new DalAccount();
                // now get statement informatin.
                CustomerAccountSchema.CustomerStatementsDataTable statements =
                    dalAccount.GetCustomerStatements(_siteId, _siteCode, _accountNumber.AccountNumber9);

                // the customer statement data table returns back 1 record for each statementCode
                // and serviceCode. However, our return sums up these results. this means we need
                // to track when we have a new statement code.
                int       previousStatementCode = -1;
                Statement statement             = null;
                for (int i = 0; i < statements.Count; i++)
                {
                    CustomerAccountSchema.CustomerStatement stmnt = statements[i];
                    int statementCode = (int)stmnt.StatementCode;
                    // these values only change when the statement code changes.
                    if (previousStatementCode != statementCode)
                    {
                        // create a new statement and add it to the account.
                        double           amountBilled      = (double)stmnt.AmountBilled;
                        Icoms1900Date    lastStatementDate = new Icoms1900Date((int)stmnt.LastStatementDate);
                        eStatementStatus statementStatus   = (eStatementStatus)TypeDescriptor.GetConverter(
                            typeof(eStatementStatus)).ConvertFrom(stmnt.Status);

                        // ok, we care about all statements, except...
                        if (statementStatus == eStatementStatus.Cancelled ||
                            statementStatus == eStatementStatus.Disconnect)
                        {
                            //we want to show cancelled or disconnected
                            //statements that have been billed within the
                            //last 100 days or if the statement still has
                            //a balance. Otherwise we get the next statement
                            if ((!lastStatementDate.SpecialDate &&
                                 (DateTime.Now - lastStatementDate).Days > __statementDays) &&
                                amountBilled <= 0)
                            {
                                continue;                                 //get the next statement
                            }
                        }
                        // set this first off.
                        previousStatementCode = statementCode;
                        // need this for later.
                        string paddedStatementCode = statementCode.ToString().PadLeft(3, '0');
                        // create new statement object and add it to collection.
                        statement = new Statement();
                        account.Statements.Add(statement);
                        statement.AccountNumber16 = paddedStatementCode + _accountNumber.AccountNumber13;
                        statement.StatementCode   = paddedStatementCode;
                        statement.AmountBilled    = amountBilled;
                        statement.BillingOption   = (eBillingOption)TypeDescriptor.GetConverter(
                            typeof(eBillingOption)).ConvertFrom(stmnt.BillHandlingCode);
                        // this is the balance outstanding net of any charges not billed.
                        Icoms1900Date dueDate = new Icoms1900Date((int)stmnt.DueDate);
                        statement.DueOnReceipt = dueDate.SpecialDate;
                        statement.DueDate      = dueDate.SpecialDate == true?DateTime.MinValue:(DateTime)dueDate;
                        int mopCode = (int)stmnt.MopCode;
                        statement.EasyPayFlag    = mopCode != 0;
                        statement.EasyPayMopType = statement.EasyPayFlag ?
                                                   (ePaymentType) new MopPaymentType(_userName, mopCode) :
                                                   ePaymentType.Unknown;
                        statement.LastStatementDate = new Icoms1900Date((int)stmnt.LastStatementDate);

                        // adjustment amounts
                        UnappliedAmounts unappliedAmounts = dalAccount.GetUnappliedPaymentAmount(
                            _siteId, _siteCode, _accountNumber.AccountNumber9, statementCode);
                        statement.UnappliedPaymentAmount          = unappliedAmounts.Payments;
                        statement.UnappliedAdjustmentAmount       = unappliedAmounts.NetAdjustments;
                        statement.UnappliedDebitAdjustmentAmount  = unappliedAmounts.DebitAdjustments;
                        statement.UnappliedCreditAdjustmentAmount = unappliedAmounts.CreditAdjustments;

                        // pending amount
                        statement.PendingPaymentAmount = dalAccount.GetPendingPaymentAmount(
                            _siteId, _siteCode, _accountNumber.AccountNumber9, statementCode);

                        // now. let's start setting the fields that are a calculation of 1-N
                        // other fields. however, we only want to set that portion of the value
                        // that is calculated once per statement (remember GetCustomerStatements()
                        // may return multiple records for a single statement we return to a customer)
                        // This means if the calculated value of the field depends upon the following
                        // items, we want to include it in our calculation here:
                        //	a) A PendingPayment
                        //	b) UnappliedDebitAdjustment
                        //	c) UnappliedCreditAdjustment
                        //	d) UnappliedNetAdjustment(net of debit and credit).
                        //  e) Any field that includes BALANCE_LAST_STATEMENT
                        //	f) Any field that includes LAST_PAYMENT_AMOUNT1,2 or 3

                        statement.Status = statementStatus;
                        if (stmnt.LastPaymentDate1 > 0)
                        {
                            statement.RecentPayments.Add(
                                new PaymentItem((double)stmnt.LastPaymentAmount1,
                                                new Icoms1900Date((int)stmnt.LastPaymentDate1)));
                        }
                        if (stmnt.LastPaymentDate2 > 0)
                        {
                            statement.RecentPayments.Add(
                                new PaymentItem((double)stmnt.LastPaymentAmount2,
                                                new Icoms1900Date((int)stmnt.LastPaymentDate2)));
                        }
                        if (stmnt.LastPaymentDate3 > 0)
                        {
                            statement.RecentPayments.Add(
                                new PaymentItem((double)stmnt.LastPaymentAmount3,
                                                new Icoms1900Date((int)stmnt.LastPaymentDate3)));
                        }
                    }
                    // HERE WE WANT TO SET THOSE VALUES THAT CHANGE ON A PER RECORD
                    // BASIS. REMEMBER THAT GetCustomerStatements() CAN RETURN MULTIPLE
                    // RECORDS PER STATEMENT DUE TO AR AGING TRACKING AMOUNTS AT THE
                    // PRODUCT LEVEL (E.G. CABLE, DATA, CALLING CARD, TELEPHONE).

                    // add service code to service code collection.
                    statement.ServiceCategories.Add((eServiceCategory)TypeDescriptor.GetConverter(
                                                        typeof(eServiceCategory)).ConvertFrom(stmnt.ServiceCode));
                    // modify deposit due.
                    statement.DepositDueAmount += (double)stmnt.DepositDueAmount;
                    // next writeoffamount.
                    statement.WriteOffAmount += (double)stmnt.WriteOffAmount;
                    // current ar balance.
                    statement.CurrentBalance += (double)stmnt.ArBalanceAmount;
                    // next adjust the current bucket.
                    statement.CurrentBucket += (double)stmnt.CurrentArBalanceAmount;
                    // are 1-30 bucket.
                    statement.AR1To30Amount += (double)stmnt.Ar1To30Amount;
                    // are 31-60 bucket.
                    statement.AR31To60Amount += (double)stmnt.Ar31To60Amount;
                    // are 61-90 bucket.
                    statement.AR61To90Amount += (double)stmnt.Ar61To90Amount;
                    // are 91-120 bucket.
                    statement.AR91To120Amount += (double)stmnt.Ar91To120Amount;
                    // are 121-150 bucket.
                    statement.AR121To150Amount += (double)stmnt.Ar121To150Amount;
                    // are 150 plus bucket.
                    statement.AR150PlusAmount += (double)stmnt.Ar150PlusAmount;
                }
                for (int j = 0; j < account.Statements.Count; j++)
                {
                    Statement baseStatement = account.Statements[j];
                    double    totalPending  =
                        baseStatement.UnappliedPaymentAmount +
                        baseStatement.PendingPaymentAmount;

                    // set current balance
                    baseStatement.CurrentBalance =
                        Math.Round(baseStatement.CurrentBalance +
                                   baseStatement.DepositDueAmount +
                                   baseStatement.WriteOffAmount +
                                   baseStatement.UnappliedAdjustmentAmount -
                                   totalPending, 2);

                    // now set the different ar aging buckets. NOTE: I know that I am not
                    // using all of these fields at this time; however, we are trying to
                    // mimic the green screens and our needs may change down the road. So,
                    // I am calculating them now so some other poor soul doesn't have to
                    // go through it again. Also, I have set XmlIgnoreAttribute() on many
                    // of these fields to prevent them from being streamed to our SOA clients.
                    // if you want them to be streamed to the client merely change XmlIgnore()
                    // to XmlAttribute("NameOfProperty").
                    if (totalPending > 0)
                    {
                        double amt       = baseStatement.DepositDueAmount;
                        bool   keepGoing = netOutAmounts(ref amt, ref totalPending);
                        baseStatement.DepositDueAmount = Math.Round(amt, 2);
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR150PlusAmount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR150PlusAmount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR121To150Amount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR121To150Amount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR91To120Amount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR91To120Amount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR61To90Amount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR61To90Amount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR31To60Amount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR31To60Amount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            amt       = baseStatement.AR1To30Amount;
                            keepGoing = netOutAmounts(ref amt, ref totalPending);
                            baseStatement.AR1To30Amount = Math.Round(amt, 2);
                        }
                        if (keepGoing)
                        {
                            baseStatement.CurrentBucket -= totalPending;
                        }
                    }
                    // now modify current bucket by unapplied debit adjustments.
                    baseStatement.CurrentBucket = Math.Round(
                        baseStatement.CurrentBucket +
                        baseStatement.UnappliedDebitAdjustmentAmount, 2);
                    // now set minimumDue.
                    baseStatement.MinimumDue = Math.Round(baseStatement.CurrentBalance -
                                                          baseStatement.CurrentBucket - baseStatement.AR1To30Amount, 2);
                    // make sure it doesn't go below 0
                    if (baseStatement.MinimumDue < 0)
                    {
                        statement.MinimumDue = 0;
                    }
                }
            }
            catch (BusinessLogicLayerException)
            {
                // already handled
                throw;
            }
            catch (DataSourceException dse)
            {
                // not handled. need to handle
                throw new DataSourceUnavailableException(dse);
            }
            catch (Exception ex)
            {
                // not handled. need to handle
                throw new UnexpectedSystemException(ex);
            }
        }