// A Pattern column adds constraints to a Pattern. It has a value in the OBJECT row
  private List<BRLVariableColumn> addPatternColumn() {
    // Sort column builders by column index to ensure columns are added in the correct sequence
    final TreeSet<Integer> sortedIndexes = new TreeSet<Integer>(this.valueBuilders.keySet());
    final List<BRLVariableColumn> variableColumns = new ArrayList<BRLVariableColumn>();

    // DRL prefix
    final StringBuffer drl = new StringBuffer();
    drl.append(this.colDefPrefix);
    String sep = "";

    // DRL fragment
    for (Integer index : sortedIndexes) {
      final ParameterizedValueBuilder vb = this.valueBuilders.get(index);
      for (String parameter : vb.getParameters()) {
        final BRLConditionVariableColumn parameterColumn =
            new BRLConditionVariableColumn(parameter, DataType.TYPE_OBJECT);
        parameterColumn.setHeader(this.columnHeaders.get(index));
        variableColumns.add(parameterColumn);
      }

      drl.append(sep).append(vb.getTemplate());
      sep = this.andop;
    }

    // DRL suffix
    drl.append(this.colDefSuffix);

    // Store DRL fragment for use by GuidedDecisionTableRHSBuilder
    drlFragments.add(drl.toString());
    return variableColumns;
  }
  private String getType(final BRLConditionVariableColumn col) {

    // If the parameter is not bound to a Fact or FactField use the explicit type. This is
    // (currently)
    // used when a BRL fragment does not contain any Template Keys and a single
    // BRLConditionVariableColumn
    // is created with type SuggestionCompletionEngine.TYPE_BOOLEAN i.e. Limited Entry
    if (col.getFactType() == null && col.getFactField() == null) {
      return col.getFieldType();
    }

    // Otherwise lookup from SuggestionCompletionEngine
    final String factType = col.getFactType();
    final String fieldName = col.getFactField();
    return getTypeFromDataOracle(factType, fieldName);
  }
  @Override
  protected List<BRLConditionVariableColumn> convertInterpolationVariables(
      Map<InterpolationVariable, Integer> ivs) {

    // If there are no variables add a boolean column to specify whether the fragment should apply
    if (ivs.size() == 0) {
      BRLConditionVariableColumn variable =
          new BRLConditionVariableColumn("", DataType.TYPE_BOOLEAN);
      variable.setHeader(editingCol.getHeader());
      variable.setHideColumn(editingCol.isHideColumn());
      List<BRLConditionVariableColumn> variables = new ArrayList<BRLConditionVariableColumn>();
      variables.add(variable);
      return variables;
    }

    // Convert to columns for use in the Decision Table
    BRLConditionVariableColumn[] variables = new BRLConditionVariableColumn[ivs.size()];
    for (Map.Entry<InterpolationVariable, Integer> me : ivs.entrySet()) {
      InterpolationVariable iv = me.getKey();
      int index = me.getValue();
      BRLConditionVariableColumn variable =
          new BRLConditionVariableColumn(
              iv.getVarName(), iv.getDataType(), iv.getFactType(), iv.getFactField());
      variable.setHeader(editingCol.getHeader());
      variable.setHideColumn(editingCol.isHideColumn());
      variables[index] = variable;
    }

    // Convert the array into a mutable list (Arrays.toList provides an immutable list)
    List<BRLConditionVariableColumn> variableList = new ArrayList<BRLConditionVariableColumn>();
    for (BRLConditionVariableColumn variable : variables) {
      variableList.add(variable);
    }
    return variableList;
  }
  // An explicit column does not add constraints to a Pattern. It does not have a value in the
  // OBJECT row
  private List<BRLVariableColumn> addExplicitColumns() {
    // Sort column builders by column index to ensure Actions are added in the correct sequence
    final Set<Integer> sortedIndexes = new TreeSet<Integer>(this.valueBuilders.keySet());

    final List<BRLVariableColumn> variableColumns = new ArrayList<BRLVariableColumn>();

    for (Integer index : sortedIndexes) {
      final ParameterizedValueBuilder vb = this.valueBuilders.get(index);
      final List<BRLVariableColumn> vbVariableColumns = new ArrayList<BRLVariableColumn>();
      if (vb instanceof LiteralValueBuilder) {
        vbVariableColumns.addAll(addLiteralColumn((LiteralValueBuilder) vb));
        for (BRLVariableColumn vbVariableColumn : vbVariableColumns) {
          ((BRLConditionVariableColumn) vbVariableColumn).setHeader(this.columnHeaders.get(index));
        }
      } else {
        vbVariableColumns.addAll(addBRLFragmentColumn(vb));
        for (BRLVariableColumn vbVariableColumn : vbVariableColumns) {
          ((BRLConditionVariableColumn) vbVariableColumn).setHeader(this.columnHeaders.get(index));
        }
      }
      variableColumns.addAll(vbVariableColumns);
    }
    return variableColumns;
  }
 private BRLConditionVariableColumn cloneVariable(BRLConditionVariableColumn variable) {
   BRLConditionVariableColumn clone =
       new BRLConditionVariableColumn(
           variable.getVarName(),
           variable.getFieldType(),
           variable.getFactType(),
           variable.getFactField());
   clone.setHeader(variable.getHeader());
   clone.setHideColumn(variable.isHideColumn());
   clone.setWidth(variable.getWidth());
   return clone;
 }