@Test
  @DiagramResource(
      "org/camunda/bpm/modeler/test/core/utils/ExtensionUtilTest.testAddAndRemoveExtensions.bpmn")
  public void testAddAndRemoveExtensionsToOutType() {
    final CallActivity callActivity =
        findBusinessObjectById(diagram, "callActivity", CallActivity.class);

    List<ExtensionAttributeValue> extensionAttributeValues =
        ExtensionUtil.getExtensionAttributeValues(callActivity);
    assertThat(extensionAttributeValues).hasSize(0);

    // add <camunda:out source="test" target="test"/>
    final OutType sourceOutType = modelFactory.createOutType();
    sourceOutType.setSource("test");
    sourceOutType.setTarget("test");

    addCallActivityExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, sourceOutType);

    Object value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, "source");
    assertThat(value).isEqualTo("test");

    // add <camunda:out source="test2" target="test2"/>
    final OutType source2OutType = modelFactory.createOutType();
    source2OutType.setSource("test2");
    source2OutType.setTarget("test2");

    addCallActivityExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, source2OutType);

    // add <camunda:out variables="all"/>
    final OutType variablesOutType = modelFactory.createOutType();
    variablesOutType.setVariables(ALL_VARIABLES_VALUE);

    addCallActivityExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, variablesOutType);

    value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, "variables");
    assertThat(value).isEqualTo(ALL_VARIABLES_VALUE);

    List<OutType> extensions = ExtensionUtil.getExtensions(callActivity, OutType.class);
    assertThat(extensions).hasSize(3);

    // remove outType source="test2" extension
    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            ExtensionUtil.removeExtensionByValue(
                callActivity, CALL_ACTIVITY_OUT_TYPE, OUT_TYPE_SOURCE, "test2");
          }
        });

    extensions = ExtensionUtil.getExtensions(callActivity, OutType.class);
    assertThat(extensions).hasSize(2);

    value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_OUT_TYPE, "source");
    assertThat(value).isEqualTo("test");

    extensionAttributeValues = ExtensionUtil.getExtensionAttributeValues(callActivity);
    assertThat(extensionAttributeValues).hasSize(1);
  }
  @Test
  @DiagramResource(
      "org/camunda/bpm/modeler/test/core/utils/ExtensionUtilTest.testGetExtensionAttributeValues.bpmn")
  public void testUpdateExtension() {
    final CallActivity callActivity1 =
        findBusinessObjectById(diagram, "CallActivity_1", CallActivity.class);

    Object valueBefore = ExtensionUtil.getExtension(callActivity1, RETRY_CYCLE_FEATURE, "text");

    assertThat(valueBefore).isEqualTo("R3/PT10S");

    final FailedJobRetryTimeCycleType retryCycle = foxFactory.createFailedJobRetryTimeCycleType();
    retryCycle.setText("R3/PT200000S");

    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            ExtensionUtil.updateExtension(callActivity1, RETRY_CYCLE_FEATURE, retryCycle);
          }
        });

    Object valueAfter = ExtensionUtil.getExtension(callActivity1, RETRY_CYCLE_FEATURE, "text");

    assertThat(valueAfter).isEqualTo("R3/PT200000S");
  }
  @Test
  @DiagramResource("org/camunda/bpm/modeler/test/ui/change/ChangeSupportTest.testBase.bpmn")
  public void testExtensionElementUpdate() {
    final Task task1 = findBusinessObjectById(diagram, "Task_1", Task.class);

    ExtensionChangeFilter filter = new ExtensionChangeFilter(task1, RETRY_CYCLE_FEATURE);
    CustomResourceSetListener listener = new CustomResourceSetListener(task1, filter);

    listener.register();

    final FailedJobRetryTimeCycleType retryCycle = foxFactory.createFailedJobRetryTimeCycleType();
    retryCycle.setText("R3/PT10S");

    // assert that feature is set
    assertThat(ExtensionUtil.getExtension(task1, RETRY_CYCLE_FEATURE, "text")).isNotNull();

    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            ExtensionUtil.updateExtension(task1, RETRY_CYCLE_FEATURE, retryCycle);
          }
        });

    assertThat(listener.getCapturedEvents()).hasSize(1);
  }
  @Test
  @DiagramResource("org/camunda/bpm/modeler/test/ui/change/ChangeSupportTest.testBase.bpmn")
  public void testExtensionElementRemoveAndCleanExtensionAttributeValues() {
    final Task task1 = findBusinessObjectById(diagram, "Task_1", Task.class);

    // assert that feature is set
    assertThat(ExtensionUtil.getExtension(task1, RETRY_CYCLE_FEATURE, "text")).isNotNull();

    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            ExtensionUtil.removeExtensionByFeature(task1, RETRY_CYCLE_FEATURE);
          }
        });

    ExtensionChangeFilter filter = new ExtensionChangeFilter(task1, RETRY_CYCLE_FEATURE);
    CustomResourceSetListener listener = new CustomResourceSetListener(task1, filter);
    listener.register();

    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            AttributeUtil.clearEmptyExtensionElements(task1);
          }
        });

    assertThat(listener.getCapturedEvents()).hasSize(1);
  }
  @Test
  @DiagramResource(
      "org/camunda/bpm/modeler/test/core/utils/ExtensionUtilTest.testGetExtensionAttributeValues.bpmn")
  public void testGetExtensionAttribute() {
    final CallActivity callActivity1 =
        findBusinessObjectById(diagram, "CallActivity_1", CallActivity.class);

    Object value = ExtensionUtil.getExtension(callActivity1, RETRY_CYCLE_FEATURE, "text");

    assertThat(value).isEqualTo("R3/PT10S");
  }
  @Test
  @DiagramResource(
      "org/camunda/bpm/modeler/test/core/utils/ExtensionUtilTest.testGetExtensionOutOfManyInTypes.bpmn")
  public void testGetExtensionOutOfManyInTypes() {
    final CallActivity callActivity =
        findBusinessObjectById(diagram, "callActivity", CallActivity.class);

    List<ExtensionAttributeValue> extensionAttributeValues =
        ExtensionUtil.getExtensionAttributeValues(callActivity);
    assertThat(extensionAttributeValues).hasSize(1);

    Object businessKeyValue =
        ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "businessKey");

    assertThat(businessKeyValue).isEqualTo(BUSINESS_KEY_EXPRESSION);

    Object variablesValue =
        ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "variables");

    assertThat(variablesValue).isEqualTo("all");

    List<InType> extensions = ExtensionUtil.getExtensions(callActivity, InType.class);
    assertThat(extensions).hasSize(5);
  }
  @Test
  @DiagramResource(
      "org/camunda/bpm/modeler/test/core/utils/ExtensionUtilTest.testAddAndRemoveExtensions.bpmn")
  public void testAddAndRemoveExtensionsToInType() {
    final CallActivity callActivity =
        findBusinessObjectById(diagram, "callActivity", CallActivity.class);

    List<ExtensionAttributeValue> extensionAttributeValues =
        ExtensionUtil.getExtensionAttributeValues(callActivity);
    assertThat(extensionAttributeValues).hasSize(0);

    // add <camunda:in source="test" target="test"/>
    final InType sourceInType = modelFactory.createInType();
    sourceInType.setSource("test");
    sourceInType.setTarget("test");

    addCallActivityExtension(callActivity, CALL_ACTIVITY_IN_TYPE, sourceInType);

    Object value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "source");
    assertThat(value).isEqualTo("test");

    // add <camunda:in source="test2" target="test2"/>
    final InType source2InType = modelFactory.createInType();
    source2InType.setSource("test2");
    source2InType.setTarget("test2");

    addCallActivityExtension(callActivity, CALL_ACTIVITY_IN_TYPE, source2InType);

    // add <camunda:in businessKey="#{execution.processBusinessKey}"/>
    final InType businessKeyInType = modelFactory.createInType();
    businessKeyInType.setBusinessKey(BUSINESS_KEY_EXPRESSION);

    addCallActivityExtension(callActivity, CALL_ACTIVITY_IN_TYPE, businessKeyInType);

    value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "businessKey");
    assertThat(value).isEqualTo(BUSINESS_KEY_EXPRESSION);

    // add <camunda:in variables="all"/>
    final InType variablesInType = modelFactory.createInType();
    variablesInType.setVariables(ALL_VARIABLES_VALUE);

    addCallActivityExtension(callActivity, CALL_ACTIVITY_IN_TYPE, variablesInType);

    value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "variables");
    assertThat(value).isEqualTo(ALL_VARIABLES_VALUE);

    List<InType> extensions = ExtensionUtil.getExtensions(callActivity, InType.class);
    assertThat(extensions).hasSize(4);

    // remove inType businessKey extension
    transactionalExecute(
        new RecordingCommand(editingDomain) {

          @Override
          protected void doExecute() {
            ExtensionUtil.removeExtensionByValue(
                callActivity, CALL_ACTIVITY_IN_TYPE, IN_TYPE_BUSINESS_KEY, BUSINESS_KEY_EXPRESSION);
          }
        });

    extensions = ExtensionUtil.getExtensions(callActivity, InType.class);
    assertThat(extensions).hasSize(3);

    value = ExtensionUtil.getExtension(callActivity, CALL_ACTIVITY_IN_TYPE, "businessKey");
    assertThat(value).isNull();

    extensionAttributeValues = ExtensionUtil.getExtensionAttributeValues(callActivity);
    assertThat(extensionAttributeValues).hasSize(1);
  }