@NotNull
  public static <CommitId> PermanentGraphImpl<CommitId> newInstance(
      @NotNull List<? extends GraphCommit<CommitId>> graphCommits,
      @NotNull final GraphColorManager<CommitId> graphColorManager,
      @NotNull Set<CommitId> branchesCommitId) {
    PermanentLinearGraphBuilder<CommitId> permanentLinearGraphBuilder =
        PermanentLinearGraphBuilder.newInstance(graphCommits);
    final Map<Integer, CommitId> notLoadCommits = ContainerUtil.newHashMap();
    PermanentLinearGraphImpl linearGraph =
        permanentLinearGraphBuilder.build(
            new NotNullFunction<CommitId, Integer>() {
              @NotNull
              @Override
              public Integer fun(CommitId dom) {
                int nodeId = -(notLoadCommits.size() + 2);
                notLoadCommits.put(nodeId, dom);
                return nodeId;
              }
            });

    final PermanentCommitsInfoIml<CommitId> commitIdPermanentCommitsInfo =
        PermanentCommitsInfoIml.newInstance(graphCommits, notLoadCommits);

    GraphLayoutImpl permanentGraphLayout =
        GraphLayoutBuilder.build(
            linearGraph,
            new Comparator<Integer>() {
              @Override
              public int compare(@NotNull Integer nodeIndex1, @NotNull Integer nodeIndex2) {
                CommitId commitId1 = commitIdPermanentCommitsInfo.getCommitId(nodeIndex1);
                CommitId commitId2 = commitIdPermanentCommitsInfo.getCommitId(nodeIndex2);
                return graphColorManager.compareHeads(commitId2, commitId1);
              }
            });

    return new PermanentGraphImpl<CommitId>(
        linearGraph,
        permanentGraphLayout,
        commitIdPermanentCommitsInfo,
        graphColorManager,
        branchesCommitId);
  }