private static <T> int weights(ImmutableList<ComponentSizeAndWeight<T>> sizes) {
    return Folds.foldLeft(
        sizes,
        new Foldleft<ComponentSizeAndWeight<T>, Integer>() {

          @Override
          public Integer apply(Integer left, ComponentSizeAndWeight<T> right) {
            return left + right.weight();
          }
        },
        0);
  }
  private static <T> int sumOrMax(ImmutableList<ComponentAndSize<T>> sizes) {
    return Folds.foldLeft(
        sizes,
        new Foldleft<ComponentAndSize<T>, Integer>() {

          @Override
          public Integer apply(Integer left, ComponentAndSize<T> right) {
            int ret = left + right.size();
            // overflow happend
            if ((ret < left) && (ret < right.size())) {
              ret = Integer.MAX_VALUE;
            }
            return ret;
          }
        },
        0);
  }