public static CloseableIterable<CombinedScanTask> planTasks(
      CloseableIterable<FileScanTask> splitFiles, long splitSize, int lookback, long openFileCost) {

    validatePlanningArguments(splitSize, lookback, openFileCost);

    // Check the size of delete file as well to avoid unbalanced bin-packing
    Function<FileScanTask, Long> weightFunc =
        file ->
            Math.max(
                file.length()
                    + file.deletes().stream().mapToLong(ContentFile::fileSizeInBytes).sum(),
                (1 + file.deletes().size()) * openFileCost);

    return CloseableIterable.transform(
        CloseableIterable.combine(
            new BinPacking.PackingIterable<>(splitFiles, splitSize, lookback, weightFunc, true),
            splitFiles),
        BaseCombinedScanTask::new);
  }
@Test
  public void testPlanTaskWithDeleteFiles() {
    List<FileScanTask> testFiles =
        tasksWithDataAndDeleteSizes(
            Arrays.asList(
                Pair.of(150L, new Long[] {50L, 100L}),
                Pair.of(50L, new Long[] {1L, 50L}),
                Pair.of(50L, new Long[] {100L}),
                Pair.of(1L, new Long[] {1L, 1L}),
                Pair.of(75L, new Long[] {75L})));

    List<CombinedScanTask> combinedScanTasks =
        Lists.newArrayList(
            TableScanUtil.planTasks(CloseableIterable.withNoopClose(testFiles), 300L, 3, 50L));

    List<CombinedScanTask> expectedCombinedTasks =
        Arrays.asList(
            new BaseCombinedScanTask(Collections.singletonList(testFiles.get(0))),
            new BaseCombinedScanTask(Arrays.asList(testFiles.get(1), testFiles.get(2))),
            new BaseCombinedScanTask(Arrays.asList(testFiles.get(3), testFiles.get(4))));

    assertThat(combinedScanTasks)
        .as("Should plan 3 Combined tasks since there is delete files to be considered")
        .hasSize(3);
    for (int i = 0; i < expectedCombinedTasks.size(); ++i) {
      assertThat(combinedScanTasks.get(i).files())
          .as("Scan tasks detail in combined task check failed")
          .isEqualTo(expectedCombinedTasks.get(i).files());
    }
  }