code: public static Collection<ThreadGroup> findThreadGroups(final ThreadGroup group, final boolean recurse, final ThreadGroupPredicate predicate){
          Validate.isTrue(group != null, "The group must not be null");
          Validate.isTrue(predicate != null, "The predicate must not be null");
  
          int count = group.activeGroupCount();
          ThreadGroup[] threadGroups;
          do {
              threadGroups = new ThreadGroup[count + (count / 2) + 1]; //slightly grow the array size
              count = group.enumerate(threadGroups, recurse);
              //return value of enumerate() must be strictly less than the array size according to javadoc
          } while(count >= threadGroups.length);
  
          final List<ThreadGroup> result = new ArrayList<>(count);
          for(int i = 0; i < count; ++i) {
              if(predicate.test(threadGroups[i])) {
                  result.add(threadGroups[i]);
              }
          }
          return Collections.unmodifiableCollection(result);
      }
docs: Select all active threadgroups which match the given predicate and which is a subgroup of the given thread group (or one of its subgroups).
  
  @param group the thread group
  @param recurse if {@code true} then evaluate the predicate recursively on all threadgroups in all subgroups of the given group
  @param predicate the predicate
  @return An unmodifiable {@code Collection} of active threadgroups which match the given predicate and which is a subgroup of the given thread group
  @throws IllegalArgumentException if the given group or predicate is null
  @throws  SecurityException  if the current thread cannot modify
  thread groups from this thread's thread group up to the system thread group