private BalancingResult applyBestResult() {
    final float hCenter = horCenter();
    List<Element> elements = sequence.getElements();

    setColumn((float) bestResult.leftColumnHeight, hCenter, true, true, singleColumnRect, leftCTB);
    setColumn(
        (float) bestResult.rightColumnHeight, hCenter, false, false, singleColumnRect, rightCTB);

    if (b.drawBorders) {
      b.getCanvasBuilder().drawGrayRectangle(leftCTB.getSimpleColumnRectangle(), BaseColor.RED);
      b.getCanvasBuilder().drawGrayRectangle(rightCTB.getSimpleColumnRectangle(), BaseColor.GREEN);
    }

    leftCTB.clearContent();
    rightCTB.clearContent();

    final DirectContentAdder.Result addResult =
        new DirectContentAdder(leftCTB)
            .setStartWith(initialLeftCTB)
            .setStartAtIndex(startAtElement)
            .setSwitchToRightCTB(rightCTB)
            .setSimulate(false)
            .go();

    float yLine = Math.min(leftCTB.getYLine(), rightCTB.getYLine());

    final BalancingResult r;

    if (addResult.hasContentLeft(elements.size())) {
      final ColumnTextBuilder contentCopy =
          addResult.contentLeft == null
              ? null
              : b.newColumnTextBuilder().setACopy(addResult.contentLeft);

      r = startWithANewPage(contentCopy, addResult.index);
    } else {
      r = new BalancingResult(yLine);

      //            if(updateAfterRun != null){
      //                updateAfterRun.growBottom(origRectangle.getTop() - yLine);
      //            }
    }

    if (updateAfterRun != null) {
      updateAfterRun.setSimpleColumn(
          b.reuseRectangleBuilder(new Rectangle(origRectangle.get()))
              .setTop(yLine)
              .setBottom(b.getDocument().bottom())
              .get());
    }

    return r;
  }
  private BalancingResult startWithANewPage(ColumnTextBuilder content, int startAt) {
    //noinspection SimplifiableConditionalExpression
    logger.debug(
        "starting with a new page, content: {}, startAt: {}",
        content == null ? false : content.hasMoreText(),
        startAt);

    final RectangleBuilder rect =
        b.reuseRectangleBuilder(origRectangle.get())
            .setTop(b.getDocument().top())
            .setBottom(b.getDocument().bottom());

    b.getDocument().newPage();

    return new BalancedColumnsBuilder(content, startAt, rect.get(), b).setSequence(sequence).go();
  }
  public boolean fits() {
    final boolean simulate = true;

    // try adding into a single infinite column to calc height
    ColumnTextBuilder ctb = b.reuseColumnTextBuilder();

    b.reuseRectangleBuilder(tempR).copyPositionsFrom(rectangle);

    tempR.setBottom(-10000f);
    tempR.setRight(horCenter());

    applyPadding(tempR, true);

    ctb.setSimpleColumn(tempR);

    float yBefore = ctb.getYLine();

    contentAdder.add(ctb, simulate);

    int status = ctb.go(simulate);

    if (ColumnText.hasMoreText(status)) {
      return false;
    }

    float yAfter = ctb.getYLine();

    final float height = yBefore - yAfter;

    logger.trace("height: {}", height);

    //        if(height > rectangle.getHeight()) {
    //            return false;
    //        }

    // now try adding into two actual columns
    final float columnHeight = height / 2 + additionalSpaceForColumn;

    if (!addToTwoColumns(simulate, columnHeight)) {
      return false;
    }

    addToTwoColumns(false, columnHeight);

    return true;
  }
  private void setColumn(
      float height, float horCenter, boolean left, ColumnTextBuilder ctb, boolean simulate) {
    b.reuseRectangleBuilder(tempR).copyPositionsFrom(rectangle);

    tempR.setBottom(tempR.getTop() - height);

    if (left) {
      tempR.setRight(horCenter);
    } else {
      tempR.setLeft(horCenter);
      tempR.setBottom(-10000f);
    }

    applyPadding(tempR, left);

    logger.debug("setting column to: {}", tempR);

    ctb.setSimpleColumn(tempR);
  }
  private boolean addToTwoColumns(boolean simulate, float height) {
    ColumnTextBuilder ctb;
    int status;
    ctb = b.reuseColumnTextBuilder();

    b.reuseRectangleBuilder(tempR).copyPositionsFrom(rectangle);

    final float horCenter = horCenter();

    setColumn(height, horCenter, true, ctb, simulate);

    contentAdder.add(ctb, simulate);

    status = ctb.go(simulate);

    yLine = ctb.getYLine();

    if (!ColumnText.hasMoreText(status) && simulate) {
      return true;
    }

    setColumn(height, horCenter, false, ctb, simulate);

    status = ctb.go(simulate);

    yLine = Math.min(yLine, ctb.getYLine());

    // right column may not fit the rect, check if does fit the page
    if (simulate) {
      if (yLine < rectangle.getBottom()) {
        return false;
      }
    }

    return !ColumnText.hasMoreText(status);
  }