public static void addPresetPath(String npcName, PresetPath path, NPCHandler handle) {
    io.read();
    for (SyncWrapper wrap : io.getReadableData()) {
      io.add(wrap.getTag(), wrap.getObject());
    }
    io.add(npcName, path);
    io.write();
    presetNPCs.add(npcName);

    SimpleNPC rem = handle.getSimpleNPCByName(npcName);
    if (rem != null) {
      rem.destroyNPCObject();
    }

    LoadNPCTemplate tmp = new LoadNPCTemplate(npcName);

    tmp.loadProperties();

    SimpleNPC npc =
        tmp.getLoadedNPCTemplate().registerSimpleNPCFixedSpawn(handle, fixedSpawns.get(npcName));

    npc.setPresetPath(path);

    PresetPathsDisplay.updateSoftReference();
  }
  public static boolean removePresetPath(Player p, String npcName, NPCHandler handle) {
    if (!FileLocator.doesNPCNameExist(npcName)) {
      if (p != null) {
        QuestX.logChat(p, ChatColor.RED + LocaleBundle.getString("no_npc_name"));
      }
      return false;
    } else {
      if (!fixedSpawns.containsKey(npcName)) {
        if (p != null) {
          QuestX.logChat(p, LocaleBundle.getString("no_fixed_spawn"));
        }
        return false;
      } else {
        if (!presetNPCs.contains(npcName)) {
          QuestX.logChat(p, LocaleBundle.getString("no_preset_path"));
          return false;
        } else {
          io.read();
          io.clearWriteArray();
          io.clearReadArray();
          for (SyncWrapper wrap : loader.getReadableData()) {
            // copy all the data read, except the npc to remove
            if (!wrap.getTag().equalsIgnoreCase(npcName)) {
              io.add(wrap);
            }
          }
          io.write();

          presetNPCs.remove(npcName);

          SimpleNPC rem = handle.getSimpleNPCByName(npcName);
          if (rem != null) {
            rem.destroyNPCObject();
          }

          LoadNPCTemplate tmp = new LoadNPCTemplate(npcName);

          tmp.loadProperties();

          SimpleNPC npc =
              tmp.getLoadedNPCTemplate()
                  .registerSimpleNPCFixedSpawn(handle, fixedSpawns.get(npcName));

          npc.setAllowedToMove(true);

          PresetPathsDisplay.updateSoftReference();
          QuestX.logChat(p, ChatColor.GREEN + "Preset path for NPC " + npcName + " was removed.");
          return true;
        }
      }
    }
  }
  public static void spawnFixedNPCS(NPCHandler handle) {
    loader.read();
    io.read();

    for (SyncWrapper wrap : io.getReadableData()) {
      if (!wrap.getTag().equalsIgnoreCase("NULL")) {
        presetNPCs.add(wrap.getTag());
      }
    }

    QuestX.logDebug("wrapper length = " + loader.getReadableData().size());
    for (SyncWrapper wrapper : loader.getReadableData()) {
      if (wrapper.getTag().equalsIgnoreCase("NPC_COUNT")) {
        continue;
      }
      String npcName = wrapper.getTag();
      if (FileLocator.doesNPCNameExist(npcName)) {
        SyncLocation sl = (SyncLocation) wrapper.getObject();
        Location spawnLocation = sl.getBukkitLocation();

        LoadNPCTemplate tempLoader = new LoadNPCTemplate(npcName);

        tempLoader.loadProperties();
        NPCTemplate template = tempLoader.getLoadedNPCTemplate();

        SimpleNPC npc = template.registerSimpleNPCFixedSpawn(handle, spawnLocation);

        npc.setAllowedToMove(false);

        if (io.doesObjectExist(npcName)) {
          PresetPath path = (PresetPath) io.getObject(npcName);
          npc.setPresetPath(path);
        }

        npc.setAllowedToMove(true);

        fixedSpawns.put(npcName, spawnLocation);

      } else {
        QuestX.logError("Tried to load NPC '" + npcName + "' but no NPC file was found.");
      }
    }
    FixedSpawnsDisplay.updateSoftReference();
    PresetPathsDisplay.updateSoftReference();
  }
  public static boolean addFixedNPCSpawn(Player p, String npcName, Location l, NPCHandler handle) {
    if (!FileLocator.doesNPCNameExist(npcName)) {
      if (p != null) {
        QuestX.logChat(p, ChatColor.RED + LocaleBundle.getString("no_npc_name"));
      }
      return false;
    } else {
      if (fixedSpawns.containsKey(npcName)) {
        if (p != null) {
          QuestX.logChat(p, LocaleBundle.getString("yes_fixed_spawn"));
        }
        return false;
      }
      SimpleNPC remove = handle.getSimpleNPCByName(npcName);
      if (remove != null) {
        remove.destroyNPCObject();
      }

      LoadNPCTemplate tmp = new LoadNPCTemplate(npcName);

      tmp.loadProperties();

      tmp.getLoadedNPCTemplate().registerSimpleNPCFixedSpawn(handle, l);

      loader.read();
      for (SyncWrapper wrap : loader.getReadableData()) {
        loader.add(wrap.getTag(), wrap.getObject());
      }
      loader.add(npcName, new SyncLocation(l));
      loader.write();
      loader.clearReadArray();
      loader.clearWriteArray();

      fixedSpawns.put(npcName, l);

      FixedSpawnsDisplay.updateSoftReference();

      if (p != null) {
        QuestX.logChat(p, LocaleBundle.getString("fixed_spawn_success") + npcName + "'.");
      }
      return true;
    }
  }
  public static void spawnFixedNPC(NPCHandler handle, String name) {
    loader.read();
    io.read();
    SyncLocation sl = (SyncLocation) loader.getObject(name);
    Location spawnLocation = sl.getBukkitLocation();
    LoadNPCTemplate tempLoader = new LoadNPCTemplate(name);

    tempLoader.loadProperties();

    NPCTemplate template = tempLoader.getLoadedNPCTemplate();

    SimpleNPC npc = template.registerSimpleNPCFixedSpawn(handle, spawnLocation);

    npc.setAllowedToMove(false);

    if (io.doesObjectExist(name)) {
      PresetPath path = (PresetPath) io.getObject(name);
      npc.setPresetPath(path);
    }

    npc.setAllowedToMove(true);
  }
  public static boolean editFixedNPCSpawn(Player p, String npcName, NPCHandler handle) {
    if (!FileLocator.doesNPCNameExist(npcName)) {
      if (p != null) {
        QuestX.logChat(p, ChatColor.RED + "There is no NPC created with this name!");
      }
      return false;
    } else {
      if (!fixedSpawns.containsKey(npcName)) {
        if (p != null) {
          QuestX.logChat(p, LocaleBundle.getString("no_fixed_spawn"));
        }
        return false;
      } else {

        SimpleNPC rem = handle.getSimpleNPCByName(npcName);
        if (rem != null) {
          rem.destroyNPCObject();
        }

        loader.read();
        io.read();
        loader.clearWriteArray();
        for (SyncWrapper wrap : loader.getReadableData()) {
          // copy all the data read, except the npc to remove, set
          // this to be edited
          if (!wrap.getTag().equalsIgnoreCase(npcName)) {
            loader.add(wrap);
          } else {
            if (p != null) {
              loader.add(wrap.getTag(), new SyncLocation(p.getLocation()));
            }
          }
        }

        loader.write();
        loader.clearReadArray();
        loader.clearWriteArray();

        io.read();
        io.clearWriteArray();
        io.clearReadArray();
        for (SyncWrapper wrap : loader.getReadableData()) {
          // copy all the data read, except the npc to remove
          if (!wrap.getTag().equalsIgnoreCase(npcName)) {
            io.add(wrap);
          }
        }
        io.write();

        if (presetNPCs.contains(npcName)) {
          QuestX.logChat(p, "The preset path for NPC '" + npcName + "' was removed.");
          presetNPCs.remove(npcName);
        }

        LoadNPCTemplate tmp = new LoadNPCTemplate(npcName);

        tmp.loadProperties();

        SimpleNPC npc =
            tmp.getLoadedNPCTemplate().registerSimpleNPCFixedSpawn(handle, p.getLocation());

        npc.setAllowedToMove(true);

        if (p != null) {
          QuestX.logChat(
              p, "The fixed spawn for NPC '" + npcName + "' was changed to your current location.");
        }

        PresetPathsDisplay.updateSoftReference();

        return true;
      }
    }
  }