code: @Override
      public boolean next() throws JRException {
          List<BandData> children = currentBand.getChildrenList();
  
          if (children != null && !children.isEmpty() && !visitedBands.containsKey(currentBand)) {
              currentIterator = children.iterator();
              visitedBands.put(currentBand, currentIterator);
          } else if (currentIterator == null) {
              currentIterator = Collections.singletonList(currentBand).iterator();
          }
  
          if (currentIterator.hasNext()) {
              currentBand = currentIterator.next();
              if (readBands.contains(currentBand) || currentBand.getData().isEmpty())
                  return next();
  
              return true;
          } else {
              BandData parentBand = currentBand.getParentBand();
              currentBand = parentBand;
              currentIterator = visitedBands.get(parentBand);
  
              if (parentBand == null || parentBand.equals(root))
                  return false;
  
              return next();
          }
      }
docs: Maintains visitedBands to continue bypass on the same
  level after return from deeper level of hierarchy.
  Creates iterator for each level.