protected void writeFormProperties(FlowElement flowElement, XMLStreamWriter xtw)
      throws Exception {

    List<FormProperty> propertyList = null;
    if (flowElement instanceof UserTask) {
      propertyList = ((UserTask) flowElement).getFormProperties();
    } else if (flowElement instanceof StartEvent) {
      propertyList = ((StartEvent) flowElement).getFormProperties();
    }

    if (propertyList != null) {

      for (FormProperty property : propertyList) {

        if (StringUtils.isNotEmpty(property.getId())) {

          if (didWriteExtensionStartElement == false) {
            xtw.writeStartElement(ELEMENT_EXTENSIONS);
            didWriteExtensionStartElement = true;
          }

          xtw.writeStartElement(
              ACTIVITI_EXTENSIONS_PREFIX, ELEMENT_FORMPROPERTY, ACTIVITI_EXTENSIONS_NAMESPACE);
          writeDefaultAttribute(ATTRIBUTE_FORM_ID, property.getId(), xtw);

          writeDefaultAttribute(ATTRIBUTE_FORM_NAME, property.getName(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_TYPE, property.getType(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_EXPRESSION, property.getExpression(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_VARIABLE, property.getVariable(), xtw);

          xtw.writeEndElement();
        }
      }
    }
  }
  protected boolean writeFormProperties(
      FlowElement flowElement, boolean didWriteExtensionStartElement, XMLStreamWriter xtw)
      throws Exception {

    List<FormProperty> propertyList = null;
    if (flowElement instanceof UserTask) {
      propertyList = ((UserTask) flowElement).getFormProperties();
    } else if (flowElement instanceof StartEvent) {
      propertyList = ((StartEvent) flowElement).getFormProperties();
    }

    if (propertyList != null) {

      for (FormProperty property : propertyList) {

        if (StringUtils.isNotEmpty(property.getId())) {

          if (didWriteExtensionStartElement == false) {
            xtw.writeStartElement(ELEMENT_EXTENSIONS);
            didWriteExtensionStartElement = true;
          }

          xtw.writeStartElement(
              ACTIVITI_EXTENSIONS_PREFIX, ELEMENT_FORMPROPERTY, ACTIVITI_EXTENSIONS_NAMESPACE);
          writeDefaultAttribute(ATTRIBUTE_FORM_ID, property.getId(), xtw);

          writeDefaultAttribute(ATTRIBUTE_FORM_NAME, property.getName(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_TYPE, property.getType(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_EXPRESSION, property.getExpression(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_VARIABLE, property.getVariable(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_DEFAULT, property.getDefaultExpression(), xtw);
          writeDefaultAttribute(ATTRIBUTE_FORM_DATEPATTERN, property.getDatePattern(), xtw);
          if (property.isReadable() == false) {
            writeDefaultAttribute(ATTRIBUTE_FORM_READABLE, ATTRIBUTE_VALUE_FALSE, xtw);
          }
          if (property.isWriteable() == false) {
            writeDefaultAttribute(ATTRIBUTE_FORM_WRITABLE, ATTRIBUTE_VALUE_FALSE, xtw);
          }
          if (property.isRequired()) {
            writeDefaultAttribute(ATTRIBUTE_FORM_REQUIRED, ATTRIBUTE_VALUE_TRUE, xtw);
          }

          for (FormValue formValue : property.getFormValues()) {
            if (StringUtils.isNotEmpty(formValue.getId())) {
              xtw.writeStartElement(
                  ACTIVITI_EXTENSIONS_PREFIX, ELEMENT_VALUE, ACTIVITI_EXTENSIONS_NAMESPACE);
              xtw.writeAttribute(ATTRIBUTE_ID, formValue.getId());
              xtw.writeAttribute(ATTRIBUTE_NAME, formValue.getName());
              xtw.writeEndElement();
            }
          }

          xtw.writeEndElement();
        }
      }
    }

    return didWriteExtensionStartElement;
  }
  protected void writeMessageDefinition(
      Event parentEvent,
      MessageEventDefinition messageDefinition,
      BpmnModel model,
      XMLStreamWriter xtw)
      throws Exception {
    xtw.writeStartElement(ELEMENT_EVENT_MESSAGEDEFINITION);

    String messageRef = messageDefinition.getMessageRef();
    if (StringUtils.isNotEmpty(messageRef)) {
      // remove the namespace from the message id if set
      if (messageRef.startsWith(model.getTargetNamespace())) {
        messageRef = messageRef.replace(model.getTargetNamespace(), "");
        messageRef = messageRef.replaceFirst(":", "");
      } else {
        for (String prefix : model.getNamespaces().keySet()) {
          String namespace = model.getNamespace(prefix);
          if (messageRef.startsWith(namespace)) {
            messageRef = messageRef.replace(model.getTargetNamespace(), "");
            messageRef = prefix + messageRef;
          }
        }
      }
    }
    writeDefaultAttribute(ATTRIBUTE_MESSAGE_REF, messageRef, xtw);
    boolean didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(messageDefinition, false, xtw);
    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }
    xtw.writeEndElement();
  }
  protected void writeListeners(BaseElement element, XMLStreamWriter xtw) throws Exception {
    List<ActivitiListener> listenerList = null;
    String xmlElementName = ELEMENT_EXECUTION_LISTENER;
    if (element instanceof UserTask) {
      listenerList = ((UserTask) element).getTaskListeners();
      xmlElementName = ELEMENT_TASK_LISTENER;
    } else if (element instanceof Activity) {
      listenerList = ((Activity) element).getExecutionListeners();
    } else if (element instanceof Process) {
      listenerList = ((Process) element).getExecutionListeners();
    } else if (element instanceof SequenceFlow) {
      listenerList = ((SequenceFlow) element).getExecutionListeners();
    }

    if (listenerList != null) {

      for (ActivitiListener listener : listenerList) {

        if (StringUtils.isNotEmpty(listener.getEvent())) {

          if (didWriteExtensionStartElement == false) {
            xtw.writeStartElement(ELEMENT_EXTENSIONS);
            didWriteExtensionStartElement = true;
          }

          xtw.writeStartElement(
              ACTIVITI_EXTENSIONS_PREFIX, xmlElementName, ACTIVITI_EXTENSIONS_NAMESPACE);
          writeDefaultAttribute(ATTRIBUTE_LISTENER_EVENT, listener.getEvent(), xtw);

          if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(
              listener.getImplementationType())) {
            writeDefaultAttribute(ATTRIBUTE_LISTENER_CLASS, listener.getImplementation(), xtw);
          } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(
              listener.getImplementationType())) {
            writeDefaultAttribute(ATTRIBUTE_LISTENER_EXPRESSION, listener.getImplementation(), xtw);
          } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
              listener.getImplementationType())) {
            writeDefaultAttribute(
                ATTRIBUTE_LISTENER_DELEGATEEXPRESSION, listener.getImplementation(), xtw);
          }

          xtw.writeEndElement();
        }
      }
    }
  }
 protected void writeErrorDefinition(
     Event parentEvent, ErrorEventDefinition errorDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_ERRORDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw);
   boolean didWriteExtensionStartElement =
       BpmnXMLUtil.writeExtensionElements(errorDefinition, false, xtw);
   if (didWriteExtensionStartElement) {
     xtw.writeEndElement();
   }
   xtw.writeEndElement();
 }
 protected void writeSignalDefinition(
     Event parentEvent, SignalEventDefinition signalDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_SIGNALDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw);
   if (parentEvent instanceof ThrowEvent && signalDefinition.isAsync()) {
     BpmnXMLUtil.writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, "true", xtw);
   }
   boolean didWriteExtensionStartElement =
       BpmnXMLUtil.writeExtensionElements(signalDefinition, false, xtw);
   if (didWriteExtensionStartElement) {
     xtw.writeEndElement();
   }
   xtw.writeEndElement();
 }
  public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel model)
      throws Exception {
    xtw.writeStartElement(getXMLElementName());
    boolean didWriteExtensionStartElement = false;
    writeDefaultAttribute(ATTRIBUTE_ID, baseElement.getId(), xtw);
    if (baseElement instanceof FlowElement) {
      writeDefaultAttribute(ATTRIBUTE_NAME, ((FlowElement) baseElement).getName(), xtw);
    }

    if (baseElement instanceof Activity) {
      final Activity activity = (Activity) baseElement;
      if (activity.isAsynchronous()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
        if (activity.isNotExclusive()) {
          writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
        }
      }
      if (StringUtils.isNotEmpty(activity.getDefaultFlow())) {
        FlowElement defaultFlowElement = model.getFlowElement(activity.getDefaultFlow());
        if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
          writeDefaultAttribute(ATTRIBUTE_DEFAULT, activity.getDefaultFlow(), xtw);
        }
      }
    }

    if (baseElement instanceof Gateway) {
      final Gateway gateway = (Gateway) baseElement;
      if (gateway.isAsynchronous()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
        if (gateway.isNotExclusive()) {
          writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
        }
      }
      if (StringUtils.isNotEmpty(gateway.getDefaultFlow())) {
        FlowElement defaultFlowElement = model.getFlowElement(gateway.getDefaultFlow());
        if (defaultFlowElement != null && defaultFlowElement instanceof SequenceFlow) {
          writeDefaultAttribute(ATTRIBUTE_DEFAULT, gateway.getDefaultFlow(), xtw);
        }
      }
    }

    writeAdditionalAttributes(baseElement, model, xtw);

    if (baseElement instanceof FlowElement) {
      final FlowElement flowElement = (FlowElement) baseElement;
      if (StringUtils.isNotEmpty(flowElement.getDocumentation())) {

        xtw.writeStartElement(ELEMENT_DOCUMENTATION);
        xtw.writeCharacters(flowElement.getDocumentation());
        xtw.writeEndElement();
      }
    }

    didWriteExtensionStartElement =
        writeExtensionChildElements(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement = writeListeners(baseElement, didWriteExtensionStartElement, xtw);
    didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(baseElement, didWriteExtensionStartElement, xtw);

    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }

    if (baseElement instanceof Activity) {
      final Activity activity = (Activity) baseElement;
      MultiInstanceExport.writeMultiInstance(activity, xtw);
    }

    writeAdditionalChildElements(baseElement, model, xtw);

    xtw.writeEndElement();
  }
 protected void writeErrorDefinition(ErrorEventDefinition errorDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_ERRORDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_ERROR_REF, errorDefinition.getErrorCode(), xtw);
   xtw.writeEndElement();
 }
 protected void writeMessageDefinition(
     MessageEventDefinition messageDefinition, XMLStreamWriter xtw) throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_MESSAGEDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_MESSAGE_REF, messageDefinition.getMessageRef(), xtw);
   xtw.writeEndElement();
 }
 protected void writeSignalDefinition(SignalEventDefinition signalDefinition, XMLStreamWriter xtw)
     throws Exception {
   xtw.writeStartElement(ELEMENT_EVENT_SIGNALDEFINITION);
   writeDefaultAttribute(ATTRIBUTE_SIGNAL_REF, signalDefinition.getSignalRef(), xtw);
   xtw.writeEndElement();
 }
  public void convertToXML(XMLStreamWriter xtw, FlowElement flowElement) throws Exception {
    xtw.writeStartElement(getXMLElementName());
    didWriteExtensionStartElement = false;
    writeDefaultAttribute(ATTRIBUTE_ID, flowElement.getId(), xtw);
    writeDefaultAttribute(ATTRIBUTE_NAME, flowElement.getName(), xtw);

    if (flowElement instanceof Activity) {
      Activity activity = (Activity) flowElement;
      if (activity.isAsynchronous()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_ASYNCHRONOUS, ATTRIBUTE_VALUE_TRUE, xtw);
      }
      if (activity.isNotExclusive()) {
        writeQualifiedAttribute(ATTRIBUTE_ACTIVITY_EXCLUSIVE, ATTRIBUTE_VALUE_FALSE, xtw);
      }
      writeDefaultAttribute(ATTRIBUTE_ACTIVITY_DEFAULT, activity.getDefaultFlow(), xtw);
    }

    writeAdditionalAttributes(flowElement, xtw);
    if (StringUtils.isNotEmpty(flowElement.getDocumentation())) {

      xtw.writeStartElement(ELEMENT_DOCUMENTATION);
      xtw.writeCharacters(flowElement.getDocumentation());
      xtw.writeEndElement();
    }
    writeAdditionalChildElements(flowElement, xtw);

    writeListeners(flowElement, xtw);

    if (didWriteExtensionStartElement) {
      xtw.writeEndElement();
    }

    if (flowElement instanceof Activity) {
      Activity activity = (Activity) flowElement;
      if (activity.getLoopCharacteristics() != null) {
        MultiInstanceLoopCharacteristics multiInstanceObject = activity.getLoopCharacteristics();
        if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())
            || StringUtils.isNotEmpty(multiInstanceObject.getInputDataItem())
            || StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) {

          xtw.writeStartElement(ELEMENT_MULTIINSTANCE);
          writeDefaultAttribute(
              ATTRIBUTE_MULTIINSTANCE_SEQUENTIAL,
              String.valueOf(multiInstanceObject.isSequential()).toLowerCase(),
              xtw);
          if (StringUtils.isNotEmpty(multiInstanceObject.getInputDataItem())) {
            writeQualifiedAttribute(
                ATTRIBUTE_MULTIINSTANCE_COLLECTION, multiInstanceObject.getInputDataItem(), xtw);
          }
          if (StringUtils.isNotEmpty(multiInstanceObject.getElementVariable())) {
            writeQualifiedAttribute(
                ATTRIBUTE_MULTIINSTANCE_VARIABLE, multiInstanceObject.getElementVariable(), xtw);
          }
          if (StringUtils.isNotEmpty(multiInstanceObject.getLoopCardinality())) {
            xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CARDINALITY);
            xtw.writeCharacters(multiInstanceObject.getLoopCardinality());
            xtw.writeEndElement();
          }
          if (StringUtils.isNotEmpty(multiInstanceObject.getCompletionCondition())) {
            xtw.writeStartElement(ELEMENT_MULTIINSTANCE_CONDITION);
            xtw.writeCharacters(multiInstanceObject.getCompletionCondition());
            xtw.writeEndElement();
          }
          xtw.writeEndElement();
        }
      }
    }

    xtw.writeEndElement();
  }