/**
     * Create a revision.
     *
     * <p>This method doesn't check site id because ProjectControl interface is available only if
     * site is is valid.
     */
    @Override
    public StoredWorkflowDefinition insertWorkflowDefinition(
        int projId, int revId, WorkflowDefinition def, ZoneId workflowTimeZone)
        throws ResourceConflictException {
      String configText = cfm.toText(def.getConfig());
      String zoneId = workflowTimeZone.getId();
      long configDigest = WorkflowConfig.digest(configText, zoneId);

      int configId;

      WorkflowConfig found = dao.findWorkflowConfigByDigest(projId, configDigest);
      if (found != null && WorkflowConfig.isEquivalent(found, configText, zoneId)) {
        configId = found.getId();
      } else {
        configId = dao.insertWorkflowConfig(projId, configText, zoneId, configDigest);
      }

      long wfId =
          catchConflict(
              () -> dao.insertWorkflowDefinition(revId, def.getName(), configId),
              "workflow=%s in revision id=%d",
              def.getName(),
              revId);

      try {
        return requiredResource(
            dao.getWorkflowDefinitionById(siteId, wfId), "workflow id=%d", wfId);
      } catch (ResourceNotFoundException ex) {
        throw new IllegalStateException("Database state error", ex);
      }
    }