gt:             for (int i = 1; i < effectFadeColors.size(); i++) {
context: /***************************************************************************
   * Project file:    NPlugins - NCore - ItemMetaUtil.java                   *
   * Full Class name: fr.ribesg.bukkit.ncore.util.inventory.ItemMetaUtil     *
   *                                                                         *
   *                Copyright (c) 2012-2014 Ribesg - www.ribesg.fr           *
   *   This file is under GPLv3 -> http://www.gnu.org/licenses/gpl-3.0.txt   *
   *    Please contact me at ribesg[at]yahoo.fr if you improve this file!    *
   ***************************************************************************/
  
  package fr.ribesg.bukkit.ncore.util.inventory;
  
  import fr.ribesg.bukkit.ncore.util.ColorUtil;
  import fr.ribesg.bukkit.ncore.util.StringUtil;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.List;
  import java.util.Map;
  import java.util.TreeMap;
  
  import org.bukkit.Color;
  import org.bukkit.FireworkEffect;
  import org.bukkit.configuration.ConfigurationSection;
  import org.bukkit.enchantments.Enchantment;
  import org.bukkit.inventory.ItemStack;
  import org.bukkit.inventory.meta.BookMeta;
  import org.bukkit.inventory.meta.EnchantmentStorageMeta;
  import org.bukkit.inventory.meta.FireworkEffectMeta;
  import org.bukkit.inventory.meta.FireworkMeta;
  import org.bukkit.inventory.meta.ItemMeta;
  import org.bukkit.inventory.meta.LeatherArmorMeta;
  import org.bukkit.inventory.meta.MapMeta;
  import org.bukkit.inventory.meta.PotionMeta;
  import org.bukkit.inventory.meta.SkullMeta;
  import org.bukkit.potion.PotionEffect;
  import org.bukkit.potion.PotionEffectType;
  
  public class ItemMetaUtil {
  
      // ############ //
      // ## Global ## //
      // ############ //
  
      /**
       * Get the custom name of this ItemStack, if any.
       *
       * @param is the ItemStack
       *
       * @return the custom name of this ItemStack or an empty String
       */
      public static String getNameString(final ItemStack is) {
          final ItemMeta meta = is.getItemMeta();
          if (meta.hasDisplayName()) {
              return meta.getDisplayName();
          } else {
              return "";
          }
      }
  
      /**
       * Get a String representing the lore of this ItemStack, if any.
       *
       * @param is the ItemStack
       *
       * @return a String representing this ItemStack's lore, or an empty String
       */
      public static String getLoreString(final ItemStack is) {
          final ItemMeta meta = is.getItemMeta();
          if (meta.hasLore()) {
              final List<String> lore = meta.getLore();
              final String separator = StringUtil.getPossibleSeparator(lore, 2);
              final StringBuilder loreStringBuilder = new StringBuilder();
              for (final String loreLine : lore) {
                  loreStringBuilder.append(separator).append(loreLine);
              }
              return loreStringBuilder.toString();
          } else {
              return "";
          }
      }
  
      /**
       * Gets a String representing all special meta of this ItemStack, if any.
       *
       * @param is         the ItemStack
       * @param separators the separators
       *
       * @return a String representing this ItemStack's special meta or an empty String
       *
       * @throws InventoryUtilException if something goes wrong
       */
      public static String getSpecialMetaString(final ItemStack is, final String[] separators) throws InventoryUtilException {
          final ItemMeta meta = is.getItemMeta();
  
          if (meta instanceof BookMeta) {
              return getBookMetaString((BookMeta)meta);
          } else if (meta instanceof EnchantmentStorageMeta) {
              return getEnchantmentStorageMetaString((EnchantmentStorageMeta)meta, separators);
          } else if (meta instanceof FireworkEffectMeta) {
              return getFireworkEffectMetaString((FireworkEffectMeta)meta);
          } else if (meta instanceof FireworkMeta) {
              return getFireworkMetaString((FireworkMeta)meta, separators);
          } else if (meta instanceof LeatherArmorMeta) {
              return getLeatherArmorMetaString((LeatherArmorMeta)meta);
          } else if (meta instanceof MapMeta) {
              return getMapMetaString((MapMeta)meta);
          } else if (meta instanceof PotionMeta) {
              return getPotionMetaString((PotionMeta)meta, separators);
          } else if (meta instanceof SkullMeta) {
              return getSkullMetaString((SkullMeta)meta);
          } else {
              throw new InventoryUtilException("Unknown Meta type '" + meta.getClass().getName() + "', please report this to the author (Ribesg)!");
          }
      }
  
      /**
       * Parses 3 strings into an ItemMeta.
       *
       * @param meta              the ItemMeta to complete
       * @param nameString        the DisplayName String
       * @param loreString        the Lore String representation
       * @param specialMetaString the Special Meta part String representation
       *
       * @return the same ItemMeta, completed
       */
      public static ItemMeta fromString(final ItemMeta meta, final String nameString, final String loreString, final String specialMetaString, final String[] separators) throws InventoryUtilException {
          if (meta instanceof BookMeta) {
              parseBookMetaString(specialMetaString, (BookMeta)meta);
          } else if (meta instanceof EnchantmentStorageMeta) {
              parseEnchantmentStorageMetaString(specialMetaString, (EnchantmentStorageMeta)meta, separators);
          } else if (meta instanceof FireworkEffectMeta) {
              parseFireworkEffectMetaString(specialMetaString, (FireworkEffectMeta)meta);
          } else if (meta instanceof FireworkMeta) {
              parseFireworkMetaString(specialMetaString, (FireworkMeta)meta, separators);
          } else if (meta instanceof LeatherArmorMeta) {
              parseLeatherArmorMetaString(specialMetaString, (LeatherArmorMeta)meta);
          } else if (meta instanceof MapMeta) {
              parseMapMetaString(specialMetaString, (MapMeta)meta);
          } else if (meta instanceof PotionMeta) {
              parsePotionMetaString(specialMetaString, (PotionMeta)meta, separators);
          } else if (meta instanceof SkullMeta) {
              parseSkullMetaString(specialMetaString, (SkullMeta)meta);
          }
  
          if (!nameString.isEmpty()) {
              meta.setDisplayName(nameString);
          }
  
          if (loreString.length() > 1) {
              final List<String> lore = new ArrayList<>();
              final String separator = loreString.substring(0, 2);
              Collections.addAll(lore, StringUtil.splitKeepEmpty(loreString.substring(2), separator));
              meta.setLore(lore);
          }
  
          return meta;
      }
  
      /**
       * Saves an ItemMeta to a ConfigurationSection
       *
       * @param itemSection the parent section of the to-be-created meta section
       * @param is          the ItemStack
       */
      public static void saveToConfigSection(final ConfigurationSection itemSection, final ItemStack is) {
          final ItemMeta meta = is.getItemMeta();
  
          if (meta instanceof BookMeta) {
              saveBookMetaToConfigSection(itemSection, (BookMeta)meta);
          } else if (meta instanceof EnchantmentStorageMeta) {
              saveEnchantmentStorageMetaToConfigSection(itemSection, (EnchantmentStorageMeta)meta);
          } else if (meta instanceof FireworkEffectMeta) {
              saveFireworkEffectMetaToConfigSection(itemSection, (FireworkEffectMeta)meta);
          } else if (meta instanceof FireworkMeta) {
              saveFireworkMetaToConfigSection(itemSection, (FireworkMeta)meta);
          } else if (meta instanceof LeatherArmorMeta) {
              saveLeatherArmorMetaToConfigSection(itemSection, (LeatherArmorMeta)meta);
          } else if (meta instanceof MapMeta) {
              saveMapMetaToConfigSection(itemSection, (MapMeta)meta);
          } else if (meta instanceof PotionMeta) {
              savePotionMetaToConfigSection(itemSection, (PotionMeta)meta);
          } else if (meta instanceof SkullMeta) {
              saveSkullMetaToConfigSection(itemSection, (SkullMeta)meta);
          }
  
          if (meta.hasDisplayName()) {
              createAndGetSection(itemSection, "meta").set("name", ColorUtil.decolorize(meta.getDisplayName()));
          }
  
          if (meta.hasLore()) {
              createAndGetSection(itemSection, "meta").set("lore", ColorUtil.decolorize(meta.getLore()));
          }
      }
  
      /**
       * Gets a ConfigurationSection, eventually creating it.
       *
       * @param parent the parent ConfigurationSection
       * @param key    the key under which the ConfigurationSection will be created
       *
       * @return the ConfigurationSection
       */
      private static ConfigurationSection createAndGetSection(final ConfigurationSection parent, final String key) {
          if (!parent.isConfigurationSection(key)) {
              parent.createSection(key);
          }
          return parent.getConfigurationSection(key);
      }
  
      /**
       * Loads an ItemMeta from a ConfigurationSection.
       *
       * @param itemSection the parent section of the meta section
       * @param is          the ItemStack to complete
       *
       * @throws InventoryUtilException if something goes wrong
       */
      public static void loadFromConfigSection(final ConfigurationSection itemSection, final ItemStack is) throws InventoryUtilException {
          if (itemSection.isConfigurationSection("meta")) {
              final ItemMeta meta = is.getItemMeta();
              final ConfigurationSection metaSection = itemSection.getConfigurationSection("meta");
  
              if (meta instanceof BookMeta) {
                  loadBookMetaFromConfigSection(metaSection, (BookMeta)meta);
              } else if (meta instanceof EnchantmentStorageMeta) {
                  loadEnchantmentStorageMetaFromConfigSection(metaSection, (EnchantmentStorageMeta)meta);
              } else if (meta instanceof FireworkEffectMeta) {
                  loadFireworkEffectMetaFromConfigSection(metaSection, (FireworkEffectMeta)meta);
              } else if (meta instanceof FireworkMeta) {
                  loadFireworkMetaFromConfigSection(metaSection, (FireworkMeta)meta);
              } else if (meta instanceof LeatherArmorMeta) {
                  loadLeatherArmorMetaFromConfigSection(metaSection, (LeatherArmorMeta)meta);
              } else if (meta instanceof MapMeta) {
                  loadMapMetaFromConfigSection(metaSection, (MapMeta)meta);
              } else if (meta instanceof PotionMeta) {
                  loadPotionMetaFromConfigSection(metaSection, (PotionMeta)meta);
              } else if (meta instanceof SkullMeta) {
                  loadSkullMetaFromConfigSection(metaSection, (SkullMeta)meta);
              }
  
              final String displayName = metaSection.getString("name", "");
              if (!displayName.isEmpty()) {
                  meta.setDisplayName(ColorUtil.colorize(displayName));
              }
  
              final List<String> lore = metaSection.getStringList("lore");
              if (!lore.isEmpty()) {
                  meta.setLore(ColorUtil.colorize(lore));
              }
  
              is.setItemMeta(meta);
          }
      }
  
      // ############## //
      // ## BookMeta ## //
      // ############## //
  
      private static String getBookMetaString(final BookMeta meta) {
          final String author = meta.getAuthor();
          final String title = meta.getTitle();
          final List<String> pages = meta.getPages();
  
          final List<String> stringList = new ArrayList<>();
          stringList.add(title);
          stringList.add(author);
          stringList.addAll(pages);
  
          final String separator = StringUtil.getPossibleSeparator(stringList, 2);
          final StringBuilder builder = new StringBuilder();
          for (final String string : stringList) {
              builder.append(separator).append(string);
          }
          return builder.toString();
      }
  
      private static void parseBookMetaString(final String string, final BookMeta meta) {
          final String separator = string.substring(0, 2);
          final List<String> stringList = Arrays.asList(StringUtil.splitKeepEmpty(string, separator));
  
          final String title = stringList.remove(0);
          final String author = stringList.remove(0);
  
          meta.setTitle(title);
          meta.setAuthor(author);
          meta.setPages(stringList);
      }
  
      private static void saveBookMetaToConfigSection(final ConfigurationSection metaSection, final BookMeta meta) {
          metaSection.set("title", ColorUtil.decolorize(meta.getTitle()));
          metaSection.set("author", ColorUtil.decolorize(meta.getAuthor()));
          metaSection.set("pages", ColorUtil.decolorize(meta.getPages()));
      }
  
      private static void loadBookMetaFromConfigSection(final ConfigurationSection metaSection, final BookMeta meta) {
          final String title = ColorUtil.colorize(metaSection.getString("title"));
          final String author = ColorUtil.colorize(metaSection.getString("author"));
          final List<String> pages = ColorUtil.colorize(metaSection.getStringList("pages"));
  
          meta.setTitle(title);
          meta.setAuthor(author);
          meta.setPages(pages);
      }
  
      // ############################ //
      // ## EnchantmentStorageMeta ## //
      // ############################ //
  
      private static String getEnchantmentStorageMetaString(final EnchantmentStorageMeta meta, final String[] separators) {
          if (meta.getStoredEnchants().isEmpty()) {
              return "";
          } else {
              final StringBuilder enchantmentsStringBuilder = new StringBuilder();
              final Map<Enchantment, Integer> sortedEnchantmentMap = new TreeMap<>(EnchantmentUtil.ENCHANTMENT_COMPARATOR);
              sortedEnchantmentMap.putAll(meta.getStoredEnchants());
              for (final Map.Entry<Enchantment, Integer> e : sortedEnchantmentMap.entrySet()) {
                  enchantmentsStringBuilder.append(e.getKey().getName());
                  enchantmentsStringBuilder.append(separators[2]);
                  enchantmentsStringBuilder.append(e.getValue());
                  enchantmentsStringBuilder.append(separators[1]);
              }
              return enchantmentsStringBuilder.substring(0, enchantmentsStringBuilder.length() - separators[1].length());
          }
      }
  
      private static void parseEnchantmentStorageMetaString(final String string, final EnchantmentStorageMeta meta, final String[] separators) throws InventoryUtilException {
          if (!string.isEmpty()) {
              final String[] enchantmentsPairs = StringUtil.splitKeepEmpty(string, separators[1]);
              for (final String enchantmentPair : enchantmentsPairs) {
                  final String[] enchantmentPairSplit = StringUtil.splitKeepEmpty(enchantmentPair, separators[2]);
                  if (enchantmentPairSplit.length != 2) {
                      throw new InventoryUtilException("Malformed Enchantments field '" + string + '\'');
                  } else {
                      final String enchantmentName = enchantmentPairSplit[0];
                      final String enchantmentLevel = enchantmentPairSplit[1];
                      final Enchantment enchantment = EnchantmentUtil.getEnchantment(enchantmentName);
                      if (enchantment == null) {
                          throw new InventoryUtilException("Unknown Enchantment '" + enchantmentName + "' (parsing '\" + string + \"')\"");
                      }
                      try {
                          final int level = Integer.parseInt(enchantmentLevel);
                          if (level < 1) {
                              throw new InventoryUtilException("Invalid enchantment level '" + level + "' for enchantment '" + enchantment.getName() + "' (parsing '\" + string + \"')\"");
                          }
                          meta.addStoredEnchant(enchantment, level, true);
                      } catch (final NumberFormatException e) {
                          throw new InventoryUtilException("Invalid level value '" + enchantmentLevel + "' for enchantment '" + enchantment.getName() + "' (parsing '" + string + "')");
                      }
                  }
              }
          }
      }
  
      private static void saveEnchantmentStorageMetaToConfigSection(final ConfigurationSection metaSection, final EnchantmentStorageMeta meta) {
          final ConfigurationSection enchantmentsSection = metaSection.createSection("storedEnchantments");
          for (final Map.Entry<Enchantment, Integer> e : meta.getStoredEnchants().entrySet()) {
              enchantmentsSection.set(e.getKey().getName(), e.getValue());
          }
      }
  
      private static void loadEnchantmentStorageMetaFromConfigSection(final ConfigurationSection metaSection, final EnchantmentStorageMeta meta) throws InventoryUtilException {
          if (metaSection.isConfigurationSection("storedEnchantments")) {
              final ConfigurationSection enchantmentsSection = metaSection.getConfigurationSection("storedEnchantments");
              for (final String enchantmentName : enchantmentsSection.getKeys(false)) {
                  final Enchantment enchantment = EnchantmentUtil.getEnchantment(enchantmentName);
                  final int level = enchantmentsSection.getInt(enchantmentName, -1);
                  if (level < 1) {
                      throw new InventoryUtilException("Invalid enchantment level '" + level + "' for enchantment '" + enchantment.getName() + '\'');
                  } else {
                      meta.addStoredEnchant(enchantment, level, true);
                  }
              }
          }
      }
  
      // ######################## //
      // ## FireworkEffectMeta ## //
      // ######################## //
  
      private static String getFireworkEffectMetaString(final FireworkEffectMeta meta) {
          return getFireworkEffectString(meta.getEffect());
      }
  
      private static String getFireworkEffectString(final FireworkEffect effect) {
          final String effectType = effect.getType().name();
  
          final List<String> effectColors = new ArrayList<>();
          for (final Color color : effect.getColors()) {
              effectColors.add(Integer.toString(color.asRGB()));
          }
  
          final List<String> effectFadeColors = new ArrayList<>();
          for (final Color color : effect.getFadeColors()) {
              effectFadeColors.add(Integer.toString(color.asRGB()));
          }
  
          final List<String> allStrings = new ArrayList<>();
          allStrings.addAll(effectColors);
          allStrings.addAll(effectFadeColors);
  
          final String separator2 = StringUtil.getPossibleSeparator(allStrings, 2);
  
          allStrings.add(effectType);
  
          String separator1;
          do {
              separator1 = StringUtil.getPossibleSeparator(allStrings, 2);
          } while (separator1.equals(separator2));
  
          final StringBuilder builder = new StringBuilder();
          builder.append(separator1);
          builder.append(effectType).append(separator1);
          if (!effectColors.isEmpty()) {
              builder.append(separator2).append(effectColors.get(0));
              for (int i = 1; i < effectColors.size(); i++) {
                  builder.append(separator2).append(effectColors.get(i));
              }
          }
          builder.append(separator1);
          if (!effectFadeColors.isEmpty()) {
              builder.append(separator2).append(effectFadeColors.get(0));
  