public void loadCommitInfos(
      final CDOBranch branch,
      final long startTime,
      final long endTime,
      CDOCommitInfoHandler handler) {
    if (endTime < CDOBranchPoint.UNSPECIFIED_DATE) {
      throw new IllegalArgumentException("Counting not supported");
    }

    ObjectSet<DB4OCommitInfo> resultSet =
        getObjectContainer()
            .query(
                new Predicate<DB4OCommitInfo>() {
                  private static final long serialVersionUID = 1L;

                  @Override
                  public boolean match(DB4OCommitInfo info) {
                    if (startTime != CDOBranchPoint.UNSPECIFIED_DATE
                        && info.getTimeStamp() < startTime) {
                      return false;
                    }

                    if (endTime != CDOBranchPoint.UNSPECIFIED_DATE
                        && info.getTimeStamp() > endTime) {
                      return false;
                    }

                    if (branch != null && !(info.getBranchID() == branch.getID())) {
                      return false;
                    }

                    return true;
                  }
                });

    InternalRepository repository = getStore().getRepository();
    InternalCDOCommitInfoManager commitInfoManager = repository.getCommitInfoManager();
    InternalCDOBranchManager branchManager = repository.getBranchManager();

    // Although not specified in the API, the test suite
    // suggests CommitInfos should be returned ordered by timeStamp
    // TODO Specify this in the API!

    List<DB4OCommitInfo> infos = new ArrayList<DB4OCommitInfo>(resultSet);
    Collections.sort(
        infos,
        new Comparator<DB4OCommitInfo>() {
          public int compare(DB4OCommitInfo arg0, DB4OCommitInfo arg1) {
            return CDOCommonUtil.compareTimeStamps(arg0.getTimeStamp(), arg1.getTimeStamp());
          }
        });

    for (DB4OCommitInfo info : infos) {
      info.handle(branchManager, commitInfoManager, handler);
    }
  }