gt:             for (MapleData idata : monsterData) {
context: package server.life;
  
  import constants.GameConstants;
  import database.DatabaseConnection;
  import java.awt.Point;
  import java.io.File;
  import java.sql.Connection;
  import java.sql.PreparedStatement;
  import java.sql.ResultSet;
  import java.sql.SQLException;
  import java.util.ArrayList;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.HashMap;
  import java.util.Map;
  
  import provider.MapleData;
  import provider.MapleDataDirectoryEntry;
  import provider.MapleDataFileEntry;
  import provider.MapleDataProvider;
  import provider.MapleDataProviderFactory;
  import provider.MapleDataTool;
  import provider.MapleDataType;
  import server.Randomizer;
  import tools.Pair;
  import tools.StringUtil;
  
  public class MapleLifeFactory {
  
      private static final MapleDataProvider data = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Mob.wz"));
      private static final MapleDataProvider npcData = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Npc.wz"));
      private static final MapleDataProvider stringDataWZ = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/String.wz"));
      private static final MapleDataProvider etcDataWZ = MapleDataProviderFactory.getDataProvider(new File(System.getProperty("wzpath") + "/Etc.wz"));
      private static final MapleData mobStringData = stringDataWZ.getData("Mob.img");
      private static final MapleData npcStringData = stringDataWZ.getData("Npc.img");
      private static final MapleData npclocData = etcDataWZ.getData("NpcLocation.img");
      private static final Map<Integer, String> npcNames = new HashMap<>();
      private static final Map<Integer, MapleMonsterStats> monsterStats = new HashMap<>();
      private static final Map<Integer, Integer> NPCLoc = new HashMap<>();
      private static final Map<Integer, List<Integer>> questCount = new HashMap<>();
  
      public static AbstractLoadedMapleLife getLife(int id, String type) {
          if (type.equalsIgnoreCase("n")) {
              return getNPC(id);
          } else if (type.equalsIgnoreCase("m")) {
              return getMonster(id);
          } else {
              System.err.println("Unknown Life type: " + type + "");
              return null;
          }
      }
  
      public static int getNPCLocation(int npcid) {
          if (NPCLoc.containsKey(npcid)) {
              return NPCLoc.get(npcid);
          }
          final int map = MapleDataTool.getIntConvert(Integer.toString(npcid) + "/0", npclocData, -1);
          NPCLoc.put(npcid, map);
          return map;
      }
  
      public static void loadQuestCounts() {
          if (questCount.size() > 0) {
              return;
          }
          for (MapleDataDirectoryEntry mapz : data.getRoot().getSubdirectories()) {
              if (mapz.getName().equals("QuestCountGroup")) {
                  for (MapleDataFileEntry entry : mapz.getFiles()) {
                      final int id = Integer.parseInt(entry.getName().substring(0, entry.getName().length() - 4));
                      MapleData dat = data.getData("QuestCountGroup/" + entry.getName());
                      if (dat != null && dat.getChildByPath("info") != null) {
                          List<Integer> z = new ArrayList<>();
                          for (MapleData da : dat.getChildByPath("info")) {
                              z.add(MapleDataTool.getInt(da, 0));
                          }
                          questCount.put(id, z);
                      } else {
                          System.out.println("null questcountgroup");
                      }
                  }
              }
          }
          /*for (MapleData c : npcStringData) {
           int nid = Integer.parseInt(c.getName());
           String n = StringUtil.getLeftPaddedStr(nid + ".img", '0', 11);
           try {
           if (npcData.getData(n) != null) {//only thing we really have to do is check if it exists. if we wanted to, we could get the script as well :3
           String name = MapleDataTool.getString("name", c, "MISSINGNO");
           if (name.contains("Maple TV") || name.contains("Baby Moon Bunny")) {
           continue;
           }
           npcNames.put(nid, name);
           }
           } catch (NullPointerException e) {
           } catch (RuntimeException e) { //swallow, don't add if 
           }
           }*/
          Connection con = DatabaseConnection.getConnection();
          try {
              try (PreparedStatement ps = con.prepareStatement("SELECT * FROM wz_npcnamedata ORDER BY `npc`"); ResultSet rs = ps.executeQuery()) {
                  while (rs.next()) {
                      npcNames.put(rs.getInt("npc"), rs.getString("name"));
                  }
              }
          } catch (SQLException ex) {
              System.out.println("Failed to load npc name data. " + ex);
          }
      }
  
      public static List<Integer> getQuestCount(final int id) {
          return questCount.get(id);
      }
  
      public static MapleMonster getMonster(int mid) {
          MapleMonsterStats stats = getMonsterStats(mid);
          if (stats == null) {
              return null;
          }
          return new MapleMonster(mid, stats);
      }
  
      public static MapleMonsterStats getMonsterStats(int mid) {
          MapleMonsterStats stats = monsterStats.get(Integer.valueOf(mid));
  
          if (stats == null) {
              MapleData monsterData;
              try {
                  monsterData = data.getData(StringUtil.getLeftPaddedStr(Integer.toString(mid) + ".img", '0', 11));
              } catch (RuntimeException e) {
                  return null;
              }
              if (monsterData == null) {
                  return null;
              }
              MapleData monsterInfoData = monsterData.getChildByPath("info");
              stats = new MapleMonsterStats(mid);
  
              stats.setHp((int) (GameConstants.getPartyPlayHP(mid) > 0 ? GameConstants.getPartyPlayHP(mid) : MapleDataTool.getLongConvert("maxHP", monsterInfoData)));
              stats.setMp(MapleDataTool.getIntConvert("maxMP", monsterInfoData, 0));
              stats.setExp(mid == 9300027 ? 0 : (GameConstants.getPartyPlayEXP(mid) > 0 ? GameConstants.getPartyPlayEXP(mid) : MapleDataTool.getIntConvert("exp", monsterInfoData, 0)));
              stats.setLevel((short) MapleDataTool.getIntConvert("level", monsterInfoData, 1));
              stats.setCharismaEXP((short) MapleDataTool.getIntConvert("charismaEXP", monsterInfoData, 0));
              stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", monsterInfoData, 0));
              stats.setrareItemDropLevel((byte) MapleDataTool.getIntConvert("rareItemDropLevel", monsterInfoData, 0));
              stats.setFixedDamage(MapleDataTool.getIntConvert("fixedDamage", monsterInfoData, -1));
              stats.setOnlyNormalAttack(MapleDataTool.getIntConvert("onlyNormalAttack", monsterInfoData, 0) > 0);
              stats.setBoss(GameConstants.getPartyPlayHP(mid) > 0 || MapleDataTool.getIntConvert("boss", monsterInfoData, 0) > 0 || mid == 8810018 || mid == 9410066 || (mid >= 8810118 && mid <= 8810122));
              stats.setExplosiveReward(MapleDataTool.getIntConvert("explosiveReward", monsterInfoData, 0) > 0);
              stats.setUndead(MapleDataTool.getIntConvert("undead", monsterInfoData, 0) > 0);
              stats.setEscort(MapleDataTool.getIntConvert("escort", monsterInfoData, 0) > 0);
              stats.setPartyBonus(GameConstants.getPartyPlayHP(mid) > 0 || MapleDataTool.getIntConvert("partyBonusMob", monsterInfoData, 0) > 0);
              stats.setPartyBonusRate(MapleDataTool.getIntConvert("partyBonusR", monsterInfoData, 0));
              if (mobStringData.getChildByPath(String.valueOf(mid)) != null) {
                  stats.setName(MapleDataTool.getString("name", mobStringData.getChildByPath(String.valueOf(mid)), "MISSINGNO"));
              }
              stats.setBuffToGive(MapleDataTool.getIntConvert("buff", monsterInfoData, -1));
              stats.setChange(MapleDataTool.getIntConvert("changeableMob", monsterInfoData, 0) > 0);
              stats.setFriendly(MapleDataTool.getIntConvert("damagedByMob", monsterInfoData, 0) > 0);
              stats.setNoDoom(MapleDataTool.getIntConvert("noDoom", monsterInfoData, 0) > 0);
              stats.setFfaLoot(MapleDataTool.getIntConvert("publicReward", monsterInfoData, 0) > 0);
              stats.setCP((byte) MapleDataTool.getIntConvert("getCP", monsterInfoData, 0));
              stats.setPoint(MapleDataTool.getIntConvert("point", monsterInfoData, 0));
              stats.setDropItemPeriod(MapleDataTool.getIntConvert("dropItemPeriod", monsterInfoData, 0));
              stats.setPhysicalAttack(MapleDataTool.getIntConvert("PADamage", monsterInfoData, 0));
              stats.setMagicAttack(MapleDataTool.getIntConvert("MADamage", monsterInfoData, 0));
              stats.setPDRate((byte) MapleDataTool.getIntConvert("PDRate", monsterInfoData, 0));
              stats.setMDRate((byte) MapleDataTool.getIntConvert("MDRate", monsterInfoData, 0));
              stats.setAcc(MapleDataTool.getIntConvert("acc", monsterInfoData, 0));
              stats.setEva(MapleDataTool.getIntConvert("eva", monsterInfoData, 0));
              stats.setSummonType((byte) MapleDataTool.getIntConvert("summonType", monsterInfoData, 0));
              stats.setCategory((byte) MapleDataTool.getIntConvert("category", monsterInfoData, 0));
              stats.setSpeed(MapleDataTool.getIntConvert("speed", monsterInfoData, 0));
              stats.setPushed(MapleDataTool.getIntConvert("pushed", monsterInfoData, 0));
              //final boolean hideHP = MapleDataTool.getIntConvert("HPgaugeHide", monsterInfoData, 0) > 0 || MapleDataTool.getIntConvert("hideHP", monsterInfoData, 0) > 0;
              final MapleData selfd = monsterInfoData.getChildByPath("selfDestruction");
              if (selfd != null) {
                  stats.setSelfDHP(MapleDataTool.getIntConvert("hp", selfd, 0));
                  stats.setRemoveAfter(MapleDataTool.getIntConvert("removeAfter", selfd, stats.getRemoveAfter()));
                  stats.setSelfD((byte) MapleDataTool.getIntConvert("action", selfd, -1));
              } else {
                  stats.setSelfD((byte) -1);
              }
              final MapleData firstAttackData = monsterInfoData.getChildByPath("firstAttack");
              if (firstAttackData != null) {
                  if (firstAttackData.getType() == MapleDataType.FLOAT) {
                      stats.setFirstAttack(Math.round(MapleDataTool.getFloat(firstAttackData)) > 0);
                  } else {
                      stats.setFirstAttack(MapleDataTool.getInt(firstAttackData) > 0);
                  }
              }
              if (stats.isBoss() || isDmgSponge(mid)) {
                  if (/*
                           * hideHP ||
                           */monsterInfoData.getChildByPath("hpTagColor") == null || monsterInfoData.getChildByPath("hpTagBgcolor") == null) {
                      stats.setTagColor(0);
                      stats.setTagBgColor(0);
                  } else {
                      stats.setTagColor(MapleDataTool.getIntConvert("hpTagColor", monsterInfoData));
                      stats.setTagBgColor(MapleDataTool.getIntConvert("hpTagBgcolor", monsterInfoData));
                  }
              }
  
              final MapleData banishData = monsterInfoData.getChildByPath("ban");
              if (banishData != null) {
                  stats.setBanishInfo(new BanishInfo(
                          MapleDataTool.getString("banMsg", banishData),
                          MapleDataTool.getInt("banMap/0/field", banishData, -1),
                          MapleDataTool.getString("banMap/0/portal", banishData, "sp")));
              }
  
              final MapleData reviveInfo = monsterInfoData.getChildByPath("revive");
              if (reviveInfo != null) {
                  List<Integer> revives = new LinkedList<>();
                  for (MapleData bdata : reviveInfo) {
                      revives.add(MapleDataTool.getInt(bdata));
                  }
                  stats.setRevives(revives);
              }
  
              final MapleData monsterSkillData = monsterInfoData.getChildByPath("skill");
              if (monsterSkillData != null) {
                  int i = 0;
                  List<Pair<Integer, Integer>> skills = new ArrayList<>();
                  while (monsterSkillData.getChildByPath(Integer.toString(i)) != null) {
                      skills.add(new Pair<>(MapleDataTool.getInt(i + "/skill", monsterSkillData, 0), MapleDataTool.getInt(i + "/level", monsterSkillData, 0)));
                      i++;
                  }
                  stats.setSkills(skills);
              }
  
              decodeElementalString(stats, MapleDataTool.getString("elemAttr", monsterInfoData, ""));
  
              // Other data which isn't in the mob, but might in the linked data
              final int link = MapleDataTool.getIntConvert("link", monsterInfoData, 0);
              stats.setLink(link);
              if (link != 0) { // Store another copy, for faster processing.
                  monsterData = data.getData(StringUtil.getLeftPaddedStr(link + ".img", '0', 11));
              }
              OUTER:
  