/**
   * Construct a new row of data for the MergableGridWidget
   *
   * @return
   */
  @Override
  public DynamicDataRow makeUIRowData() {
    DynamicDataRow data = new DynamicDataRow();
    List<BaseColumn> columns = model.getExpandedColumns();
    for (BaseColumn column : columns) {
      DTCellValue52 dcv = makeModelCellValue(column);
      DataType.DataTypes dataType = utilities.getDataType(column);
      utilities.assertDTCellValue(dataType, dcv);
      CellValue<? extends Comparable<?>> cell = convertModelCellValue(column, dcv);
      data.add(cell);
    }

    return data;
  }
  /**
   * Make a Model cell for the given column
   *
   * @param column
   * @return
   */
  @Override
  public DTCellValue52 makeModelCellValue(BaseColumn column) {
    DataType.DataTypes dataType = utilities.getDataType(column);
    DTCellValue52 dcv = null;
    if (column instanceof LimitedEntryCol) {
      dcv = new DTCellValue52(Boolean.FALSE);
    } else if (column instanceof AttributeCol52) {
      AttributeCol52 ac = (AttributeCol52) column;
      if (ac.getAttribute().equals(RuleAttributeWidget.DIALECT_ATTR)) {
        dcv = new DTCellValue52(RuleAttributeWidget.DEFAULT_DIALECT);
      } else {
        dcv = new DTCellValue52(column.getDefaultValue());
      }

    } else {
      dcv = new DTCellValue52(column.getDefaultValue());
    }
    utilities.assertDTCellValue(dataType, dcv);
    return dcv;
  }
  /**
   * Convert a type-safe UI CellValue into a type-safe Model CellValue
   *
   * @param column Model column from which data-type can be derived
   * @param cell UI CellValue to convert into Model CellValue
   * @return
   */
  public DTCellValue52 convertToModelCell(BaseColumn column, CellValue<?> cell) {
    DataType.DataTypes dt = utilities.getDataType(column);
    DTCellValue52 dtCell = null;

    switch (dt) {
      case BOOLEAN:
        dtCell = new DTCellValue52((Boolean) cell.getValue());
        break;
      case DATE:
        dtCell = new DTCellValue52((Date) cell.getValue());
        break;
      case NUMERIC:
        dtCell = new DTCellValue52((BigDecimal) cell.getValue());
        break;
      case NUMERIC_BIGDECIMAL:
        dtCell = new DTCellValue52((BigDecimal) cell.getValue());
        break;
      case NUMERIC_BIGINTEGER:
        dtCell = new DTCellValue52((BigInteger) cell.getValue());
        break;
      case NUMERIC_BYTE:
        dtCell = new DTCellValue52((Byte) cell.getValue());
        break;
      case NUMERIC_DOUBLE:
        dtCell = new DTCellValue52((Double) cell.getValue());
        break;
      case NUMERIC_FLOAT:
        dtCell = new DTCellValue52((Float) cell.getValue());
        break;
      case NUMERIC_INTEGER:
        dtCell = new DTCellValue52((Integer) cell.getValue());
        break;
      case NUMERIC_LONG:
        dtCell = new DTCellValue52((Long) cell.getValue());
        break;
      case NUMERIC_SHORT:
        dtCell = new DTCellValue52((Short) cell.getValue());
        break;
      default:
        dtCell = new DTCellValue52((String) cell.getValue());
    }
    dtCell.setOtherwise(cell.isOtherwise());
    return dtCell;
  }
  /**
   * Convert a Model cell to one that can be used in the UI
   *
   * @param dcv
   * @return
   */
  @Override
  public CellValue<? extends Comparable<?>> convertModelCellValue(
      BaseColumn column, DTCellValue52 dcv) {

    // Analysis cells do not use data-type
    if (column instanceof AnalysisCol52) {
      return makeNewAnalysisCellValue();
    }

    // Other cells do use data-type
    DataType.DataTypes dataType = utilities.getDataType(column);
    utilities.assertDTCellValue(dataType, dcv);

    CellValue<? extends Comparable<?>> cell = null;
    switch (dataType) {
      case BOOLEAN:
        cell = makeNewBooleanCellValue(dcv.getBooleanValue());
        break;
      case DATE:
        cell = makeNewDateCellValue(dcv.getDateValue());
        break;
      case NUMERIC:
        cell = makeNewNumericCellValue((BigDecimal) dcv.getNumericValue());
        break;
      case NUMERIC_BIGDECIMAL:
        cell = makeNewBigDecimalCellValue((BigDecimal) dcv.getNumericValue());
        break;
      case NUMERIC_BIGINTEGER:
        cell = makeNewBigIntegerCellValue((BigInteger) dcv.getNumericValue());
        break;
      case NUMERIC_BYTE:
        cell = makeNewByteCellValue((Byte) dcv.getNumericValue());
        break;
      case NUMERIC_DOUBLE:
        cell = makeNewDoubleCellValue((Double) dcv.getNumericValue());
        break;
      case NUMERIC_FLOAT:
        cell = makeNewFloatCellValue((Float) dcv.getNumericValue());
        break;
      case NUMERIC_INTEGER:
        cell = makeNewIntegerCellValue((Integer) dcv.getNumericValue());
        break;
      case NUMERIC_LONG:
        if (column instanceof RowNumberCol52) {
          cell = makeNewRowNumberCellValue((Long) dcv.getNumericValue());
        } else {
          cell = makeNewLongCellValue((Long) dcv.getNumericValue());
          if (column instanceof AttributeCol52) {
            AttributeCol52 at = (AttributeCol52) column;
            if (at.getAttribute().equals(RuleAttributeWidget.SALIENCE_ATTR)) {
              if (at.isUseRowNumber()) {
                cell = makeNewRowNumberCellValue((Long) dcv.getNumericValue());
              }
            }
          }
        }
        break;
      case NUMERIC_SHORT:
        cell = makeNewShortCellValue((Short) dcv.getNumericValue());
        break;
      default:
        cell = makeNewStringCellValue(dcv.getStringValue());
        if (column instanceof AttributeCol52) {
          AttributeCol52 ac = (AttributeCol52) column;
          if (ac.getAttribute().equals(RuleAttributeWidget.DIALECT_ATTR)) {
            cell = makeNewDialectCellValue(dcv.getStringValue());
          }
        }
    }

    if (dcv.isOtherwise()) {
      cell.addState(CellState.OTHERWISE);
    }

    return cell;
  }