/** Adds a new constraint. */
  private void addConstraint() {
    IDecisionVariable variable = getVariable();
    ConstraintEditorDialog dlg = new ConstraintEditorDialog(getShell(), variable, null);
    if (ConstraintEditorDialog.OK == dlg.open()) {
      String constraint = dlg.getConstraintText();
      if (constraint.length() > 0) {
        try {
          if (null == variableValue) {
            variableValue =
                (ContainerValue)
                    ValueFactory.createValue(
                        variable.getDeclaration().getType(), ValueFactory.EMPTY);
            variable.setValue(variableValue, AssignmentState.ASSIGNED);
          }
          if (null != variableValue) {
            Value val = createConstraintValue(constraint);
            checkForDuplicates(val, -1);
            variableValue.addElement(val);

            TableItem item = new TableItem(tableViewer.getTable(), SWT.NULL);
            item.setText(constraint);
            setDirty();
          }
        } catch (ValueDoesNotMatchTypeException e) {
          exceptionDialog(e);
        } catch (ConfigurationException e) {
          exceptionDialog(e);
        }
      }
    }
  }
  /**
   * Creates an editor instance.
   *
   * @param config the UI configuration
   * @param variable the variable to edit
   * @param parent the parent composite
   */
  private ConstraintsEditor(UIConfiguration config, IDecisionVariable variable, Composite parent) {
    super(config, variable, parent, SWT.NULL);
    this.config = config;
    setLayout(new FillLayout());
    tableViewer = setTableViewer(createTableViewer(this, true));

    IDatatype type = DerivedDatatype.resolveToBasis(variable.getDeclaration().getType());
    if (1 == type.getGenericTypeCount()) {
      IDatatype contained = type.getGenericType(0);
      if (ConstraintType.TYPE.isAssignableFrom(contained)) {
        Value val = variable.getValue();
        if (val instanceof ContainerValue) {
          variableValue = (ContainerValue) val;
          fillTable(toConstraints((ContainerValue) val), tableViewer);
        }
      }
    }

    tableViewer.addDoubleClickListener(
        new IDoubleClickListener() {

          @Override
          public void doubleClick(DoubleClickEvent event) {
            // IStructuredSelection does not work well until content provider is used
            if (tableViewer == event.getSource()) {
              editSelectedConstraint();
            }
          }
        });

    manager = new MenuManager();
    tableViewer.getControl().setMenu(manager.createContextMenu(tableViewer.getControl()));
    manager.add(
        new Action("Add constraint", null) {

          @Override
          public void run() {
            addConstraint();
          }
        });
    manager.add(
        new Action("Remove constraint", null) {
          @Override
          public void run() {
            removeSelectedConstraint();
          }
        });
  }