/**
  * Returns all available groups belonging to a stage before a current stage An available group
  * should have some rank not put in groups of current the stage and must belong to the given
  * previous stage
  *
  * @param currentStage stage with participants
  * @param previousStage stage to which belong the available groups that we want
  * @return groups of the previous stage with available participants (not put in a group of the
  *     current stage)
  */
 public List<GroupEntity> getAvailableGroupsOfAPreviousStage(
     final StageEntity currentStage, final StageEntity previousStage) {
   final List<GroupEntity> resultGroups = new ArrayList<GroupEntity>();
   if (currentStage != null
       && previousStage != null
       && previousStage.getGroups() != null
       && !previousStage.getGroups().isEmpty()) {
     // number of participants already in current stage and coming from groups of previous stage by
     // group
     final Map<Long, Long> participantsByPreviousGroup =
         effectiveParticipantDao.getNumberOfEffectiveParticipantsOfAStageByInitialGroup(
             currentStage, previousStage);
     for (final GroupEntity aPreviousGroup : previousStage.getGroups()) {
       final Long numberParticipantsInCurrentStage =
           participantsByPreviousGroup.get(aPreviousGroup.getId()) != null
               ? participantsByPreviousGroup.get(aPreviousGroup.getId())
               : 0L;
       final int numberParticipantInPreviousGroup =
           aPreviousGroup.getParticipants() != null ? aPreviousGroup.getParticipants().size() : 0;
       // group is available if number of participants of the previous group put in current stage
       // is less that the number of participants in this group
       if (numberParticipantsInCurrentStage < numberParticipantInPreviousGroup) {
         resultGroups.add(aPreviousGroup);
       }
     }
   }
   return resultGroups;
 }
 /**
  * Define order, we know thanks to declaration of Stage Entity that the last existing group of the
  * stage has the max order
  *
  * @param aStage with group
  * @return order for the next group
  */
 public Integer defineNextOrderGroup(final StageEntity aStage) {
   final List<GroupEntity> listGroups = aStage.getGroups();
   Integer order = 1;
   if (listGroups != null && !listGroups.isEmpty()) {
     final Integer maxOrder = listGroups.get(listGroups.size() - 1).getOrder();
     order = maxOrder + 1;
   }
   return order;
 }
 /**
  * Fill a group and returns the group filled but not saved.
  *
  * @param aGroup a group to fill
  * @return the group with real participants
  */
 public GroupEntity fillGroup(final GroupEntity aGroup) {
   if (aGroup != null) {
     // First get the tournament
     final TournamentEntity theTournament = aGroup.getStage().getTournament();
     final boolean isTeam = theTournament.getIsTeamTournament();
     // Get players or teams list
     List<TeamEntity> teamsTournament = null;
     List<PlayerEntity> playersTournament = null;
     if (isTeam) {
       teamsTournament =
           teamService.getSortedListTeam(theTournament.getTeams(), SortType.RANKING_POINTS);
     } else {
       playersTournament =
           playerService.getSortedListPlayer(theTournament.getPlayers(), SortType.RANKING_POINTS);
     }
     // Loop over the participant of the group
     for (final EffectiveParticipantEntity aParticipant : aGroup.getParticipants()) {
       final GroupRankReference theReference = aParticipant.getInitialReference();
       final GroupEntity groupReference = theReference.getGroup();
       final StageEntity stageReference = theReference.getStage();
       final Integer rank = theReference.getRank();
       if (groupReference == null && stageReference == null) {
         // Get the real participant from tournament
         ParticipantEntity realParticipant = null;
         if (isTeam) {
           realParticipant = teamsTournament.get(rank - 1);
         } else {
           realParticipant = playersTournament.get(rank - 1);
         }
         aParticipant.setParticipant(realParticipant);
       } else if (groupReference == null && stageReference != null) {
         // Get from stage
         if (stageReference.getGroups() != null) {
           for (final GroupEntity groupReferenceStage : stageReference.getGroups()) {
             final List<EffectiveParticipantEntity> participants =
                 groupReferenceStage.getParticipants();
             for (final EffectiveParticipantEntity previousParticipant : participants) {
               final Integer finalRankStage =
                   previousParticipant.getFinalRankStage() != null
                       ? previousParticipant.getFinalRankStage()
                       : 0;
               if (finalRankStage == rank) {
                 aParticipant.setParticipant(previousParticipant.getParticipant());
                 break;
               }
             }
           }
         }
       } else {
         // Get from group
         final List<EffectiveParticipantEntity> participants = groupReference.getParticipants();
         for (final EffectiveParticipantEntity previousParticipant : participants) {
           final Integer finalRank =
               previousParticipant.getFinalRank() != null ? previousParticipant.getFinalRank() : 0;
           if (finalRank == rank) {
             aParticipant.setParticipant(previousParticipant.getParticipant());
             break;
           }
         }
       }
     }
   } else {
     final GroupEntity emptyGroup = new GroupEntity();
     emptyGroup.setParticipants(new ArrayList<EffectiveParticipantEntity>());
     return emptyGroup;
   }
   return aGroup;
 }