gt:             if (ct.getTemplate().isRepeatable()) {
context: /**
   * This file is part of Aion-Lightning <aion-lightning.org>.
   *
   *  Aion-Lightning is free software: you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation, either version 3 of the License, or
   *  (at your option) any later version.
   *
   *  Aion-Lightning is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details. *
   *
   *  You should have received a copy of the GNU General Public License
   *  along with Aion-Lightning.
   *  If not, see <http://www.gnu.org/licenses/>.
   *
   *
   * Credits goes to all Open Source Core Developer Groups listed below
   * Please do not change here something, ragarding the developer credits, except the "developed by XXXX".
   * Even if you edit a lot of files in this source, you still have no rights to call it as "your Core".
   * Everybody knows that this Emulator Core was developed by Aion Lightning 
   * @-Aion-Unique-
   * @-Aion-Lightning
   * @Aion-Engine
   * @Aion-Extreme
   * @Aion-NextGen
   * @Aion-Core Dev.
   */
  package com.aionemu.gameserver.services;
  
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.TreeMap;
  
  import javolution.util.FastMap;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import com.aionemu.commons.database.dao.DAOManager;
  import com.aionemu.gameserver.configs.main.CustomConfig;
  import com.aionemu.gameserver.dao.ChallengeTasksDAO;
  import com.aionemu.gameserver.dao.LegionMemberDAO;
  import com.aionemu.gameserver.dao.PlayerDAO;
  import com.aionemu.gameserver.dao.TownDAO;
  import com.aionemu.gameserver.dataholders.DataManager;
  import com.aionemu.gameserver.model.challenge.ChallengeQuest;
  import com.aionemu.gameserver.model.challenge.ChallengeTask;
  import com.aionemu.gameserver.model.gameobjects.LetterType;
  import com.aionemu.gameserver.model.gameobjects.player.Player;
  import com.aionemu.gameserver.model.team.legion.LegionMember;
  import com.aionemu.gameserver.model.templates.challenge.ChallengeTaskTemplate;
  import com.aionemu.gameserver.model.templates.challenge.ChallengeType;
  import com.aionemu.gameserver.model.templates.challenge.ContributionReward;
  import com.aionemu.gameserver.model.town.Town;
  import com.aionemu.gameserver.network.aion.serverpackets.SM_CHALLENGE_LIST;
  import com.aionemu.gameserver.network.aion.serverpackets.SM_SYSTEM_MESSAGE;
  import com.aionemu.gameserver.services.mail.SystemMailService;
  import com.aionemu.gameserver.utils.PacketSendUtility;
  import com.aionemu.gameserver.world.World;
  
  /**
   * @author ViAl
   */
  public class ChallengeTaskService {
  
      private Map<Integer, Map<Integer, ChallengeTask>> cityTasks;
      private Map<Integer, Map<Integer, ChallengeTask>> legionTasks;
      private static final Logger log = LoggerFactory.getLogger(ChallengeTaskService.class);
  
      private ChallengeTaskService() {
          cityTasks = new FastMap<Integer, Map<Integer, ChallengeTask>>().shared();
          legionTasks = new FastMap<Integer, Map<Integer, ChallengeTask>>().shared();
          log.info("ChallengeTaskService initialized.");
      }
  
      public void onChallengeQuestFinish(Player player, int questId) {
          ChallengeTaskTemplate taskTemplate = DataManager.CHALLENGE_DATA.getTaskByQuestId(questId);
          switch (taskTemplate.getType()) {
              case TOWN:
                  onCityTaskFinish(player, taskTemplate, questId);
                  break;
              case LEGION:
                  onLegionTaskFinish(player, taskTemplate, questId);
                  break;
          }
      }
  
      private void onCityTaskFinish(Player player, ChallengeTaskTemplate taskTemplate, int questId) {
          int townId = TownService.getInstance().getTownIdByPosition(player);
          if (cityTasks.get(townId) == null) {
              buildTaskList(player, ChallengeType.TOWN, townId, TownService.getInstance().getTownById(townId).getLevel());
              if (cityTasks.get(townId) == null) {
                  log.warn("Town not in CityTasks! TownId:" + townId + "; Player town residence:" + TownService.getInstance().getTownResidence(player));
                  return;
              }
          }
          ChallengeTask task = cityTasks.get(townId).get(taskTemplate.getId());
          if (task == null || task.getQuests().get(questId) == null) {
              log.warn("Player " + player.getName() + " trying to finish city task in the city which haven't task with this id. Town id:" + townId + ", task id:" + taskTemplate.getId() + ", quest id:" + questId);
              return;
          }
          ChallengeQuest quest = task.getQuests().get(questId);
          if (quest.getCompleteCount() >= quest.getMaxRepeats()) {
              return;
          }
          if (!task.isCompleted()) {
              task.updateCompleteTime();
              quest.increaseCompleteCount();
              DAOManager.getDAO(ChallengeTasksDAO.class).storeTask(task);
              Town town = TownService.getInstance().getTownById(townId);
              if (town != null) {
                  int oldLevel = town.getLevel();
                  town.increasePoints(quest.getScorePerQuest());
                  if (task.isCompleted()) {
                      switch (taskTemplate.getReward().getType()) {
                          case POINT:
                              town.increasePoints(taskTemplate.getReward().getValue());
                              break;
                          case SPAWN:
                              // TODO
                              break;
  					default:
  						break;
                      }
                      // PacketSendUtility.sendPacket(player, new SM_SYSTEM_MESSAGE(1401519, new DescriptionId(804307), 601));
                  }
                  if (town.getLevel() != oldLevel) {
                      PacketSendUtility.sendPacket(player, new SM_SYSTEM_MESSAGE(1401520, town.getId(), town.getLevel()));
                  }
                  DAOManager.getDAO(TownDAO.class).store(town);
              }
          }
      }
  
      private void onLegionTaskFinish(Player player, ChallengeTaskTemplate taskTemplate, int questId) {
          /**
           * Player could take challenge task and after that leave legion.
           */
          if (player.getLegion() == null) {
              return;
          }
          int legionId = player.getLegion().getLegionId();
          /**
           * If player took challenge task in one legion, then leave that legion
           * and enter another.
           */
          if (!legionTasks.containsKey(legionId)) {
              return;
          }
          /**
           * If player took challenge task in one legion, then leave that legion
           * and enter another, and after that completed this task in new legion.
           */
          if (legionTasks.get(legionId).get(taskTemplate.getId()) == null) {
              return;
          }
          ChallengeTask task = legionTasks.get(player.getLegion().getLegionId()).get(taskTemplate.getId());
          ChallengeQuest quest = task.getQuests().get(questId);
          if (quest.getCompleteCount() >= quest.getMaxRepeats()) {
              return;
          }
          player.getLegionMember().increaseChallengeScore(quest.getScorePerQuest());
          if (!task.isCompleted()) {
              task.updateCompleteTime();
              quest.increaseCompleteCount();
              DAOManager.getDAO(ChallengeTasksDAO.class).storeTask(task);
              if (task.isCompleted()) {
                  TreeMap<Integer, List<Integer>> winnersByPoints = new TreeMap<Integer, List<Integer>>();
                  for (Integer memberObjId : player.getLegion().getLegionMembers()) {
                      Player member = World.getInstance().findPlayer(memberObjId);
                      if (member != null) {
                          int score = member.getLegionMember().getChallengeScore();
                          if (winnersByPoints.get(score) == null) {
                              winnersByPoints.put(score, new ArrayList<Integer>());
                          }
                          winnersByPoints.get(score).add(member.getObjectId());
                          member.getLegionMember().setChallengeScore(0);
                          continue;
                      } else {
                          LegionMember legionMember = DAOManager.getDAO(LegionMemberDAO.class).loadLegionMember(memberObjId);
                          int score = legionMember.getChallengeScore();
                          if (winnersByPoints.get(score) == null) {
                              winnersByPoints.put(score, new ArrayList<Integer>());
                          }
                          winnersByPoints.get(score).add(legionMember.getObjectId());
                          legionMember.setChallengeScore(0);
                          DAOManager.getDAO(LegionMemberDAO.class).storeLegionMember(memberObjId, legionMember);
                      }
                  }
                  int rewardsAdded = 0, itemId, itemCount;
                  for (Entry<Integer, List<Integer>> e : winnersByPoints.descendingMap().entrySet()) {
                      for (int objectId : e.getValue()) {
                          for (ContributionReward reward : taskTemplate.getContrib()) {
                              if (rewardsAdded <= reward.getNumber()) {
                                  rewardsAdded++;
                                  itemId = reward.getRewardId();
                                  itemCount = reward.getItemCount();
                                  String recipientName = DAOManager.getDAO(PlayerDAO.class).loadPlayerCommonData(objectId).getName();
                                  SystemMailService.getInstance().sendMail("Legion reward", recipientName, "", "", itemId, itemCount, 0, LetterType.NORMAL);
                                  break;
                              }
                          }
                      }
                      e.getValue().clear();
                  }
                  winnersByPoints.clear();
                  winnersByPoints = null;
              }
          }
      }    
      
      public void showTaskList(Player player, ChallengeType challengeType, int ownerId) {
          if (CustomConfig.CHALLENGE_TASKS_ENABLED) {
              int ownerLevel = 0;
              switch (challengeType) {
                  case TOWN:
                      ownerLevel = TownService.getInstance().getTownById(ownerId).getLevel();
                      break;
                  case LEGION:
                      ownerLevel = player.getLegion().getLegionLevel();
                      break;
              }
              List<ChallengeTask> availableTasks = buildTaskList(player, challengeType, ownerId, ownerLevel);
              PacketSendUtility.sendPacket(player, new SM_CHALLENGE_LIST(2, ownerId, challengeType, availableTasks));
              for (ChallengeTask task : availableTasks) {
                  PacketSendUtility.sendPacket(player, new SM_CHALLENGE_LIST(7, ownerId, challengeType, task));
              }
          }
      }
  
      private List<ChallengeTask> buildTaskList(Player player, ChallengeType challengeType, int ownerId, int ownerLevel) {
          Map<Integer, Map<Integer, ChallengeTask>> taskMap = null;
          if (challengeType == ChallengeType.LEGION) {
              taskMap = legionTasks;
          } else if (challengeType == ChallengeType.TOWN) {
              taskMap = cityTasks;
          }
          int playerTownId = TownService.getInstance().getTownResidence(player);
          List<ChallengeTask> availableTasks = new ArrayList<ChallengeTask>();
          if (!taskMap.containsKey(ownerId)) {
              Map<Integer, ChallengeTask> tasks = DAOManager.getDAO(ChallengeTasksDAO.class).load(ownerId, challengeType);
              taskMap.put(ownerId, tasks);
          }
          for (ChallengeTask ct : taskMap.get(ownerId).values()) {
  