code: private static List<IItem> getAllItems(List<IItem> items, boolean countHeaders, boolean subItemsOnly, IPredicate predicate) {
          List<IItem> res = new ArrayList<>();
          if (items == null || items.size() == 0) {
              return res;
          }
  
          int temp;
          int itemCount = items.size();
          IItem item;
          List<IItem> subItems;
          for (int i = 0; i < itemCount; i++) {
              item = items.get(i);
              if (item instanceof IExpandable && ((IExpandable) item).getSubItems() != null) {
                  subItems = ((IExpandable) item).getSubItems();
                  if (predicate == null) {
                      if (countHeaders) {
                          res.add(item);
                      }
                      if (subItems != null && subItems.size() > 0) {
                          res.addAll(subItems);
                      }
                      res.addAll(getAllItems(subItems, countHeaders, true, predicate));
                  } else {
                      if (countHeaders && predicate.apply(item)) {
                          res.add(item);
                      }
                      temp = subItems != null ? subItems.size() : 0;
                      for (int j = 0; j < temp; j++) {
                          if (predicate.apply(subItems.get(j))) {
                              res.add(subItems.get(j));
                          }
                      }
                  }
              }
              // in some cases, we must manually check, if the item is a sub item, process is optimised as much as possible via the subItemsOnly parameter already
              // sub items will be counted in above if statement!
              else if (!subItemsOnly && getParent(item) == null) {
                  if (predicate == null) {
                      res.add(item);
                  } else if (predicate.apply(item)) {
                      res.add(item);
                  }
              }
  
          }
          return res;
      }
docs: internal function!
  <p>
  Why countHeaders and subItems => because the subItemsOnly is an internal flag for the recursive call to optimise it!