@Override
  protected void writeAdditionalAttributes(BaseElement element, XMLStreamWriter xtw)
      throws Exception {

    ServiceTask serviceTask = (ServiceTask) element;

    if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(serviceTask.getImplementationType())) {
      writeQualifiedAttribute(ATTRIBUTE_TASK_SERVICE_CLASS, serviceTask.getImplementation(), xtw);
    } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(
        serviceTask.getImplementationType())) {
      writeQualifiedAttribute(
          ATTRIBUTE_TASK_SERVICE_EXPRESSION, serviceTask.getImplementation(), xtw);
    } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
        serviceTask.getImplementationType())) {
      writeQualifiedAttribute(
          ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION, serviceTask.getImplementation(), xtw);
    }

    if (StringUtils.isNotEmpty(serviceTask.getResultVariableName())) {
      writeQualifiedAttribute(
          ATTRIBUTE_TASK_SERVICE_RESULTVARIABLE, serviceTask.getResultVariableName(), xtw);
    }
    if (StringUtils.isNotEmpty(serviceTask.getType())) {
      writeQualifiedAttribute(ATTRIBUTE_TYPE, serviceTask.getType(), xtw);
    }
    if (StringUtils.isNotEmpty(serviceTask.getExtensionId())) {
      writeQualifiedAttribute(
          ATTRIBUTE_TASK_SERVICE_EXTENSIONID, serviceTask.getExtensionId(), xtw);
    }
  }
  @Override
  protected BaseElement convertXMLToElement(XMLStreamReader xtr) throws Exception {
    ServiceTask serviceTask = new ServiceTask();
    BpmnXMLUtil.addXMLLocation(serviceTask, xtr);
    if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_CLASS))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_CLASS);
      serviceTask.setImplementation(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_CLASS));

    } else if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXPRESSION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION);
      serviceTask.setImplementation(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXPRESSION));

    } else if (StringUtils.isNotEmpty(
        xtr.getAttributeValue(
            ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
      serviceTask.setImplementation(
          xtr.getAttributeValue(
              ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_DELEGATEEXPRESSION));

    } else if ("##WebService".equals(xtr.getAttributeValue(null, ATTRIBUTE_TASK_IMPLEMENTATION))) {
      serviceTask.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_WEBSERVICE);
      serviceTask.setOperationRef(
          parseOperationRef(xtr.getAttributeValue(null, ATTRIBUTE_TASK_OPERATION_REF), model));
    }

    serviceTask.setResultVariableName(
        xtr.getAttributeValue(
            ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_RESULTVARIABLE));
    if (StringUtils.isEmpty(serviceTask.getResultVariableName())) {
      serviceTask.setResultVariableName(
          xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, "resultVariable"));
    }

    if (StringUtils.isNotEmpty(serviceTask.getResultVariableName())
        && (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(serviceTask.getImplementationType())
            || ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
                serviceTask.getImplementationType()))) {

      model.addProblem(
          "'resultVariableName' not supported for service tasks using 'class' or 'delegateExpression",
          xtr);
    }

    serviceTask.setType(xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TYPE));
    serviceTask.setExtensionId(
        xtr.getAttributeValue(ACTIVITI_EXTENSIONS_NAMESPACE, ATTRIBUTE_TASK_SERVICE_EXTENSIONID));

    parseChildElements(getXMLElementName(), serviceTask, xtr);

    return serviceTask;
  }
  protected void convertElementToJson(ObjectNode propertiesNode, FlowElement flowElement) {
    ServiceTask serviceTask = (ServiceTask) flowElement;

    if ("mail".equalsIgnoreCase(serviceTask.getType())) {

      setPropertyFieldValue(PROPERTY_MAILTASK_TO, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_FROM, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_SUBJECT, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_CC, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_BCC, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_TEXT, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_HTML, serviceTask, propertiesNode);
      setPropertyFieldValue(PROPERTY_MAILTASK_CHARSET, serviceTask, propertiesNode);

    } else {

      if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(PROPERTY_SERVICETASK_CLASS, serviceTask.getImplementation());
      } else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(PROPERTY_SERVICETASK_EXPRESSION, serviceTask.getImplementation());
      } else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equals(
          serviceTask.getImplementationType())) {
        propertiesNode.put(
            PROPERTY_SERVICETASK_DELEGATE_EXPRESSION, serviceTask.getImplementation());
      }

      if (StringUtils.isNotEmpty(serviceTask.getResultVariableName())) {
        propertiesNode.put(
            PROPERTY_SERVICETASK_RESULT_VARIABLE, serviceTask.getResultVariableName());
      }

      addFieldExtensions(serviceTask.getFieldExtensions(), propertiesNode);
    }
  }