private void collectAlignableElements(
      final Section section, final List<Element> collectedElements) {
    if (section instanceof CrosstabGroup) {
      return;
    }

    final int theElementCount = section.getElementCount();
    for (int i = 0; i < theElementCount; i++) {
      final ReportElement reportElement = section.getElement(i);
      if (reportElement instanceof Section) {
        collectAlignableElements((Section) reportElement, collectedElements);
      }

      final CachedLayoutData cachedLayoutData =
          ModelUtility.getCachedLayoutData((Element) reportElement);
      final long layoutAge = cachedLayoutData.getLayoutAge();
      if (layoutAge != -1) {
        if (reportElement instanceof RootLevelBand) {
          continue;
        }

        if (reportElement instanceof Band || reportElement instanceof Section == false) {
          collectedElements.add((Element) reportElement);
        }
      }
    }
  }
  // todo: Condense this into one run where we collect all bounds for all parents ...
  private void recurse(final LogicalPageBox box, final Section section) {
    if (section != null) {
      this.ids.clear();
      this.ids.add(section.getObjectID());
      this.bounds = null;
      startProcessing(box);
      if (this.bounds == null) {
        DebugLog.log("Failed to collect bounds for report of section " + section);
        recurse(box, section.getParentSection());
        return;
      }

      DebugLog.log("Generating bounds for empty section " + section);
      this.bounds.setRect(this.bounds.getX(), this.bounds.getY(), this.bounds.getWidth(), 0);
    }
  }
  public void traverseSection(final Section section) {
    final int count = section.getElementCount();
    for (int i = 0; i < count; i++) {
      final ReportElement element = section.getElement(i);
      if (element instanceof SubReport) {
        inspect((SubReport) element);
      } else if (element instanceof Section) {
        inspectElement(element);
        traverseSection((Section) element);

        if (element instanceof RootLevelBand) {
          final RootLevelBand rlb = (RootLevelBand) element;
          for (int sr = 0; sr < rlb.getSubReportCount(); sr += 1) {
            inspect(rlb.getSubReport(sr));
          }
        }
      } else {
        inspectElement(element);
      }
    }
  }
 public StrictBounds select(
     final HashSet<InstanceID> ids, final LogicalPageBox box, final Section section) {
   if (ids == null) {
     throw new NullPointerException();
   }
   this.ids.clear();
   this.ids.addAll(ids);
   this.bounds = null;
   startProcessing(box);
   if (this.bounds == null) {
     recurse(box, section.getParentSection());
     if (this.bounds == null) {
       return new StrictBounds();
     }
   }
   return this.bounds;
 }