@Override
  protected void splitProcess(EvolutionState state) {
    splits = 0;
    List<MetaPopulation> created = new ArrayList<MetaPopulation>();
    for (MetaPopulation mp : metaPops) {
      if (mp.populations.size() > 1) {
        // Find the biggest distance between populations of the same MetaPopulation
        int maxI = -1, maxJ = -1;
        for (Integer i : mp.populations) {
          for (Integer j : mp.populations) {
            if (j > i && (maxI == -1 || distanceMatrix[i][j] > distanceMatrix[maxI][maxJ])) {
              maxI = i;
              maxJ = j;
            }
          }
        }

        double threshold =
            Math.max(
                finalThreshold, finalThreshold + thresholdDeviation - mp.age * thresholdChange);

        // Check if it needs to be split
        if (distanceMatrix[maxI][maxJ] > threshold) {
          // Determine which one will leave the metapopulation
          int exitPop = maxJ;
          if (mp.populations.size() > 2) {
            double maxIdist = 0, maxJdist = 0;
            for (Integer k : mp.populations) {
              maxIdist += distanceMatrix[k][maxI];
              maxJdist += distanceMatrix[k][maxJ];
            }
            exitPop = maxIdist > maxJdist ? maxI : maxJ;
          }

          // Do the split -- remove subpop from current metapopulation
          System.out.println(
              "Spliting "
                  + exitPop
                  + " from "
                  + mp.toString()
                  + " D: "
                  + distanceMatrix[maxI][maxJ]
                  + " T: "
                  + threshold);
          mp.populations.remove((Object) exitPop);
          mp.age = 0;

          // Create new metapopulation with subpop and the same individuals as the former metapop
          MetaPopulation mpj = new MetaPopulation();
          mpj.individuals = state.population.subpops[exitPop].individuals;
          mpj.populations.add(exitPop);
          created.add(mpj);
          splits++;
        }
      }
    }
    metaPops.addAll(created);
  }