private BranchInfo createNewBranch(
      ProjectHistory projectHistory,
      PrimaryVersionSpec baseSpec,
      PrimaryVersionSpec primarySpec,
      BranchVersionSpec branch) {
    primarySpec.setBranch(branch.getBranch());

    final BranchInfo branchInfo = VersioningFactory.eINSTANCE.createBranchInfo();
    branchInfo.setName(branch.getBranch());
    branchInfo.setSource(ModelUtil.clone(baseSpec));
    branchInfo.setHead(ModelUtil.clone(primarySpec));

    projectHistory.getBranches().add(branchInfo);

    return branchInfo;
  }
 /**
  * @param targetBranch
  * @param baseVersion
  * @return
  */
 private boolean isRegularCommit(BranchVersionSpec targetBranch, final Version baseVersion) {
   return targetBranch == null
       || baseVersion.getPrimarySpec().getBranch().equals(targetBranch.getBranch());
 }
  private PrimaryVersionSpec internalCreateVersion(
      ProjectId projectId,
      PrimaryVersionSpec baseVersionSpec,
      AbstractChangePackage changePackage,
      BranchVersionSpec targetBranch,
      PrimaryVersionSpec sourceVersion,
      LogMessage logMessage,
      final ACUser user)
      throws ESException {
    synchronized (getMonitor()) {
      final long currentTimeMillis = System.currentTimeMillis();
      final ProjectHistory projectHistory =
          getSubInterface(ProjectSubInterfaceImpl.class).getProject(projectId);

      // Find branch
      final BranchInfo baseBranch = getBranchInfo(projectHistory, baseVersionSpec);
      final Version baseVersion = getVersion(projectHistory, baseVersionSpec);

      if (baseVersion == null || baseBranch == null) {
        throw new InvalidVersionSpecException(
            Messages.VersionSubInterfaceImpl_InvalidBranchOrVersion);
      }

      // defined here fore scoping reasons
      Version newVersion = null;
      BranchInfo newBranch = null;

      // copy project and apply changes
      final Project newProjectState =
          ((ProjectImpl) getSubInterface(ProjectSubInterfaceImpl.class).getProject(baseVersion))
              .copy();
      changePackage.apply(newProjectState);

      // regular commit
      if (isRegularCommit(targetBranch, baseVersion)) {

        newVersion =
            performRegularCommit(
                baseVersionSpec,
                logMessage,
                user,
                projectHistory,
                baseBranch,
                baseVersion,
                newProjectState);

        // case for new branch creation
      } else if (isNewBranchCommit(targetBranch, projectHistory)) {
        checkNewBranchCommitPreRequisites(targetBranch.getBranch());
        // when branch does NOT exist, create new branch
        newVersion = createVersion(projectHistory, newProjectState, logMessage, user, baseVersion);
        newBranch =
            createNewBranch(
                projectHistory,
                baseVersion.getPrimarySpec(),
                newVersion.getPrimarySpec(),
                targetBranch);
        newVersion.setAncestorVersion(baseVersion);

      } else {
        // This point only can be reached with invalid input
        throw new IllegalStateException(
            Messages.VersionSubInterfaceImpl_TargetBranchCombination_Invalid);
      }

      if (sourceVersion != null) {
        newVersion.getMergedFromVersion().add(getVersion(projectHistory, sourceVersion));
      }

      // try to save
      try {
        try {
          trySave(projectId, changePackage, projectHistory, newVersion, newProjectState);
        } catch (final FatalESException e) {
          // try to roll back. removing version is necessary in all cases
          rollback(projectHistory, baseBranch, baseVersion, newVersion, newBranch, e);
        }

        // if ancestor isn't null, a new branch was created. In this
        // case we want to keep the old base project
        // state
        if (newVersion.getAncestorVersion() == null && baseVersion.getProjectState() != null) {
          // delete projectstate from last revision depending on
          // persistence policy
          deleteOldProjectStateAccordingToOptions(projectId, baseVersion);
        }

        save(baseVersion);
        save(projectHistory);

      } catch (final FatalESException e) {
        // roll back failed
        EMFStoreController.getInstance().shutdown(e);
        throw new ESException(Messages.VersionSubInterfaceImpl_ShuttingServerDown);
      }

      ModelUtil.logInfo(
          Messages.VersionSubInterfaceImpl_TotalTimeForCommit
              + (System.currentTimeMillis() - currentTimeMillis));
      return newVersion.getPrimarySpec();
    }
  }