@Test
  @DiagramResource("org/camunda/bpm/modeler/test/ui/change/ChangeSupportTest.testBase.bpmn")
  public void testAttributeUpdate() {
    final SequenceFlow sequenceFlow2 =
        findBusinessObjectById(diagram, "SequenceFlow_2", SequenceFlow.class);

    FeatureChangeFilter filter =
        new FeatureChangeFilter(sequenceFlow2, CONDITION_EXPRESSION_FEATURE);
    CustomResourceSetListener listener = new CustomResourceSetListener(sequenceFlow2, filter);
    listener.register();

    final FormalExpression expression = bpmn2factory.createFormalExpression();
    expression.setBody("FOOO");

    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            sequenceFlow2.setConditionExpression(expression);
          }
        });

    assertThat(listener.getCapturedEvents()).hasSize(1);
  }
  public void updateTask() {
    /*
     * Here we need to examine the current list of DataInputAssociations on the
     * Task and, if there is already a DataInput named NotStartedReassign or
     * NotCompletedReassign, append a new expression. Otherwise create a new
     * DataInput and DataInputAssociation.
     *
     * The XML looks like this:
     *
     * <bpmn2:ioSpecification id="IOSpec_1">
     *   <bpmn2:dataInput id="DataInput_1" name="NotCompletedReassign"/>
     *   <bpmn2:dataInput id="DataInput_2" name="NotStartedReassign"/>
     * </bpmn2:ioSpecification>
     *
     * <bpmn2:dataInputAssociation id="DataInputAssociation_1">
     *   <bpmn2:targetRef>DataInput_1</bpmn2:targetRef>
     *   <bpmn2:assignment id="Assignment_1">
     *     <bpmn2:from xsi:type="bpmn2:tFormalExpression"><![CDATA[[users:user2|groups:group2]@[exp2]^[users:user1,user2,user3|groups:group1,group2,group3]@[exp4]]]></bpmn2:from>
     *     <bpmn2:to xsi:type="bpmn2:tFormalExpression">DataInput_1</bpmn2:to>
     *   </bpmn2:assignment>
     * </bpmn2:dataInputAssociation>
     *
     * <bpmn2:dataInputAssociation id="DataInputAssociation_2">
     *   <bpmn2:targetRef>DataInput_2</bpmn2:targetRef>
     *   <bpmn2:assignment id="Assignment_2">
     *     <bpmn2:from xsi:type="bpmn2:tFormalExpression"><![CDATA[[users:user1|groups:group1]@[exp1]^[users:user1,user2,user3|groups:group1,group2,group3]@[exp4]]]></bpmn2:from>
     *     <bpmn2:to xsi:type="bpmn2:tFormalExpression">DataInput_2</bpmn2:to>
     *   </bpmn2:assignment>
     * </bpmn2:dataInputAssociation>
     */
    Resource resource = task.eResource();
    InputOutputSpecification iospec = task.getIoSpecification();
    DataInputAssociation notStarted = null;
    DataInputAssociation notCompleted = null;
    DataInput input;
    Assignment assignment;
    FormalExpression expression;
    String body;
    for (DataInputAssociation dia : task.getDataInputAssociations()) {
      if (dia.getTargetRef() instanceof DataInput) {
        input = (DataInput) dia.getTargetRef();
        if (ReassignmentType.NOT_STARTED_REASSIGN.getLiteral().equals(input.getName())) {
          notStarted = dia;
        } else if (ReassignmentType.NOT_COMPLETED_REASSIGN.getLiteral().equals(input.getName())) {
          notCompleted = dia;
        }
      }
    }

    body = toString(ReassignmentType.NOT_STARTED_REASSIGN);
    if (body.isEmpty()) {
      if (notStarted != null) {
        // need to remove the NotCompletedReassign data input and association
        iospec.getDataInputs().remove(notStarted.getTargetRef());
        iospec.getInputSets().get(0).getDataInputRefs().remove(notStarted.getTargetRef());
        task.getDataInputAssociations().remove(notStarted);
      }
    } else {
      if (notStarted == null) {
        // create the NotStartedReassign data input and association
        input =
            (DataInput) Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getDataInput());
        input.setName(ReassignmentType.NOT_STARTED_REASSIGN.getLiteral());
        iospec.getDataInputs().add(input);
        iospec.getInputSets().get(0).getDataInputRefs().add(input);
        notStarted =
            (DataInputAssociation)
                Bpmn2ModelerFactory.create(
                    resource, Bpmn2Package.eINSTANCE.getDataInputAssociation());
        notStarted.setTargetRef(input);
        assignment =
            (Assignment)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getAssignment());
        expression =
            (FormalExpression)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getFormalExpression());
        // make sure this DataInput has an ID
        ModelUtil.setID(input);
        expression.setBody(input.getId());
        assignment.setTo(expression);
        notStarted.getAssignment().add(assignment);
        task.getDataInputAssociations().add(notStarted);

        ModelUtil.setID(notStarted);
        ModelUtil.setID(assignment);
        ModelUtil.setID(expression);
      }

      assignment = (Assignment) notStarted.getAssignment().get(0);
      expression = (FormalExpression) assignment.getFrom();
      if (expression == null) {
        expression =
            (FormalExpression)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getFormalExpression());
        assignment.setFrom(expression);
        ModelUtil.setID(expression);
      }
      expression.setBody(body);
    }

    body = toString(ReassignmentType.NOT_COMPLETED_REASSIGN);
    if (body.isEmpty()) {
      if (notCompleted != null) {
        // need to remove the NotCompletedReassign data input and association
        iospec.getDataInputs().remove(notCompleted.getTargetRef());
        iospec.getInputSets().get(0).getDataInputRefs().remove(notCompleted.getTargetRef());
        task.getDataInputAssociations().remove(notCompleted);
      }
    } else {
      if (notCompleted == null) {
        // create the NotStartedReassign data input and association
        input =
            (DataInput) Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getDataInput());
        input.setName(ReassignmentType.NOT_COMPLETED_REASSIGN.getLiteral());
        iospec.getDataInputs().add(input);
        iospec.getInputSets().get(0).getDataInputRefs().add(input);
        notCompleted =
            (DataInputAssociation)
                Bpmn2ModelerFactory.create(
                    resource, Bpmn2Package.eINSTANCE.getDataInputAssociation());
        notCompleted.setTargetRef(input);
        assignment =
            (Assignment)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getAssignment());
        expression =
            (FormalExpression)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getFormalExpression());
        // make sure this DataInput has an ID
        ModelUtil.setID(input);
        expression.setBody(input.getId());
        assignment.setTo(expression);
        notCompleted.getAssignment().add(assignment);
        task.getDataInputAssociations().add(notCompleted);

        ModelUtil.setID(notCompleted);
        ModelUtil.setID(assignment);
        ModelUtil.setID(expression);
      }

      assignment = (Assignment) notCompleted.getAssignment().get(0);
      expression = (FormalExpression) assignment.getFrom();
      if (expression == null) {
        expression =
            (FormalExpression)
                Bpmn2ModelerFactory.create(resource, Bpmn2Package.eINSTANCE.getFormalExpression());
        assignment.setFrom(expression);
        ModelUtil.setID(expression);
      }
      expression.setBody(body);
    }
  }