docs: public void deleteCrowdRegion2(S indiv, int location) {
  
      double indivFitness = fitnessFunction(indiv, lambda[location]);
  
      // find the most crowded subregion, if there are more than one, keep them in crowdList
      ArrayList<Integer> crowdList = new ArrayList<>();
      int crowdIdx;
      int nicheCount = countOnes(0);
      if (location == 0) {
        nicheCount++;
      }
      crowdList.add(0);
      for (int i = 1; i < populationSize; i++) {
        int curSize = countOnes(i);
        if (location == i) {
          curSize++;
        }
        if (curSize > nicheCount) {
          crowdList.clear();
          nicheCount = curSize;
          crowdList.add(i);
        } else if (curSize == nicheCount) {
          crowdList.add(i);
        }
      }
      // determine the index of the crowded subregion
      if (crowdList.size() == 1) {
        crowdIdx = crowdList.get(0);
      } else {
        int listLength = crowdList.size();
        crowdIdx = crowdList.get(0);
        double sumFitness = sumFitness(crowdIdx);
        if (crowdIdx == location) {
          sumFitness = sumFitness + indivFitness;
        }
        for (int i = 1; i < listLength; i++) {
          int curIdx = crowdList.get(i);
          double curFitness = sumFitness(curIdx);
          if (curIdx == location) {
            curFitness = curFitness + indivFitness;
          }
          if (curFitness > sumFitness) {
            crowdIdx = curIdx;
            sumFitness = curFitness;
          }
        }
      }
  
      // find the solution indices within the 'crowdIdx' subregion
      ArrayList<Integer> indList = new ArrayList<>();
      for (int i = 0; i < populationSize; i++) {
        if (subregionIdx[crowdIdx][i] == 1) {
          indList.add(i);
        }
      }
      if (crowdIdx == location) {
        int temp = -1;
        indList.add(temp);
      }
  
      // find the solution with the largest rank
      ArrayList<Integer> maxRankList = new ArrayList<>();
      //int maxRank = ((DoubleSolution) population.get(indList.get(0))).getRank();
      int maxRank = (int) population.get(indList.get(0)).getAttribute(ranking.getAttributeIdentifier());
      maxRankList.add(indList.get(0));
      for (int i = 1; i < indList.size(); i++) {
        int curRank;
        if (indList.get(i) == -1) {
          //curRank = indiv.getRank();
          curRank = (int) indiv.getAttribute(ranking.getAttributeIdentifier());
        } else {
          //curRank = ((DoubleSolution) population.get(indList.get(i))).getRank();
          curRank = (int) population.get(indList.get(i)).getAttribute(ranking.getAttributeIdentifier());
        }
  
        if (curRank > maxRank) {
          maxRankList.clear();
          maxRank = curRank;
          maxRankList.add(indList.get(i));
        } else if (curRank == maxRank) {
          maxRankList.add(indList.get(i));
        }
      }
  
      double maxFitness;
      int rankSize = maxRankList.size();
      int targetIdx = maxRankList.get(0);
      if (targetIdx == -1) {
        maxFitness = indivFitness;
      } else {
        maxFitness = fitnessFunction(population.get(targetIdx), lambda[crowdIdx]);
      }
      for (int i = 1; i < rankSize; i++) {
        double curFitness;
        int curIdx = maxRankList.get(i);
        if (curIdx == -1) {
          curFitness = indivFitness;
        } else {
          curFitness = fitnessFunction(population.get(curIdx), lambda[crowdIdx]);
        }
  
        if (curFitness > maxFitness) {
          targetIdx = curIdx;
          maxFitness = curFitness;
        }
      }
  
      if (targetIdx == -1) {
  
        nondominated_sorting_delete(indiv);
  
      } else {
        //int indivRank = indiv.getRank();
        int indivRank = (int) indiv.getAttribute(ranking.getAttributeIdentifier());
        //int targetRank = ((DoubleSolution) population.get(targetIdx)).getRank();
        int targetRank = (int) population.get(targetIdx).getAttribute(ranking.getAttributeIdentifier());
        rankIdx[targetRank][targetIdx] = 0;
        rankIdx[indivRank][targetIdx] = 1;
  
        S targetSol = population.get(targetIdx);
  
        replace(targetIdx, indiv);
        subregionIdx[crowdIdx][targetIdx] = 0;
        subregionIdx[location][targetIdx] = 1;
  
        // update the non-domination level structure of the population
        nondominated_sorting_delete(targetSol);
      }
  
    }