class PdfTable extends Rectangle {

    // membervariables

    /**
     * Original table used to build this object
     */
    protected Table table;
    /**
     * Cached column widths.
     */
    protected float[] positions;
    /**
     * this is the number of columns in the table.
     */
    private int columns;
    /**
     * this is the ArrayList with all the cell of the table header.
     */
    private ArrayList<PdfCell> headercells;
    /**
     * this is the ArrayList with all the cells in the table.
     */
    private ArrayList<PdfCell> cells;

    // constructors

    /**
     * Constructs a <CODE>PdfTable</CODE>-object.
     *
     * @param table a <CODE>Table</CODE>
     * @param left  the left border on the page
     * @param right the right border on the page
     * @param top   the start position of the top of the table
     * @since a parameter of this method has been removed in iText 2.0.8
     */

    PdfTable(Table table, float left, float right, float top) {
        // constructs a Rectangle (the bottom value will be changed afterwards)
        super(left, top, right, top);
        this.table = table;
        table.complete();

        // copying the attributes from class Table
        cloneNonPositionParameters(table);

        this.columns = table.getColumns();
        positions = table.getWidths(left, right - left);

        // initialization of some parameters
        setLeft(positions[0]);
        setRight(positions[positions.length - 1]);

        headercells = new ArrayList<>();
        cells = new ArrayList<>();

        updateRowAdditionsInternal();
    }

    // methods

    /**
     * Updates the table row additions in the underlying table object and deletes all table rows, in order to preserve
     * memory and detect future row additions.
     * <p><b>Pre-requisite</b>: the object must have been built with the parameter
     * <code>supportUpdateRowAdditions</code> equals to true.
     */

    void updateRowAdditions() {
        table.complete();
        updateRowAdditionsInternal();
        table.deleteAllRows();
    }

    /**
     * Updates the table row additions in the underlying table object
     */

    private void updateRowAdditionsInternal() {<FILL_FUNCTION_BODY>}

    /**
     * Get the number of rows
     */

    int rows() {
        return cells.isEmpty() ? 0 : cells.get(cells.size() - 1).rownumber() + 1;
    }

    /**
     * @see com.lowagie.text.Element#type()
     */
    public int type() {
        return Element.TABLE;
    }

    /**
     * Returns the arraylist with the cells of the table header.
     *
     * @return an <CODE>ArrayList</CODE>
     */

    ArrayList<PdfCell> getHeaderCells() {
        return headercells;
    }

    /**
     * Checks if there is a table header.
     *
     * @return an <CODE>ArrayList</CODE>
     */

    boolean hasHeader() {
        return !headercells.isEmpty();
    }

    /**
     * Returns the arraylist with the cells of the table.
     *
     * @return an <CODE>ArrayList</CODE>
     */

    ArrayList<PdfCell> getCells() {
        return cells;
    }

    /**
     * Returns the number of columns of the table.
     *
     * @return the number of columns
     */

    int columns() {
        return columns;
    }

    /**
     * Returns the cellpadding of the table.
     *
     * @return the cellpadding
     */

    final float cellpadding() {
        return table.getPadding();
    }

    /**
     * Returns the cellspacing of the table.
     *
     * @return the cellspacing
     */

    final float cellspacing() {
        return table.getSpacing();
    }

    /**
     * Checks if this <CODE>Table</CODE> has to fit a page.
     *
     * @return true if the table may not be split
     */

    public final boolean hasToFitPageTable() {
        return table.isTableFitsPage();
    }

    /**
     * Checks if the cells of this <CODE>Table</CODE> have to fit a page.
     *
     * @return true if the cells may not be split
     */

    public final boolean hasToFitPageCells() {
        return table.isCellsFitPage();
    }

    /**
     * Gets the offset of this table.
     *
     * @return the space between this table and the previous element.
     */
    public float getOffset() {
        return table.getOffset();
    }
}

        // correct table : fill empty cells/ parse table in table
        Row row;
        int prevRows = rows();
        int rowNumber = 0;
        int groupNumber = 0;
        boolean groupChange;
        int firstDataRow = table.getLastHeaderRow() + 1;
        Cell cell;
        PdfCell currentCell;
        ArrayList<PdfCell> newCells = new ArrayList<>();
        int rows = table.size() + 1;
        float[] offsets = new float[rows];
        for (int i = 0; i < rows; i++) {
            offsets[i] = getBottom();
        }

        // loop over all the rows
        for (Iterator rowIterator = table.iterator(); rowIterator.hasNext(); ) {
            groupChange = false;
            row = (Row) rowIterator.next();
            if (row.isEmpty()) {
                if (rowNumber < rows - 1 && offsets[rowNumber + 1] > offsets[rowNumber]) {
                    offsets[rowNumber + 1] = offsets[rowNumber];
                }
            } else {
                for (int i = 0; i < row.getColumns(); i++) {
                    cell = (Cell) row.getCell(i);
                    if (cell != null) {
                        currentCell = new PdfCell(cell, rowNumber + prevRows, positions[i],
                                positions[i + cell.getColspan()], offsets[rowNumber], cellspacing(), cellpadding());
                        if (rowNumber < firstDataRow) {
                            currentCell.setHeader();
                            headercells.add(currentCell);
                            if (!table.isNotAddedYet()) {
                                continue;
                            }
                        }
                        try {
                            if (offsets[rowNumber] - currentCell.getHeight() - cellpadding() < offsets[rowNumber
                                    + currentCell.rowspan()]) {
                                offsets[rowNumber + currentCell.rowspan()] =
                                        offsets[rowNumber] - currentCell.getHeight() - cellpadding();
                            }
                        } catch (ArrayIndexOutOfBoundsException aioobe) {
                            if (offsets[rowNumber] - currentCell.getHeight() < offsets[rows - 1]) {
                                offsets[rows - 1] = offsets[rowNumber] - currentCell.getHeight();
                            }
                        }
                        currentCell.setGroupNumber(groupNumber);
                        groupChange |= cell.getGroupChange();
                        newCells.add(currentCell);
                    }
                }
            }
            rowNumber++;
            if (groupChange) {
                groupNumber++;
            }
        }

        // loop over all the cells
        int n = newCells.size();
        for (Object newCell : newCells) {
            currentCell = (PdfCell) newCell;
            try {
                currentCell.setBottom(offsets[currentCell.rownumber() - prevRows + currentCell.rowspan()]);
            } catch (ArrayIndexOutOfBoundsException aioobe) {
                currentCell.setBottom(offsets[rows - 1]);
            }
        }
        cells.addAll(newCells);
        setBottom(offsets[rows - 1]);
    
<methods>public void <init>(float, float, float, float) ,public void <init>(float, float) ,public void <init>(float, float, float, float, int) ,public void <init>(float, float, int) ,public void <init>(com.lowagie.text.Rectangle) ,public void cloneNonPositionParameters(com.lowagie.text.Rectangle) ,public void disableBorderSide(int) ,public void enableBorderSide(int) ,public java.awt.Color getBackgroundColor() ,public int getBorder() ,public java.awt.Color getBorderColor() ,public java.awt.Color getBorderColorBottom() ,public java.awt.Color getBorderColorLeft() ,public java.awt.Color getBorderColorRight() ,public java.awt.Color getBorderColorTop() ,public float getBorderWidth() ,public float getBorderWidthBottom() ,public float getBorderWidthLeft() ,public float getBorderWidthRight() ,public float getBorderWidthTop() ,public float getBottom() ,public float getBottom(float) ,public ArrayList<com.lowagie.text.Element> getChunks() ,public float getGrayFill() ,public float getHeight() ,public float getLeft() ,public float getLeft(float) ,public float getRelativeTop() ,public float getRight() ,public float getRight(float) ,public int getRotation() ,public float getTop() ,public float getTop(float) ,public float getWidth() ,public boolean hasBorder(int) ,public boolean hasBorders() ,public boolean isContent() ,public boolean isNestable() ,public boolean isUseVariableBorders() ,public void normalize() ,public boolean process(com.lowagie.text.ElementListener) ,public com.lowagie.text.Rectangle rectangle(float, float) ,public com.lowagie.text.Rectangle rotate() ,public void setBackgroundColor(java.awt.Color) ,public void setBorder(int) ,public void setBorderColor(java.awt.Color) ,public void setBorderColorBottom(java.awt.Color) ,public void setBorderColorLeft(java.awt.Color) ,public void setBorderColorRight(java.awt.Color) ,public void setBorderColorTop(java.awt.Color) ,public void setBorderWidth(float) ,public void setBorderWidthBottom(float) ,public void setBorderWidthLeft(float) ,public void setBorderWidthRight(float) ,public void setBorderWidthTop(float) ,public void setBottom(float) ,public void setGrayFill(float) ,public void setLeft(float) ,public void setRelativeTop(float) ,public void setRight(float) ,public void setRotation(int) ,public void setTop(float) ,public void setUseVariableBorders(boolean) ,public void softCloneNonPositionParameters(com.lowagie.text.Rectangle) ,public java.lang.String toString() ,public int type() <variables>public static final int BOTTOM,public static final int BOX,public static final int LEFT,public static final int NO_BORDER,public static final int RIGHT,public static final int TOP,public static final int UNDEFINED,protected java.awt.Color backgroundColor,protected int border,protected java.awt.Color borderColor,protected java.awt.Color borderColorBottom,protected java.awt.Color borderColorLeft,protected java.awt.Color borderColorRight,protected java.awt.Color borderColorTop,protected float borderWidth,protected float borderWidthBottom,protected float borderWidthLeft,protected float borderWidthRight,protected float borderWidthTop,protected float llx,protected float lly,protected float offsetToTop,protected int rotation,protected float urx,protected float ury,protected boolean useVariableBorders