public void TestEndOfRowRecords()
        {
            OpenNormal();

            // Find the cell at 0,0
            int cell00 = -1;
            for (int i = 0; i < r.Length; i++)
            {
                if (r[i] is LabelSSTRecord)
                {
                    LabelSSTRecord lr = (LabelSSTRecord)r[i];
                    if (lr.Row == 0 && lr.Column == 0) { cell00 = i; }
                }
            }
            Assert.IsTrue(cell00 > -1);

            // We have rows 0, 1, 2, 20 and 21
            // Row 0 has 1 entry
            // Row 1 has 4 entries
            // Row 2 has 6 entries
            // Row 20 has 5 entries
            // Row 21 has 7 entries
            // Row 22 has 12 entries

            // Row 0
            Assert.IsFalse(r[cell00 + 0] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 1] is LastCellOfRowDummyRecord);
            // Row 1
            Assert.IsFalse(r[cell00 + 2] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 3] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 4] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 5] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 6] is LastCellOfRowDummyRecord);
            // Row 2
            Assert.IsFalse(r[cell00 + 7] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 8] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 9] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 10] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 11] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 12] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 13] is LastCellOfRowDummyRecord);
            // Row 3 -> 19
            Assert.IsTrue(r[cell00 + 14] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 15] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 16] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 17] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 18] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 19] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 20] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 21] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 22] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 23] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 24] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 25] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 26] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 27] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 28] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 29] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 30] is LastCellOfRowDummyRecord);
            // Row 20
            Assert.IsFalse(r[cell00 + 31] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 32] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 33] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 34] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 35] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 36] is LastCellOfRowDummyRecord);
            // Row 21
            Assert.IsFalse(r[cell00 + 37] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 38] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 39] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 40] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 41] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 42] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 43] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 44] is LastCellOfRowDummyRecord);
            // Row 22
            Assert.IsFalse(r[cell00 + 45] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 46] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 47] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 48] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 49] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 50] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 51] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 52] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 53] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 54] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 55] is LastCellOfRowDummyRecord);
            Assert.IsFalse(r[cell00 + 56] is LastCellOfRowDummyRecord);
            Assert.IsTrue(r[cell00 + 57] is LastCellOfRowDummyRecord);

            // Check the numbers of the last seen columns
            LastCellOfRowDummyRecord[] lrs = new LastCellOfRowDummyRecord[24];
            int lrscount = 0;
            for (int i = 0; i < r.Length; i++)
            {
                if (r[i] is LastCellOfRowDummyRecord)
                {
                    lrs[lrscount] = (LastCellOfRowDummyRecord)r[i];
                    lrscount++;
                }
            }

            Assert.AreEqual(0, lrs[0].LastColumnNumber);
            Assert.AreEqual(0, lrs[0].Row);

            Assert.AreEqual(3, lrs[1].LastColumnNumber);
            Assert.AreEqual(1, lrs[1].Row);

            Assert.AreEqual(5, lrs[2].LastColumnNumber);
            Assert.AreEqual(2, lrs[2].Row);

            for (int i = 3; i <= 19; i++)
            {
                Assert.AreEqual(-1, lrs[i].LastColumnNumber);
                Assert.AreEqual(i, lrs[i].Row);
            }

            Assert.AreEqual(4, lrs[20].LastColumnNumber);
            Assert.AreEqual(20, lrs[20].Row);

            Assert.AreEqual(6, lrs[21].LastColumnNumber);
            Assert.AreEqual(21, lrs[21].Row);

            Assert.AreEqual(11, lrs[22].LastColumnNumber);
            Assert.AreEqual(22, lrs[22].Row);
        }
        /// <summary>
        /// Process an HSSF Record. Called when a record occurs in an HSSF file.
        /// </summary>
        /// <param name="record"></param>
        public void ProcessRecord(Record record)
        {
            int thisRow = -1;
            int thisColumn = -1;

            switch (record.Sid)
            {
                // the BOFRecord can represent either the beginning of a sheet or the workbook
                case BOFRecord.sid:
                    BOFRecord bof = (BOFRecord)record;
                    if (bof.Type == BOFRecord.TYPE_WORKBOOK)
                    {
                        // ReSet the row and column counts - new workbook
                        lastSeenRow = -1;
                        lastSeenColumn = -1;
                        //Console.WriteLine("Encountered workbook");
                    }
                    else if (bof.Type == BOFRecord.TYPE_WORKSHEET)
                    {
                        // ReSet the row and column counts - new sheet
                        lastSeenRow = -1;
                        lastSeenColumn = -1;
                        //Console.WriteLine("Encountered sheet reference");
                    }
                    break;
                case BoundSheetRecord.sid:
                    BoundSheetRecord bsr = (BoundSheetRecord)record;
                    //Console.WriteLine("New sheet named: " + bsr.GetSheetname());
                    break;
                case RowRecord.sid:
                    RowRecord rowrec = (RowRecord)record;
                    //Console.WriteLine("Row " + rowrec.RowNumber + " found, first column at "
                    //        + rowrec.GetFirstCol() + " last column at " + rowrec.GetLastCol());

                    // If there's a jump in rows, fire off missing row records
                    if (lastSeenRow + 1 < rowrec.RowNumber)
                    {
                        for (int i = (lastSeenRow + 1); i < rowrec.RowNumber; i++)
                        {
                            MissingRowDummyRecord dr = new MissingRowDummyRecord(i);
                            childListener.ProcessRecord(dr);
                        }
                    }

                    // Record this as the last row we saw
                    lastSeenRow = rowrec.RowNumber;
                    break;


                // These are all the "cell" records

                case BlankRecord.sid:
                    BlankRecord brec = (BlankRecord)record;
                    thisRow = brec.Row;
                    thisColumn = brec.Column;
                    break;
                case BoolErrRecord.sid:
                    BoolErrRecord berec = (BoolErrRecord)record;
                    thisRow = berec.Row;
                    thisColumn = berec.Column;
                    break;
                case FormulaRecord.sid:
                    FormulaRecord frec = (FormulaRecord)record;
                    thisRow = frec.Row;
                    thisColumn = frec.Column;
                    break;
                case LabelRecord.sid:
                    LabelRecord lrec = (LabelRecord)record;
                    thisRow = lrec.Row;
                    thisColumn = lrec.Column;
                    //Console.WriteLine("Cell found containing String "
                    //        + " at row " + lrec.Row + " and column " + lrec.Column);
                    break;
                case LabelSSTRecord.sid:
                    LabelSSTRecord lsrec = (LabelSSTRecord)record;
                    thisRow = lsrec.Row;
                    thisColumn = lsrec.Column;
                    //Console.WriteLine("Cell found containing String "
                    //        + " at row " + lsrec.Row + " and column " + lsrec.Column);
                    break;
                case NoteRecord.sid:
                    NoteRecord nrec = (NoteRecord)record;
                    thisRow = nrec.Row;
                    thisColumn = nrec.Column;
                    break;
                case NumberRecord.sid:
                    NumberRecord numrec = (NumberRecord)record;
                    thisRow = numrec.Row;
                    thisColumn = numrec.Column;
                    //Console.WriteLine("Cell found with value " + numrec.GetValue()
                    //        + " at row " + numrec.Row + " and column " + numrec.Column);
                    break;
                case RKRecord.sid:
                    RKRecord rkrec = (RKRecord)record;
                    thisRow = rkrec.Row;
                    thisColumn = rkrec.Column;
                    break;
                default:
                    //Console.WriteLine(record.GetClass());
                    break;
            }

            // Do we need to fire dummy end-of-row records?
            if (thisRow != lastSeenRow && lastSeenRow > -1)
            {
                for (int i = lastSeenRow; i < thisRow; i++)
                {
                    int cols = -1;
                    if (i == lastSeenRow)
                    {
                        cols = lastSeenColumn;
                    }
                    LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(i, cols);
                    childListener.ProcessRecord(r);
                }
            }
            // If we've finished with the columns, then fire the final
            //  dummy end-of-row record
            if (lastSeenRow != -1 && lastSeenColumn != -1 && thisRow == -1)
            {
                LastCellOfRowDummyRecord r = new LastCellOfRowDummyRecord(lastSeenRow, lastSeenColumn);
                childListener.ProcessRecord(r);

                lastSeenRow = -1;
                lastSeenColumn = -1;
            }

            // If we've moved onto a new row, the ensure we re-Set
            //  the column counter
            if (thisRow != lastSeenRow)
            {
                lastSeenColumn = -1;
            }

            // Do we need to fire dummy cell records?
            if (lastSeenColumn != (thisColumn - 1))
            {
                for (int i = lastSeenColumn + 1; i < thisColumn; i++)
                {
                    MissingCellDummyRecord r = new MissingCellDummyRecord(thisRow, i);
                    childListener.ProcessRecord(r);
                }
            }

            // Update cell and row counts if doing cells
            if (thisColumn != -1)
            {
                lastSeenRow = thisRow;
                lastSeenColumn = thisColumn;
            }

            childListener.ProcessRecord(record);
        }