code: public <S extends T> List<S> select(List<EvaluatedCandidate<S>> population,
                                          boolean naturalFitnessScores,
                                          int selectionSize,
                                          Random rng)
      {
          if (population.size() < groupSize)
          {
              throw new IllegalArgumentException("Population is too small for selection group size of " + groupSize);
          }
  
          int selectionCount = Math.min(selectionSize, maxSelectionsPerGeneration);
          List<S> selection = new ArrayList<S>(selectionCount);
          for (int i = 0; i < selectionCount; i++)
          {
              // Pick candidates at random (without replacement).
              List<S> group = new ArrayList<S>(groupSize);
              List<EvaluatedCandidate<S>> candidates = new ArrayList<EvaluatedCandidate<S>>(population);
              Collections.shuffle(candidates);
              for (int j = 0; j < groupSize; j++)
              {
                  group.add(candidates.get(j).getCandidate());
              }
              // Get the user to pick which one should survive to reproduce.
              selection.add(select(group));
          }
  
          // If the selection is not big enough, extend it by randomly duplicating some
          // of the selections.
          if (selectionCount < selectionSize)
          {
              List<S> extendedSelection = new ArrayList<S>(selectionSize);
              extendedSelection.addAll(selection);
              for (int i = 0; i < selectionSize - selectionCount; i++)
              {
                  extendedSelection.add(selection.get(selectionCount == 1 ? 0 : rng.nextInt(selectionCount)));
              }
              return extendedSelection;
          }
          else
          {
              return selection;
          }
      }
docs: {@inheritDoc}