private List<int[]> generateHeaps(int valueBound, int size, int[] left) {
        // Generates heaps of 'size' elements; i-th element in [left[i], valueBound).
        // If left is null, generates a min-heap. Otherwise, a max-heap.
        // left.size is guaranteed == either size or size+1.
        // If left.size == size+1, then implicitly result[size] is considered
        // equal to left[size].
        List<int[]> heaps = new ArrayList<int[]>();
        int[] p;
        if (left == null) {
            p = new int[size];
        }
        else {
            p = Arrays.copyOf(left, size);
        }
        do {
            if (isHeap(p, (left == null))) {
                if (left != null && left.length == size + 1) {
                    int parent = p[(size - 1) / 2];
                    if (parent < left[size])
                        continue;
                }
                heaps.add(Arrays.copyOf(p, size));
            }
        } while (increment(p, valueBound, left));
        return heaps;
    }