docs: private <R,T> Predicate createPredicateFromCriteriaList(
              CriteriaQuery<R> query, CriteriaBuilder builder,
              Class<T> resultType,
              List<QueryCriteria> inputCriteriaList,  QueryWhere queryWhere ) {
          Predicate queryPredicate = null;
          if( inputCriteriaList.size() > 1 ) {
  
              List<Predicate> predicateList = new LinkedList<Predicate>();
              QueryCriteria previousCriteria = null;
              QueryCriteria firstCriteria = null;
              List<QueryCriteria> currentIntersectingCriteriaList = new LinkedList<QueryCriteria>();
  
              int i = 0;
              for( QueryCriteria criteria : inputCriteriaList ) {
                  assert i++ != 0 || criteria.isFirst() : "First criteria is not flagged as first!";
  
                  if( criteria.isFirst() ) {
                     firstCriteria = previousCriteria = criteria;
                     continue;
                  } else if( firstCriteria != null ) {
                      if( criteria.isUnion() ) {
                         Predicate predicate = createPredicateFromSingleOrGroupCriteria(query, builder, resultType, previousCriteria, queryWhere);
                         predicateList.add(predicate);
                      } else {
                          currentIntersectingCriteriaList.add(firstCriteria);
                      }
                      firstCriteria = null;
                  }
  
                  if( criteria.isUnion() ) {
                      // AND has precedence over OR:
                      // If 'criteria' is now OR and there was a list (currentIntersectingCriteriaList) of AND criteria before 'criteria'
                      // - create a predicate from the AND criteria
                      if( previousCriteria != null && ! previousCriteria.isUnion() && ! currentIntersectingCriteriaList.isEmpty() ) {
                          Predicate predicate
                              = createPredicateFromIntersectingCriteriaList(query, builder, resultType, currentIntersectingCriteriaList, queryWhere );
                          assert predicate != null : "Null predicate when evaluating intersecting criteria [" + criteria.toString() + "]";
                          predicateList.add(predicate);
  
                          // - new (empty) current intersecting criteria list
                          currentIntersectingCriteriaList = new LinkedList<QueryCriteria>();
                      }
  
                      // Process the current union criteria
                      Predicate predicate = createPredicateFromSingleOrGroupCriteria(query, builder, resultType, criteria, queryWhere);
                      assert predicate != null : "Null predicate when evaluating union criteria [" + criteria.toString() + "]";
                      predicateList.add(predicate);
                  } else {
                      currentIntersectingCriteriaList.add(criteria);
                  }
  
                  previousCriteria = criteria;
              }
  
              if( ! currentIntersectingCriteriaList.isEmpty() ) {
                  Predicate predicate
                      = createPredicateFromIntersectingCriteriaList(query, builder, resultType, currentIntersectingCriteriaList, queryWhere );
                  predicateList.add(predicate);
              }
  
              assert ! predicateList.isEmpty() : "The predicate list should not (can not?) be empty here!";
              if( predicateList.size() == 1 ) {
                  queryPredicate = predicateList.get(0);
              } else {
                  Predicate [] predicates = predicateList.toArray(new Predicate[predicateList.size()]);
                  queryPredicate = builder.or(predicates);
              }
          } else if( inputCriteriaList.size() == 1 ) {
              QueryCriteria singleCriteria = inputCriteriaList.get(0);
              queryPredicate = createPredicateFromSingleOrGroupCriteria(query, builder, resultType, singleCriteria, queryWhere);
          }
  
          return queryPredicate;
      }