@SuppressWarnings("unchecked")
  public static void writeProcess(Process process, XMLStreamWriter xtw) throws Exception {
    // start process element
    xtw.writeStartElement(ELEMENT_PROCESS);
    xtw.writeAttribute(ATTRIBUTE_ID, process.getId());

    if (StringUtils.isNotEmpty(process.getName())) {
      xtw.writeAttribute(ATTRIBUTE_NAME, process.getName());
    }

    xtw.writeAttribute(ATTRIBUTE_PROCESS_EXECUTABLE, Boolean.toString(process.isExecutable()));
    xtw.writeAttribute("isClosed", Boolean.toString(process.isClosed()));
    if (StringUtils.isNotEmpty(process.getProcessType())) {
      xtw.writeAttribute("processType", process.getProcessType());
    }

    if (process.getCandidateStarterUsers().size() > 0) {
      xtw.writeAttribute(
          ACTIVITI_EXTENSIONS_PREFIX,
          ACTIVITI_EXTENSIONS_NAMESPACE,
          ATTRIBUTE_PROCESS_CANDIDATE_USERS,
          BpmnXMLUtil.convertToDelimitedString(process.getCandidateStarterUsers()));
    }

    if (process.getCandidateStarterGroups().size() > 0) {
      xtw.writeAttribute(
          ACTIVITI_EXTENSIONS_PREFIX,
          ACTIVITI_EXTENSIONS_NAMESPACE,
          ATTRIBUTE_PROCESS_CANDIDATE_GROUPS,
          BpmnXMLUtil.convertToDelimitedString(process.getCandidateStarterGroups()));
    }

    // write custom attributes
    BpmnXMLUtil.writeCustomAttributes(
        process.getAttributes().values(), xtw, defaultProcessAttributes);

    if (!process.getDocumentations().isEmpty()) {
      for (Documentation documentation : process.getDocumentations()) {
        xtw.writeStartElement(ELEMENT_DOCUMENTATION);
        if (StringUtils.isNotEmpty(documentation.getId())) {
          writeDefaultAttribute(ATTRIBUTE_ID, documentation.getId(), xtw);
        }
        if (StringUtils.isNotEmpty(documentation.getTextFormat())) {
          writeDefaultAttribute(ATTRIBUTE_TEXTFORMAT, documentation.getTextFormat(), xtw);
        }
        if (StringUtils.isNotEmpty(documentation.getText())) {
          xtw.writeCData(documentation.getText());
        }
        xtw.writeEndElement();
      }
    }

    boolean didWriteExtensionStartElement =
        ActivitiListenerExport.writeListeners(process, false, xtw);
    didWriteExtensionStartElement =
        BpmnXMLUtil.writeExtensionElements(process, didWriteExtensionStartElement, xtw);

    if (didWriteExtensionStartElement) {
      // closing extensions element
      xtw.writeEndElement();
    }
    if (process.getIoSpecification() != null) {
      BpmnXMLUtil.writeIOSpecification(process.getIoSpecification(), xtw);
    }

    LaneExport.writeLanes(process, xtw);
  }