code: @NonNull
      public Triple<Boolean, Item, Integer> recursive(AdapterPredicate<Item> predicate, int globalStartPosition, boolean stopOnMatch) {
          for (int i = globalStartPosition; i < getItemCount(); i++) {
              //retrieve the item + it's adapter
              RelativeInfo<Item> relativeInfo = getRelativeInfo(i);
              Item item = relativeInfo.item;
  
              if (predicate.apply(relativeInfo.adapter, i, item, i) && stopOnMatch) {
                  return new Triple<>(true, item, i);
              }
  
              if (item instanceof IExpandable) {
                  Triple<Boolean, Item, Integer> res = FastAdapter.recursiveSub(relativeInfo.adapter, i, (IExpandable) item, predicate, stopOnMatch);
                  if (res.first && stopOnMatch) {
                      return res;
                  }
              }
          }
  
          return new Triple<>(false, null, null);
      }
docs: util function which recursively iterates over all items and subItems of the given adapter.
  It executes the given `predicate` on every item and will either stop if that function returns true, or continue (if stopOnMatch is false)
  
  @param predicate           the predicate to run on every item, to check for a match or do some changes (e.g. select)
  @param globalStartPosition the start position at which we star tto recursively iterate over the items. (This will not stop at the end of a sub hierarchy!)
  @param stopOnMatch         defines if we should stop iterating after the first match
  @return Triple&lt;Boolean, IItem, Integer&gt; The first value is true (it is always not null), the second contains the item and the third the position (if the item is visible) if we had a match, (always false and null and null in case of stopOnMatch == false)