protected void generateRowData(RowDetails rowDetails) {
        List<Column> columns = rowDetails.getTable().getColumns();
        List<Object> cellValues = new ArrayList<Object>();
        
        //If column is configured as 'generates own data', then there would
        //be less number of cell values in the row. We need to fill those
        //missing cell values with null before asking call back to generate
        //the data. This is to make sure column index reference is consistent.
        int skippedColumns = 0;
        for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
            Column column = columns.get(columnIndex);
            CellDetails cellDetails = new CellDetails(rowDetails, columnIndex - skippedColumns);
            cellDetails.setColumn(column);
            
            if (column.isGeneratesOwnData()) {
                cellValues.add(null);
                skippedColumns++;
            } else {
                Object cellValue = null;
                
                if (rowDetails.getRow() instanceof BeanRow) {
                    BeanRow beanRow = (BeanRow) rowDetails.getRow();
                    cellValue = beanRow.getCellValue(column.getName());
                } else {
                    //If there are less number of cells added to the row than there are columns,
                    //we would assume rest of the cells as nulls.
                    if (rowDetails.getRow().getCellValues().size() > cellDetails.getColumnIndex()) {
                        cellValue = rowDetails.getRow().getCellValue(cellDetails);
                    }
                }
                
                if (cellValue == null) {
                    cellValue = options.getNullString();
                }
                cellValues.add(cellValue);
            }
        }
        
        rowDetails.getRow().setCellValues(cellValues);
        
        //Go ahead and ask the call back to generate the data for such column.
        //After generating the data, go ahead and ask the callback to override if
        //applicable.
        for (int columnIndex = 0; columnIndex < columns.size(); columnIndex++) {
            
            CellDetails cellDetails = new CellDetails(rowDetails, columnIndex);
            Object cellValue = null;
            Column column = columns.get(columnIndex);
            
            if (column.isGeneratesOwnData()) {
                if (column.getCellValueGenerator() == null) {
                    throw new RuntimeException("Column " + column +  " configured as own data generator but callback is not configured.");
                }
                cellValue = column.getCellValueGenerator().generateCellValue(cellDetails);
            } else {
                cellValue = rowDetails.getRow().getCellValue(cellDetails);
            }
            cellDetails.setCellValue(cellValue);
            
            rowDetails.getRow().setCellValue(columnIndex, cellValue);
        }
    }