/**
   * Create a new version.
   *
   * @param sessionId the ID of the session being used to create a new version
   * @param projectId the ID of the project for which a new version is created
   * @param baseVersionSpec the base version
   * @param changePackage the change package containing all changes that make up the new version
   * @param targetBranch the target branch for which to create the new version
   * @param sourceVersion the source version
   * @param logMessage a log message
   * @return the new version
   * @throws ESException in case of failure
   */
  @ESMethod(MethodId.CREATEVERSION)
  public PrimaryVersionSpec createVersion(
      SessionId sessionId,
      ProjectId projectId,
      PrimaryVersionSpec baseVersionSpec,
      AbstractChangePackage changePackage,
      BranchVersionSpec targetBranch,
      PrimaryVersionSpec sourceVersion,
      LogMessage logMessage)
      throws ESException {

    getAccessControl().getSessions().isValid(sessionId.toAPI());
    final ESUser rawUser = getAccessControl().getSessions().getRawUser(sessionId.toAPI());
    final ACUser tmpUser = (ACUser) ESUserImpl.class.cast(rawUser).toInternalAPI();
    final ESUser copyAndResolveUser =
        getAccessControl().getOrgUnitResolverServive().copyAndResolveUser(tmpUser.toAPI());
    final ACUser user = (ACUser) ESUserImpl.class.cast(copyAndResolveUser).toInternalAPI();
    sanityCheckObjects(sessionId, projectId, baseVersionSpec, changePackage, logMessage);

    if (FileBasedChangePackage.class.isInstance(changePackage)
        && !ServerConfiguration.useFileBasedChangePackageOnServer()) {
      // File-based change package should never arrive here in production mode
      throw new ESException(Messages.VersionSubInterfaceImpl_FileBasedChangePackageNotAllowed);
    } else if (ChangePackage.class.isInstance(changePackage)
        && ServerConfiguration.useFileBasedChangePackageOnServer()) {
      // Regular change package should never arrive here in production mode
      throw new ESException(Messages.VersionSubInterfaceImpl_FileBasedChangePackageExpected);
    }

    return internalCreateVersion(
        projectId, baseVersionSpec, changePackage, targetBranch, sourceVersion, logMessage, user);
  }
  private Version createVersion(
      ProjectHistory projectHistory,
      Project projectState,
      LogMessage logMessage,
      ACUser user,
      Version previousVersion)
      throws ESException {
    final Version newVersion = VersioningFactory.eINSTANCE.createVersion();

    long computedChecksum = ModelUtil.NO_CHECKSUM;

    try {
      if (ServerConfiguration.isComputeChecksumOnCommitActive()) {
        computedChecksum = ModelUtil.computeChecksum(projectState);
      }
    } catch (final SerializationException exception) {
      // TODO: clarify what to do in case checksum computation fails + provide ext. point
      throw new ESException(
          MessageFormat.format(
              Messages.VersionSubInterfaceImpl_ChecksumComputationFailed,
              projectHistory.getProjectName()),
          exception);
    }

    // newVersion.setChanges(changePackage);

    logMessage.setDate(new Date());
    logMessage.setAuthor(user.getName());
    newVersion.setLogMessage(logMessage);

    // latest version == getVersion.size() (version start with index 0 as
    // the list), branch from previous is used.
    newVersion.setPrimarySpec(
        Versions.createPRIMARY(
            previousVersion.getPrimarySpec(), projectHistory.getVersions().size()));
    newVersion.getPrimarySpec().setProjectStateChecksum(computedChecksum);
    newVersion.setNextVersion(null);

    projectHistory.getVersions().add(newVersion);
    return newVersion;
  }