// --------------------------------------------------------------------
  private void bucketizeHolesDown(BucketTree.Branch root, char[] numBuckets, int[] maxBuckets) {
    BUCKETIZER.setThorough(true);
    BUCKETIZER.bucketize(root, numBuckets[Round.PREFLOP.ordinal()]);
    BUCKETIZER.setThorough(false);

    bucketize(root.subBranches(), Round.FLOP, numBuckets, maxBuckets);
  }
  // --------------------------------------------------------------------
  private void bucketize(
      List<BucketTree.Branch> prevBuckets, Round round, char[] numBuckets, int[] maxBuckets) {
    int subBucketCounts[] =
        allocateBuckets(prevBuckets, numBuckets[round.ordinal()], maxBuckets[round.ordinal()]);
    LOG.debug("allocated: " + Arrays.toString(subBucketCounts));

    BUCKETIZER.setThorough(true);
    for (int prevBucketIndex = 0; prevBucketIndex < prevBuckets.size(); prevBucketIndex++) {
      BUCKETIZER.bucketize(prevBuckets.get(prevBucketIndex), subBucketCounts[prevBucketIndex]);
    }

    if (round == Round.RIVER) return;
    List<BucketTree.Branch> subBranches = new ArrayList<BucketTree.Branch>();
    for (BucketTree.Branch prevBucket : prevBuckets) {
      subBranches.addAll(prevBucket.subBranches());
    }
    bucketize(subBranches, round.next(), numBuckets, maxBuckets);
  }