TEST_FIXTURE(TableLayouterTestFixture, create_cell_layouters_2)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        create_doc_2(spDoc);
            //   50  40  25  15  20
            //  +---+---+---+---+---+
            //  | 0 |   1   |   3   |
            //  +---+---+---+---+---+
            //  | 5 | 6 | 7 | 8 | 9 +
            //  +---+---+---+---+---+
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_head_layouter() == nullptr );
        TableSectionLayouter* pSL = lyt.my_get_body_layouter();
        CHECK( pSL != nullptr );
        vector<TableCellLayouter*>& cellLyt = pSL->dbg_get_cell_layouters();
        CHECK( cellLyt.size() == 10 );

        CHECK( cellLyt[0]->get_cell_width() == 5000.0f );   //   50  40  25  15  20
        CHECK( cellLyt[1]->get_cell_width() == 6500.0f );   //  +---+---+---+---+---+
        CHECK( cellLyt[2] == nullptr );                        //  | 0 |   1   |   3   |
        CHECK( cellLyt[3]->get_cell_width() == 3500.0f );   //  +---+---+---+---+---+
        CHECK( cellLyt[4] == nullptr );                        //  | 5 | 6 | 7 | 8 | 9 +
        //                                                  //  +---+---+---+---+---+
        CHECK( cellLyt[5]->get_cell_width() == 5000.0f );
        CHECK( cellLyt[6]->get_cell_width() == 4000.0f );
        CHECK( cellLyt[7]->get_cell_width() == 2500.0f );
        CHECK( cellLyt[8]->get_cell_width() == 1500.0f );
        CHECK( cellLyt[9]->get_cell_width() == 2000.0f );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_determine_grid_size_3)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string("(lenmusdoc (vers 0.0) "
            "(content (table "
                "(tableBody"
                    "(tableRow"
                        "(tableCell (txt \"0\") )"
                        "(tableCell (rowspan 2)(colspan 2)(txt \"0,2,5,6\") )"
                        "(tableCell (txt \"3\") )"
                    ")"
                    "(tableRow"
                        "(tableCell (txt \"4\") )"
                        "(tableCell (txt \"7\") )"
                    ")"
                ")"
            ")"
            "))");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_num_head_rows() == 0 );
        CHECK( lyt.my_get_num_body_rows() == 2 );
        CHECK( lyt.my_get_num_cols() == 4 );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_determine_grid_size_2)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string("(lenmusdoc (vers 0.0) "
            "(content (table "
                "(tableHead "
                "    (tableRow (tableCell (txt \"Cell 1,1\"))"
                "              (tableCell (colspan 2)(txt \"Cell 1,2\")) )"
                ")"
                "(tableBody "
                "    (tableRow (tableCell (txt \"Cell 1,1\"))"
                "              (tableCell (txt \"Cell 1,2\"))"
                "              (tableCell (txt \"Cell 1,3\")) )"
                "    (tableRow (tableCell (txt \"Cell 2,1\"))"
                "              (tableCell (txt \"Cell 2,2\"))"
                "              (tableCell (txt \"Cell 2,3\")) )"
                ")"
            ")) )");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );

        GraphicModel model;

        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

//        cout << "head rows=" << lyt.my_get_num_head_rows() << endl;
//        cout << "body rows=" << lyt.my_get_num_body_rows() << endl;
//        cout << "cols=" << lyt.my_get_num_cols() << endl;
        CHECK( lyt.my_get_num_head_rows() == 1 );
        CHECK( lyt.my_get_num_body_rows() == 2 );
        CHECK( lyt.my_get_num_cols() == 3 );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_box_created)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string("(lenmusdoc (vers 0.0) "
            "(pageLayout (pageSize 24000 35700)(pageMargins 1000 1500 3000 2500 4000) landscape) "
            "(content (table "
                "(tableHead (tableRow (tableCell (txt \"This is a head cell\")) ))"
                "(tableBody (tableRow (tableCell (txt \"This is a body cell\")) ))"
            ") ))");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );

        GraphicModel model;
        GmoBoxDocPage page(nullptr);
        GmoBoxDocPageContent box(nullptr);
        box.set_owner_box(&page);

        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();
        lyt.create_main_box(&box, UPoint(0.0f, 0.0f), 10000.0f, 20000.0f);

        GmoBox* pTableBox = lyt.my_get_main_box();
        CHECK( pTableBox != nullptr );
    }
    TEST_FIXTURE(TableLayouterTestFixture, create_cell_layouters_3)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        create_doc_3(spDoc);
        //      7000      8000      9000        7000
        //  +----------+--------------------+----------+
        //  |          |      Bolfgums      |   Eesh   |
        //  |          +---------+----------+   data   |
        //  |          | forward | backward |          |
        //  +----------+---------+----------+----------+
        //  | Flumbos  |   270   |   177    |          |
        //  +----------+---------+----------+    37%   |
        //  | Garblos  |   315   |   187    |          |
        //  +----------+---------+----------+----------+
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        TableSectionLayouter* pSH = lyt.my_get_head_layouter();
        CHECK( pSH != nullptr );
        vector<TableCellLayouter*>& cellLytH = pSH->dbg_get_cell_layouters();
        CHECK( cellLytH.size() == 8 );

        CHECK( is_equal_pos(cellLytH[0]->get_cell_width(), 7000.0f) );
        CHECK( is_equal_pos(cellLytH[1]->get_cell_width(), 17000.0f) );
        CHECK( cellLytH[2] == nullptr );
        CHECK( is_equal_pos(cellLytH[3]->get_cell_width(), 7000.0f) );

        CHECK( cellLytH[4] == nullptr );
        CHECK( is_equal_pos(cellLytH[5]->get_cell_width(), 8000.0f) );
        CHECK( is_equal_pos(cellLytH[6]->get_cell_width(), 9000.0f) );
        CHECK( cellLytH[7] == nullptr );

        TableSectionLayouter* pSB = lyt.my_get_body_layouter();
        CHECK( pSB != nullptr );
        vector<TableCellLayouter*>& cellLytB = pSB->dbg_get_cell_layouters();
        CHECK( cellLytB.size() == 8 );

        CHECK( is_equal_pos(cellLytB[0]->get_cell_width(), 7000.0f) );
        CHECK( is_equal_pos(cellLytB[1]->get_cell_width(), 8000.0f) );
        CHECK( is_equal_pos(cellLytB[2]->get_cell_width(), 9000.0f) );
        CHECK( is_equal_pos(cellLytB[3]->get_cell_width(), 7000.0f) );

        CHECK( is_equal_pos(cellLytB[4]->get_cell_width(), 7000.0f) );
        CHECK( is_equal_pos(cellLytB[5]->get_cell_width(), 8000.0f) );
        CHECK( is_equal_pos(cellLytB[6]->get_cell_width(), 9000.0f) );
        CHECK( cellLytB[7] == nullptr );
    }
    TEST_FIXTURE(TableLayouterTestFixture, body_layouter_created_1)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        create_doc_1(spDoc);
        //    +---+---+---+---+
        //    | 0 |       | 3 |
        //    +---+   1   +---+
        //    | 4 |       | 7 |
        //    +---+---+---+---+
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_head_layouter() == nullptr );
        TableSectionLayouter* pSL = lyt.my_get_body_layouter();
        CHECK( pSL != nullptr );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_determine_widths_1)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string("(lenmusdoc (vers 0.0) "
            "(styles"
                "(defineStyle \"table1-col1\" (table-col-width 5000))"
                "(defineStyle \"table1-col2\" (table-col-width 4000))"
                "(defineStyle \"table1-col3\" (table-col-width 2500))"
            ")"
            "(content (table "
                "(tableColumn (style \"table1-col1\"))"
                "(tableColumn (style \"table1-col2\"))"
                "(tableColumn (style \"table1-col3\"))"
                "(tableBody"
                    "(tableRow"
                        "(tableCell (txt \"0\") )"
                        "(tableCell (txt \"1+(2,5,6)\") )"
                        "(tableCell (txt \"3\") )"
                    ")"
                    "(tableRow"
                        "(tableCell (txt \"4\") )"
                        "(tableCell (txt \"7\") )"
                        "(tableCell (txt \"8\") )"
                    ")"
                ")"
            ")"
            "))");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_num_cols() == 3 );
        CHECK( lyt.my_get_column_width(0) == 5000.0f );
        CHECK( lyt.my_get_column_width(1) == 4000.0f );
        CHECK( lyt.my_get_column_width(2) == 2500.0f );
        CHECK( lyt.my_get_table_width() == 11500.0f );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_determine_widths_3)
    {
        //       7000   8000
        //    +-------+-------+
        //    |   0H  |   1H  |
        //    +=======+=======+
        //    |   0B  |   1B  |
        //    +-------+-------+
        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string(
            "(lenmusdoc (vers 0.0)"
            "(styles"
            "   (defineStyle \"table1-col1\" (table-col-width 7000))"
            "   (defineStyle \"table1-col2\" (table-col-width 8000))"
            ")"
            "(content (table "
                "(tableColumn (style \"table1-col1\"))"
                "(tableColumn (style \"table1-col2\"))"
                "(tableHead (tableRow"
                    "(tableCell (txt \"This is head cell 1\"))"
                    "(tableCell (txt \"This is head cell 2\"))"
                "))"
                "(tableBody (tableRow"
                    "(tableCell (txt \"This is body cell 1\"))"
                    "(tableCell (txt \"This is body cell 2\"))"
                "))"
            ")) )");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_num_cols() == 2 );
        CHECK( is_equal_pos(lyt.my_get_column_width(0), 7000.0f) );
        CHECK( is_equal_pos(lyt.my_get_column_width(1), 8000.0f) );
        CHECK( is_equal_pos(lyt.my_get_table_width(), 15000.0f) );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_determine_widths_2)
    {
        SpDocument spDoc( new Document(m_libraryScope) );
        create_doc_1(spDoc);
        //    +---+---+---+---+
        //    | 0 |       | 3 |
        //    +---+   1   +---+
        //    | 4 |       | 7 |
        //    +---+---+---+---+
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        CHECK( lyt.my_get_num_cols() == 4 );
        CHECK( lyt.my_get_column_width(0) == 5000.0f );
        CHECK( lyt.my_get_column_width(1) == 4000.0f );
        CHECK( lyt.my_get_column_width(2) == 2500.0f );
        CHECK( lyt.my_get_column_width(3) == 1500.0f );
        CHECK( lyt.my_get_table_width() == 13000.0f );
    }
    TEST_FIXTURE(TableLayouterTestFixture, table_logical_rows_4)
    {
//        +---+---+---+
//        | 0 | 1 | 2 |
//        +---+   +   +
//        | 3 |   |   |
//        +---+---+   +
//        | 6 | 7 |   |
//        +---+---+---+
//        | 9 |10 |11 |
//        +---+---+---+

        SpDocument spDoc( new Document(m_libraryScope) );
        spDoc->from_string(
            "(lenmusdoc (vers 0.0)"
            "(styles"
            "   (defineStyle \"table1-col1\" (table-col-width 70))"
            "   (defineStyle \"table1-col2\" (table-col-width 80))"
            "   (defineStyle \"table1-col3\" (table-col-width 90))"
            ")"
            "(content (table "
                "(tableColumn (style \"table1-col1\"))"
                "(tableColumn (style \"table1-col2\"))"
                "(tableColumn (style \"table1-col3\"))"
                "(tableBody"
                    "(tableRow"
                        "(tableCell (txt \"cell 0\") )"
                        "(tableCell (rowspan 2)(txt \"cell 1\") )"
                        "(tableCell (rowspan 3)(txt \"cell 2\") )"
                    ")"
                    "(tableRow"
                        "(tableCell (txt \"cell 3\") )"
                    ")"
                    "(tableRow"
                        "(tableCell (txt \"cell 6\") )"
                        "(tableCell (txt \"cell 7\") )"
                    ")"
                    "(tableRow"
                        "(tableCell (txt \"cell 9\") )"
                        "(tableCell (txt \"cell 10\") )"
                        "(tableCell (txt \"cell 11\") )"
                    ")"
                ")"
            ")"
            "))");
        ImoDocument* pDoc = spDoc->get_im_root();
        ImoStyles* pStyles = pDoc->get_styles();
        ImoTable* pTable = static_cast<ImoTable*>( pDoc->get_content_item(0) );
        GraphicModel model;
        MyTableLayouter lyt(pTable, &model, m_libraryScope, pStyles);
        lyt.prepare_to_start_layout();

        TableSectionLayouter* pSH = lyt.my_get_head_layouter();
        CHECK( pSH == nullptr );

        TableSectionLayouter* pSB = lyt.my_get_body_layouter();
        CHECK( pSB != nullptr );
        vector<int>& rowStart = pSB->dbg_get_row_start();
//        cout << "size=" <<  rowStart.size() << endl;
        CHECK( rowStart.size() == 2 );
        CHECK( rowStart[0] == 0 );
        CHECK( rowStart[1] == 3 );
    }