public void updateSystemControlledColumnValues() {

    final DynamicData data = widget.getGridWidget().getData();
    final List<DynamicColumn<DTColumnConfig>> columns = widget.getGridWidget().getColumns();

    for (DynamicColumn<DTColumnConfig> col : columns) {

      DTColumnConfig modelColumn = col.getModelColumn();

      if (modelColumn instanceof RowNumberCol) {
        updateRowNumberColumnValues(data, col.getColumnIndex());

      } else if (modelColumn instanceof AttributeCol) {

        // Update Salience values
        AttributeCol attrCol = (AttributeCol) modelColumn;
        if (attrCol.getAttribute().equals(RuleAttributeWidget.SALIENCE_ATTR)) {
          if (attrCol.isUseRowNumber()) {
            updateSalienceColumnValues(data, col.getColumnIndex(), attrCol.isReverseOrder());
          }

          // Ensure Salience cells are rendered with the correct Cell
          col.setCell(cellFactory.getCell(attrCol));
          col.setSystemControlled(attrCol.isUseRowNumber());
          col.setSortable(!attrCol.isUseRowNumber());
        }
      }
    }
  }
 // Ensure the values in a column are within the Value List
 private boolean updateCellsForOptionValueList(
     final DTColumnConfig editColumn, final DynamicColumn<DTColumnConfig> column) {
   boolean bRedrawRequired = false;
   DynamicData data = widget.getGridWidget().getData();
   List<String> vals = Arrays.asList(model.getValueList(editColumn, sce));
   column.setCell(cellFactory.getCell(editColumn));
   int iCol = column.getColumnIndex();
   for (int iRow = 0; iRow < data.size(); iRow++) {
     DynamicDataRow row = data.get(iRow);
     if (!vals.contains(row.get(iCol).getValue())) {
       row.get(iCol).setValue(null);
       bRedrawRequired = true;
     }
   }
   return bRedrawRequired;
 }
  // Ensure the Column cell type and corresponding values are correct
  private void updateCellsForDataType(
      final DTColumnConfig editColumn, final DynamicColumn<DTColumnConfig> column) {

    // Grouping needs to be removed
    if (widget.getGridWidget().getData().isMerged()) {
      widget.getGridWidget().toggleMerging();
    }

    DynamicData data = widget.getGridWidget().getData();
    column.setCell(cellFactory.getCell(editColumn));
    for (int iRow = 0; iRow < data.size(); iRow++) {
      DynamicDataRow row = data.get(iRow);
      row.set(
          column.getColumnIndex(),
          cellValueFactory.makeCellValue(editColumn, iRow, column.getColumnIndex()));
    }
  }
  // Insert a new model column at the specified index
  private void insertColumnBefore(DTColumnConfig modelColumn, int index, boolean bRedraw) {

    // Create new column for grid
    DynamicColumn<DTColumnConfig> column =
        new DynamicColumn<DTColumnConfig>(modelColumn, cellFactory.getCell(modelColumn), index);
    column.setVisible(!modelColumn.isHideColumn());
    DynamicColumn<DTColumnConfig> columnBefore = widget.getGridWidget().getColumns().get(index);

    // Create column data
    DynamicData data = widget.getGridWidget().getData();
    List<CellValue<? extends Comparable<?>>> columnData =
        new ArrayList<CellValue<? extends Comparable<?>>>();
    for (int iRow = 0; iRow < data.size(); iRow++) {
      DTCellValue dcv = new DTCellValue(modelColumn.getDefaultValue());
      CellValue<?> cell = cellValueFactory.makeCellValue(modelColumn, iRow, index, dcv);
      columnData.add(cell);
    }

    // Add column and data to grid
    widget.insertColumnBefore(columnBefore, column, columnData, bRedraw);
  }
  /**
   * Set the Decision Table's data. This removes all existing columns from the Decision Table and
   * re-creates them based upon the provided data.
   *
   * @param data
   */
  public void setModel(TypeSafeGuidedDecisionTable model) {
    if (model == null) {
      throw new IllegalArgumentException("model cannot be null");
    }

    this.model = model;
    this.cellFactory = new DecisionTableCellFactory(sce, widget.getGridWidget(), this.model);
    this.cellValueFactory = new DecisionTableCellValueFactory(sce, this.model);

    // Date converter is injected so a GWT compatible one can be used here and another in testing
    DecisionTableCellValueFactory.injectDateConvertor(GWTDateConverter.getInstance());

    // Setup command to recalculate System Controlled values when rows are added\deleted
    widget
        .getGridWidget()
        .getData()
        .setOnRowChangeCommand(
            new Command() {

              public void execute() {
                updateSystemControlledColumnValues();
              }
            });

    widget.getGridWidget().getData().clear();
    widget.getGridWidget().getColumns().clear();

    // Dummy rows because the underlying DecoratedGridWidget expects there
    // to be enough rows to receive the columns data
    final DynamicData data = widget.getGridWidget().getData();
    for (int iRow = 0; iRow < model.getData().size(); iRow++) {
      data.addRow();
    }

    // Static columns, Row#
    int colIndex = 0;
    DTColumnConfig colStatic;
    DynamicColumn<DTColumnConfig> columnStatic;
    colStatic = model.getRowNumberCol();
    columnStatic =
        new DynamicColumn<DTColumnConfig>(
            colStatic, cellFactory.getCell(colStatic), colIndex, true, false);
    columnStatic.setWidth(24);
    widget.appendColumn(columnStatic, makeColumnData(colStatic, colIndex++), false);

    // Static columns, Description
    colStatic = model.getDescriptionCol();
    columnStatic =
        new DynamicColumn<DTColumnConfig>(colStatic, cellFactory.getCell(colStatic), colIndex);
    widget.appendColumn(columnStatic, makeColumnData(colStatic, colIndex++), false);

    // Initialise CellTable's Metadata columns
    for (DTColumnConfig col : model.getMetadataCols()) {
      DynamicColumn<DTColumnConfig> column =
          new DynamicColumn<DTColumnConfig>(col, cellFactory.getCell(col), colIndex);
      column.setVisible(!col.isHideColumn());
      widget.appendColumn(column, makeColumnData(col, colIndex++), false);
    }

    // Initialise CellTable's Attribute columns
    for (DTColumnConfig col : model.getAttributeCols()) {
      DynamicColumn<DTColumnConfig> column =
          new DynamicColumn<DTColumnConfig>(col, cellFactory.getCell(col), colIndex);
      column.setVisible(!col.isHideColumn());
      column.setSystemControlled(col.isUseRowNumber());
      column.setSortable(!col.isUseRowNumber());
      widget.appendColumn(column, makeColumnData(col, colIndex++), false);
    }

    // Initialise CellTable's Condition columns
    assertConditionColumnGrouping(model);
    for (DTColumnConfig col : model.getConditionCols()) {
      DynamicColumn<DTColumnConfig> column =
          new DynamicColumn<DTColumnConfig>(col, cellFactory.getCell(col), colIndex);
      column.setVisible(!col.isHideColumn());
      widget.appendColumn(column, makeColumnData(col, colIndex++), false);
    }

    // Initialise CellTable's Action columns
    for (DTColumnConfig col : model.getActionCols()) {
      DynamicColumn<DTColumnConfig> column =
          new DynamicColumn<DTColumnConfig>(col, cellFactory.getCell(col), colIndex);
      column.setVisible(!col.isHideColumn());
      widget.appendColumn(column, makeColumnData(col, colIndex++), false);
    }

    // Ensure System Controlled values are correctly initialised
    updateSystemControlledColumnValues();

    // Draw header first as the size of child Elements depends upon it
    widget.getHeaderWidget().redraw();
    widget.getSidebarWidget().redraw();

    // Schedule redraw of grid after sizes of child Elements have been set
    Scheduler.get()
        .scheduleFinally(
            new ScheduledCommand() {

              public void execute() {
                widget.getGridWidget().redraw();
              }
            });
  }