protected int getContentsStretchHeight() {
   return subreportFiller.getCurrentPageStretchHeight();
 }
  protected boolean prepare(int availableHeight, boolean isOverflow) throws JRException {
    boolean willOverflow = false;

    super.prepare(availableHeight, isOverflow);

    if (subreportFiller == null) {
      setToPrint(false);
    }

    if (!isToPrint()) {
      return willOverflow;
    }

    if (availableHeight < getRelativeY() + getHeight()) {
      setToPrint(false);
      return true; // willOverflow;
    }

    // willOverflow = prepareTextField((JRFillTextField)fillElement, availableStretchHeight);

    // subreportFiller.setPageHeight(getHeight() + availableStretchHeight);

    boolean filling = runner.isFilling();
    boolean toPrint = !isOverflow || isPrintWhenDetailOverflows() || !isAlreadyPrinted();
    boolean reprinted = isOverflow && isPrintWhenDetailOverflows();

    if (!filling && toPrint && reprinted) {
      rewind();
    }

    if (printPage instanceof JRVirtualPrintPage) {
      // if the previous page was virtualized, dispose it as soon as possible.
      // this normally already happened when we added the elements to the master page,
      // but there are cases (e.g. overflow) when a page is not added to the master.
      ((JRVirtualPrintPage) printPage).dispose();
    }

    subreportFiller.setPageHeight(availableHeight - getRelativeY());

    synchronized (subreportFiller) {
      JRSubreportRunResult result;
      if (filling) {
        if (log.isDebugEnabled()) {
          log.debug("Fill " + filler.fillerId + ": resuming " + subreportFiller.fillerId);
        }

        result = runner.resume();
      } else if (toPrint) {
        setReprinted(reprinted);

        if (log.isDebugEnabled()) {
          log.debug("Fill " + filler.fillerId + ": starting " + subreportFiller.fillerId);
        }

        result = runner.start();
      } else {
        printPage = null;
        setStretchHeight(getHeight());
        setToPrint(false);

        return willOverflow;
      }

      if (result.getException() != null) {
        Throwable error = result.getException();

        if (log.isErrorEnabled()) {
          log.error("Fill " + filler.fillerId + ": exception", error);
        }

        if (error instanceof RuntimeException) {
          throw (RuntimeException) error;
        }

        throw new JRRuntimeException(error);
      }

      if (result.hasFinished()) {
        if (log.isDebugEnabled()) {
          log.debug(
              "Fill " + filler.fillerId + ": subreport " + subreportFiller.fillerId + " finished");
        }

        copyValues();
      } else {
        if (log.isDebugEnabled()) {
          log.debug(
              "Fill "
                  + filler.fillerId
                  + ": subreport "
                  + subreportFiller.fillerId
                  + " to continue");
        }
      }

      printPage = subreportFiller.getCurrentPage();
      setStretchHeight(
          result.hasFinished()
              ? subreportFiller.getCurrentPageStretchHeight()
              : availableHeight - getRelativeY());

      // if the subreport fill thread has not finished,
      // it means that the subreport will overflow on the next page
      willOverflow = !result.hasFinished();

      if (!willOverflow) {
        // the subreport fill thread has finished and the next time we shall create a new one
        runner.reset();
      }
    } // synchronized

    Collection<JRPrintElement> printElements = getPrintElements();
    if ((printElements == null || printElements.size() == 0)
        && isRemoveLineWhenBlank() // FIXME if the line won't be removed, the background does not
    // appear
    ) {
      setToPrint(false);
    }

    return willOverflow;
  }