code: @Override
      protected List<Node> mate(Node parent1,
                                Node parent2,
                                int numberOfCrossoverPoints,
                                Random rng)
      {
          List<Node> offspring = new ArrayList<Node>(2);
          Node offspring1 = parent1;
          Node offspring2 = parent2;
  
          for (int i = 0; i < numberOfCrossoverPoints; i++)
          {
              int crossoverPoint1 = rng.nextInt(parent1.countNodes());
              Node subTree1 = parent1.getNode(crossoverPoint1);
              int crossoverPoint2 = rng.nextInt(parent2.countNodes());
              Node subTree2 = parent2.getNode(crossoverPoint2);
              offspring1 = parent1.replaceNode(crossoverPoint1, subTree2);
              offspring2 = parent2.replaceNode(crossoverPoint2, subTree1);
          }
  
          offspring.add(offspring1);
          offspring.add(offspring2);
          return offspring;
      }
docs: Swaps randomly selected sub-trees between the two parents.
  @param parent1 The first parent.
  @param parent2 The second parent.
  @param numberOfCrossoverPoints The number of cross-overs to perform.
  @param rng A source of randomness.
  @return A list of two offspring, generated by swapping sub-trees
  between the two parents.