@Override
  public Progress getProgress() {
    // If current tracking range is no longer growable, get progress as a normal range.
    if (range.getTo() != Long.MAX_VALUE || range.getTo() == range.getFrom()) {
      return super.getProgress();
    }

    // Convert to BigDecimal in computation to prevent overflow, which may result in lost of
    // precision.
    BigDecimal estimateRangeEnd = BigDecimal.valueOf(rangeEndEstimator.estimate());

    if (lastAttemptedOffset == null) {
      return Progress.from(
          0,
          estimateRangeEnd
              .subtract(BigDecimal.valueOf(range.getFrom()), MathContext.DECIMAL128)
              .max(BigDecimal.ZERO)
              .doubleValue());
    }

    BigDecimal workRemaining =
        estimateRangeEnd
            .subtract(BigDecimal.valueOf(lastAttemptedOffset), MathContext.DECIMAL128)
            .max(BigDecimal.ZERO);
    BigDecimal totalWork =
        estimateRangeEnd
            .max(BigDecimal.valueOf(lastAttemptedOffset))
            .subtract(BigDecimal.valueOf(range.getFrom()), MathContext.DECIMAL128);
    return Progress.from(
        totalWork.subtract(workRemaining, MathContext.DECIMAL128).doubleValue(),
        workRemaining.doubleValue());
  }
@Test
  public void testProgressAfterFinished() throws Exception {
    SimpleEstimator simpleEstimator = new SimpleEstimator();
    GrowableOffsetRangeTracker tracker = new GrowableOffsetRangeTracker(10L, simpleEstimator);
    assertFalse(tracker.tryClaim(Long.MAX_VALUE));
    tracker.checkDone();
    simpleEstimator.setEstimateRangeEnd(0L);
    Progress currentProgress = tracker.getProgress();
    assertEquals(Long.MAX_VALUE - 10L, currentProgress.getWorkCompleted(), 0);
    assertEquals(0, currentProgress.getWorkRemaining(), 0.001);
  }