@NotNull
 @Override
 public Set<CommitId> getContainingBranches(@NotNull CommitId commit) {
   int commitIndex = myPermanentCommitsInfo.getNodeId(commit);
   return myPermanentCommitsInfo.convertToCommitIdSet(
       myReachableNodes.getContainingBranches(commitIndex, myBranchNodeIds));
 }
 @NotNull
 @Override
 public List<CommitId> getChildren(@NotNull CommitId commit) {
   int commitIndex = myPermanentCommitsInfo.getNodeId(commit);
   return myPermanentCommitsInfo.convertToCommitIdList(
       LinearGraphUtils.getUpNodes(myPermanentLinearGraph, commitIndex));
 }
  @NotNull
  @Override
  public List<GraphCommit<CommitId>> getAllCommits() {
    List<GraphCommit<CommitId>> result = ContainerUtil.newArrayList();
    for (int index = 0; index < myPermanentLinearGraph.nodesCount(); index++) {
      CommitId commitId = myPermanentCommitsInfo.getCommitId(index);
      List<Integer> downNodes =
          LinearGraphUtils.getDownNodesIncludeNotLoad(myPermanentLinearGraph, index);
      List<CommitId> parentsCommitIds = myPermanentCommitsInfo.convertToCommitIdList(downNodes);
      GraphCommit<CommitId> graphCommit =
          new GraphCommitImpl<CommitId>(
              commitId, parentsCommitIds, myPermanentCommitsInfo.getTimestamp(index));
      result.add(graphCommit);
    }

    return result;
  }
 public PermanentGraphImpl(
     @NotNull PermanentLinearGraphImpl permanentLinearGraph,
     @NotNull GraphLayoutImpl permanentGraphLayout,
     @NotNull PermanentCommitsInfoIml<CommitId> permanentCommitsInfo,
     @NotNull GraphColorManager<CommitId> graphColorManager,
     @NotNull Set<CommitId> branchesCommitId) {
   myPermanentGraphLayout = permanentGraphLayout;
   myPermanentCommitsInfo = permanentCommitsInfo;
   myPermanentLinearGraph = permanentLinearGraph;
   myGraphColorManager = graphColorManager;
   myBranchesCommitId = branchesCommitId;
   myBranchNodeIds = permanentCommitsInfo.convertToNodeIds(branchesCommitId);
   myReachableNodes = new ReachableNodes(LinearGraphUtils.asLiteLinearGraph(permanentLinearGraph));
   myBekIntMap =
       BekSorter.createBekMap(
           myPermanentLinearGraph,
           myPermanentGraphLayout,
           myPermanentCommitsInfo.getTimestampGetter());
 }
  @NotNull
  @Override
  public VisibleGraph<CommitId> createVisibleGraph(
      @NotNull SortType sortType,
      @Nullable Set<CommitId> visibleHeads,
      @Nullable Set<CommitId> matchingCommits) {
    CascadeController baseController;
    if (sortType == SortType.Normal) {
      baseController = new BaseController(this);
    } else if (sortType == SortType.LinearBek) {
      baseController = new LinearBekController(new BekBaseController(this, myBekIntMap), this);
    } else {
      baseController = new BekBaseController(this, myBekIntMap);
    }

    LinearGraphController controller;
    if (matchingCommits != null) {
      controller =
          new FilteredController(
              baseController, this, myPermanentCommitsInfo.convertToNodeIds(matchingCommits));
    } else if (sortType == SortType.LinearBek) {
      if (visibleHeads != null) {
        controller =
            new BranchFilterController(
                baseController, this, myPermanentCommitsInfo.convertToNodeIds(visibleHeads));
      } else {
        controller = baseController;
      }
    } else {
      Set<Integer> idOfVisibleBranches = null;
      if (visibleHeads != null) {
        idOfVisibleBranches = myPermanentCommitsInfo.convertToNodeIds(visibleHeads);
      }
      controller = new CollapsedController(baseController, this, idOfVisibleBranches);
    }

    return new VisibleGraphImpl<CommitId>(controller, this);
  }
  @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);
  }