protected void addDueDateReference(Form form, String formSet, boolean writable) {
    String fieldName = null;
    if (form.isStartForm()) {
      fieldName = AlfrescoConversionConstants.PROPERTY_WORKFLOW_DUE_DATE;
    } else {
      fieldName = AlfrescoConversionConstants.PROPERTY_DUE_DATE;
    }

    form.getFormFieldVisibility().addShowFieldElement(fieldName);

    FormField formField =
        form.getFormAppearance()
            .addFormField(
                fieldName, AlfrescoConversionConstants.FORM_WORKFLOW_DUE_DATE_LABEL, formSet);
    if (form.isStartForm() || writable) {
      formField.setControl(new FormFieldControl(AlfrescoConversionConstants.FORM_DATE_TEMPLATE));
      formField
          .getControl()
          .getControlParameters()
          .add(
              new FormFieldControlParameter(
                  AlfrescoConversionConstants.FORM_DATE_PARAM_SHOW_TIME, Boolean.FALSE.toString()));
      formField
          .getControl()
          .getControlParameters()
          .add(
              new FormFieldControlParameter(
                  AlfrescoConversionConstants.FORM_DATE_PARAM_SUBMIT_TIME,
                  Boolean.FALSE.toString()));
    } else {
      formField.setControl(
          new FormFieldControl(AlfrescoConversionConstants.FORM_READONLY_TEMPLATE));
    }
    form.getFormAppearance().addFormAppearanceElement(formField);
  }
  public void createForm(
      M2Type contentType,
      Form formConfig,
      FormDefinition formDefinition,
      WorkflowDefinitionConversion conversion) {
    if (formDefinition != null && formDefinition.getFormGroups() != null) {

      for (FormPropertyGroup group : formDefinition.getFormGroups()) {
        // Create a group in the form-config
        String groupId = null;
        if (group.getId() != null) {
          groupId = AlfrescoConversionUtil.getValidIdString(group.getId());
        } else {
          groupId = AlfrescoConversionUtil.getValidIdString(group.getTitle());
        }

        FormSet formSet =
            formConfig
                .getFormAppearance()
                .addFormSet(
                    groupId,
                    getAppearanceForGroup(group),
                    group.getTitle(),
                    getTemplateForGroup(group));

        // Convert all properties
        AlfrescoFormPropertyConverter converter = null;
        for (FormPropertyDefinition property : group.getFormPropertyDefinitions()) {
          converter = propertyConverters.get(property.getClass());
          if (converter == null) {
            throw new AlfrescoSimpleWorkflowException(
                "Unsupported property type: " + property.getClass().getName());
          }
          converter.convertProperty(contentType, formSet.getId(), formConfig, property, conversion);
        }
      }
    }

    // Finally, add "transitions" if not already added
    // TODO: check if added once transitions are supported
    formConfig
        .getFormAppearance()
        .addFormSet(AlfrescoConversionConstants.FORM_SET_RESPONSE, null, null, null);
    formConfig
        .getFormFieldVisibility()
        .addShowFieldElement(AlfrescoConversionConstants.FORM_FIELD_TRANSITIONS);
    formConfig
        .getFormAppearance()
        .addFormField(
            AlfrescoConversionConstants.FORM_FIELD_TRANSITIONS,
            null,
            AlfrescoConversionConstants.FORM_SET_RESPONSE);
  }
  protected void addAssociation(
      Form form,
      String formSet,
      ReferencePropertyDefinition referenceDefinition,
      M2Type contentType,
      WorkflowDefinitionConversion conversion) {

    M2Model model = AlfrescoConversionUtil.getContentModel(conversion);

    // Check if model contains an aspect for the property
    String propertyName = getPropertyName(referenceDefinition, conversion);

    M2ClassAssociation association = new M2ClassAssociation();
    association.setName(propertyName);
    association.setTitle(referenceDefinition.getName());
    M2AssociationSource source = new M2AssociationSource();
    source.setMany(false);
    source.setMandatory(true);
    M2AssociationTarget target = new M2AssociationTarget();
    target.setClassName(referenceDefinition.getType());
    target.setMandatory(referenceDefinition.isMandatory());

    // Determine whether or not it's allowed to select multiple targets
    boolean isTargetMany =
        extractBooleanFromParameters(
            referenceDefinition.getParameters(),
            AlfrescoConversionConstants.PARAMETER_REFERENCE_MANY,
            false);
    target.setMany(isTargetMany);

    association.setTarget(target);
    association.setSource(source);

    M2Aspect aspect = model.getAspect(propertyName);
    if (aspect != null) {
      if (aspect.getAssociations().isEmpty()) {
        aspect.getAssociations().add(association);
      }
      contentType.getMandatoryAspects().add(propertyName);
    } else {
      contentType.getAssociations().add(association);
    }

    // Add field to form
    form.getFormFieldVisibility().addShowFieldElement(propertyName);

    FormField field = new FormField();
    form.getFormAppearance().addFormAppearanceElement(field);
    field.setId(propertyName);
    field.setSet(formSet);
  }
  protected void addPackageReference(
      Form form,
      String formSet,
      M2Type contentType,
      ReferencePropertyDefinition referenceDefinition) {
    form.getFormFieldVisibility()
        .addShowFieldElement(AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS);
    form.getFormAppearance()
        .addFormField(AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS, null, formSet);

    // Only take into account package-actions when we're not dealing with a start-form
    if (!form.isStartForm()) {
      boolean allowAddingItems =
          extractBooleanFromParameters(
              referenceDefinition.getParameters(),
              AlfrescoConversionConstants.PARAMETER_PACKAGEITEMS_ALLOW_ADD,
              true);
      boolean allowRemovingItems =
          extractBooleanFromParameters(
              referenceDefinition.getParameters(),
              AlfrescoConversionConstants.PARAMETER_PACKAGEITEMS_ALLOW_REMOVE,
              true);

      if (allowAddingItems) {
        M2PropertyOverride addOverride = new M2PropertyOverride();
        addOverride.setName(AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ACTION_GROUP);
        addOverride.setDefaultValue(
            AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ACTION_GROUP_ADD);
        contentType.getPropertyOverrides().add(addOverride);
      }

      // Override for package item actions
      M2PropertyOverride addOverride = new M2PropertyOverride();
      contentType.getPropertyOverrides().add(addOverride);

      if (allowRemovingItems) {
        addOverride.setName(AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ITEM_ACTION_GROUP);
        addOverride.setDefaultValue(
            AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ITEM_ACTION_GROUP_REMOVE);
      } else {
        addOverride.setName(AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ITEM_ACTION_GROUP);
        addOverride.setDefaultValue(
            AlfrescoConversionConstants.PROPERTY_PACKAGEITEMS_ITEM_ACTION_GROUP_EDIT);
      }
    }
  }
  protected void addWorkflowDescriptionReference(Form form, String formSet) {
    String fieldName = null;
    if (form.isStartForm()) {
      fieldName = AlfrescoConversionConstants.PROPERTY_WORKFLOW_DESCRIPTION;
    } else {
      fieldName = AlfrescoConversionConstants.PROPERTY_DESCRIPTION;
    }
    form.getFormFieldVisibility().addShowFieldElement(fieldName);

    FormField descriptionField = new FormField();
    descriptionField.setId(fieldName);
    descriptionField.setLabelId(AlfrescoConversionConstants.FORM_WORKFLOW_DESCRIPTION_LABEL);
    descriptionField.setSet(formSet);
    if (form.isStartForm()) {
      descriptionField.setControl(
          new FormFieldControl(AlfrescoConversionConstants.FORM_MULTILINE_TEXT_TEMPLATE));
    } else {
      descriptionField.setControl(
          new FormFieldControl(AlfrescoConversionConstants.FORM_READONLY_TEMPLATE));
    }
    form.getFormAppearance().addFormAppearanceElement(descriptionField);
  }
  protected void addFieldReference(
      Form form,
      String formSet,
      ReferencePropertyDefinition definition,
      M2Type contentType,
      WorkflowDefinitionConversion conversion) {
    if (form.isStartForm()) {
      throw new AlfrescoSimpleWorkflowException("Field references cannot be used on start-forms");
    }

    M2Model model = AlfrescoConversionUtil.getContentModel(conversion);

    // Check if model contains an aspect for the property
    String propertyName = getPropertyName(definition, conversion);

    if (model.getAspect(propertyName) == null) {
      throw new AlfrescoSimpleWorkflowException(
          "The property '"
              + definition.getName()
              + "' is not used in a from prior to this form: "
              + contentType.getName()
              + " - "
              + propertyName);
    }

    // Add aspect to content-type
    contentType.getMandatoryAspects().add(propertyName);

    // Add read-only field to form
    form.getFormFieldVisibility().addShowFieldElement(propertyName);

    FormField field = new FormField();
    form.getFormAppearance().addFormAppearanceElement(field);
    field.setId(propertyName);
    field.setLabelId(definition.getName());
    field.setSet(formSet);
    field.setControl(new FormFieldControl(AlfrescoConversionConstants.FORM_READONLY_TEMPLATE));
  }
  protected void addPriorityReference(Form form, String formSet, boolean writable) {

    String fieldName = null;
    if (form.isStartForm()) {
      fieldName = AlfrescoConversionConstants.PROPERTY_WORKFLOW_PRIORITY;
    } else {
      fieldName = AlfrescoConversionConstants.PROPERTY_PRIORITY;
    }
    form.getFormFieldVisibility().addShowFieldElement(fieldName);

    FormField priorityField = new FormField();
    priorityField.setSet(formSet);
    priorityField.setLabelId(AlfrescoConversionConstants.FORM_WORKFLOW_PRIORITY_LABEL);
    priorityField.setId(fieldName);

    if (form.isStartForm() || writable) {
      priorityField.setControl(
          new FormFieldControl(AlfrescoConversionConstants.FORM_PRIORITY_TEMPLATE));
    } else {
      priorityField.setControl(
          new FormFieldControl(AlfrescoConversionConstants.FORM_READONLY_TEMPLATE));
    }
    form.getFormAppearance().addFormAppearanceElement(priorityField);
  }