code: @Override
      protected List<Sudoku> mate(Sudoku parent1,
                                  Sudoku parent2,
                                  int numberOfCrossoverPoints,
                                  Random rng)
      {
          Sudoku.Cell[][] offspring1 = new Sudoku.Cell[Sudoku.SIZE][];
          Sudoku.Cell[][] offspring2 = new Sudoku.Cell[Sudoku.SIZE][];
          for (int i = 0; i < Sudoku.SIZE; i++)
          {
              offspring1[i] = parent1.getRow(i);
              offspring2[i] = parent2.getRow(i);
          }
          
          // Apply as many cross-overs as required.
          Sudoku.Cell[][] temp = new Sudoku.Cell[Sudoku.SIZE][];
          for (int i = 0; i < numberOfCrossoverPoints; i++)
          {
              // Cross-over index is always greater than zero and less than
              // the length of the parent so that we always pick a point that
              // will result in a meaningful cross-over.
              int crossoverIndex = (1 + rng.nextInt(Sudoku.SIZE - 1));
              System.arraycopy(offspring1, 0, temp, 0, crossoverIndex);
              System.arraycopy(offspring2, 0, offspring1, 0, crossoverIndex);
              System.arraycopy(temp, 0, offspring2, 0, crossoverIndex);
          }
  
          List<Sudoku> result = new ArrayList<Sudoku>(2);
          result.add(new Sudoku(offspring1));
          result.add(new Sudoku(offspring2));
          return result;
      }
docs: Applies cross-over to a pair of parents.  Cross-over is performed vertically
  (each offspring consists of some rows from {@literal parent1} and some rows
  from {@literal parent2}).
  @param parent1 The first parent.
  @param parent2 The second parent.
  @param numberOfCrossoverPoints The number of cross-overs to perform.
  @param rng The RNG used to select the cross-over points.
  @return A list containing a pair of offspring.