diff --git a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
index 79a913a..3649ae0 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/handlers/EventHandlers.java
@@ -117,32 +117,35 @@ public class EventHandlers implements Listener
                 combined.put(entry.getKey(), entry.getValue());
         }
 
-        // Get the protection enchantment rating for both enchantment sets.
-        int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0);
-        int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1);
+        if (!plugin.getConfigLoader().allowMultipleProtectionEnchantments())
+        {
+            // Get the protection enchantment rating for both enchantment sets.
+            int protVal0 = Util.getProtectionEnchantmentsVal(enchantments0);
+            int protVal1 = Util.getProtectionEnchantmentsVal(enchantments1);
 
-        // If they have different protection enchantments, keep enchantment1's enchantments
-        // And remove the protection enchantment from enchantments0. Yes, this system only works
-        // If there is 1 protection enchantment on
-        if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1)
-            switch(protVal0)
-            {
-            case 1:
-                combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
-                break;
-            case 2:
-                combined.remove(Enchantment.PROTECTION_EXPLOSIONS);
-                break;
-            case 4:
-                combined.remove(Enchantment.PROTECTION_FALL);
-                break;
-            case 8:
-                combined.remove(Enchantment.PROTECTION_FIRE);
-                break;
-            case 16:
-                combined.remove(Enchantment.PROTECTION_PROJECTILE);
-                break;
-            }
+            // If they have different protection enchantments, keep enchantment1's enchantments
+            // And remove the protection enchantment from enchantments0. Yes, this system only works
+            // If there is 1 protection enchantment on
+            if (protVal0 != 0 && protVal1 != 0 && protVal0 != protVal1)
+                switch(protVal0)
+                {
+                case 1:
+                    combined.remove(Enchantment.PROTECTION_ENVIRONMENTAL);
+                    break;
+                case 2:
+                    combined.remove(Enchantment.PROTECTION_EXPLOSIONS);
+                    break;
+                case 4:
+                    combined.remove(Enchantment.PROTECTION_FALL);
+                    break;
+                case 8:
+                    combined.remove(Enchantment.PROTECTION_FIRE);
+                    break;
+                case 16:
+                    combined.remove(Enchantment.PROTECTION_PROJECTILE);
+                    break;
+                }
+        }
         return combined;
     }
 
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
index 40d8f10..c7dac1a 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/util/ConfigLoader.java
@@ -29,6 +29,7 @@ public class ConfigLoader
     private int DIAMONDS_TO_FULL;
     private boolean noFlightDurability;
     private List<String> allowedEnchantments;
+    private boolean allowMultipleProtectionEnchantments;
 
     private ArrayList<ConfigOption<?>> configOptionsList;
     private ArmoredElytra plugin;
@@ -93,6 +94,14 @@ public class ConfigLoader
             {
                 "Specify a language file to be used. Note that en_US.txt will get regenerated!"
             };
+        String[] allowMultipleProtectionEnchantmentsComment =
+            {
+                "Allow more than 1 type of protection enchantment on a single armored elytra. ",
+                "If true, you could have both blast protection and environmental protection at the same time.",
+                "If false, the second enchantment (while crafting) will override the first. So combining an armored",
+                "elytra that has the protection enchantment with an enchanted book that has the blast protection enchantment",
+                "would result in removal of the protection enchantment and addition of the blast protection enchantment."
+            };
 
         // Set default list of allowed enchantments.
         allowedEnchantments = new ArrayList<>(Arrays.asList("DURABILITY", "PROTECTION_FIRE", "PROTECTION_EXPLOSIONS",
@@ -108,6 +117,7 @@ public class ConfigLoader
         IRON_TO_FULL = addNewConfigOption(config, "ironRepair", 4, null);
         DIAMONDS_TO_FULL = addNewConfigOption(config, "diamondsRepair", 3, null);
         allowedEnchantments = addNewConfigOption(config, "allowedEnchantments", allowedEnchantments, enchantmentsComment);
+        allowMultipleProtectionEnchantments = addNewConfigOption(config, "allowMultipleProtectionEnchantments", false, allowMultipleProtectionEnchantmentsComment);
         checkForUpdates = addNewConfigOption(config, "checkForUpdates", true, updateComment);
         allowStats = addNewConfigOption(config, "allowStats", true, bStatsComment);
         enableDebug = addNewConfigOption(config, "enableDebug", false, debugComment);
@@ -205,6 +215,11 @@ public class ConfigLoader
         return DIAMONDS_TO_FULL;
     }
 
+    public boolean allowMultipleProtectionEnchantments()
+    {
+        return allowMultipleProtectionEnchantments;
+    }
+
     public boolean uninstallMode()
     {
         return uninstallMode;
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/util/Util.java b/src/main/java/nl/pim16aap2/armoredElytra/util/Util.java
index 8a25f8d..a5253f6 100644
--- a/src/main/java/nl/pim16aap2/armoredElytra/util/Util.java
+++ b/src/main/java/nl/pim16aap2/armoredElytra/util/Util.java
@@ -76,6 +76,7 @@ public class Util
     }
 
     // Function that returns which/how many protection enchantments there are.
+    // TODO: Use bit flags for this.
     public static int getProtectionEnchantmentsVal(Map<Enchantment, Integer> enchantments)
     {
         int ret  =  0;
diff --git a/src/main/java/nl/pim16aap2/armoredElytra/util/XMaterial.java b/src/main/java/nl/pim16aap2/armoredElytra/util/XMaterial.java
new file mode 100644
index 0000000..42b25a4
--- /dev/null
+++ b/src/main/java/nl/pim16aap2/armoredElytra/util/XMaterial.java
@@ -0,0 +1,656 @@
+package nl.pim16aap2.armoredElytra.util;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+/*
+ * The MIT License (MIT)
+ *
+ * Original work Copyright (c) 2018 Hex_27
+ * v2.0 Copyright (c) 2019 Crypto Morin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+import org.apache.commons.lang.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+/*
+ * References
+ *
+ * * * GitHub: https://github.com/CryptoMorin/XMaterial/blob/master/XMaterial.java
+ * * Thread: https://www.spigotmc.org/threads/378136/
+ * https://minecraft.gamepedia.com/Java_Edition_data_values/Pre-flattening
+ * https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
+ * http://docs.codelanx.com/Bukkit/1.8/org/bukkit/Material.html
+ * https://www.spigotmc.org/threads/1-8-to-1-13-itemstack-material-version-support.329630/
+ * https://minecraft-ids.grahamedgecombe.com/
+ * v1: https://pastebin.com/Fe65HZnN
+ * v2: 6/15/2019
+ */
+
+/**
+ * XMaterial v2.2 - Data Values/Pre-flattening Supports 1.8-1.14 1.13 and above
+ * as priority.
+ */
+public enum XMaterial
+{
+
+    CHAINMAIL_CHESTPLATE(0, ""),
+    DIAMOND_CHESTPLATE(0, ""),
+    GOLDEN_CHESTPLATE(0, "GOLD_CHESTPLATE"),
+    IRON_CHESTPLATE(0, ""),
+    LEATHER_CHESTPLATE(0, ""),
+
+    AIR(0, ""),
+    ;
+
+
+    /**
+     * A list of material names that can be damaged. Some names are not complete as
+     * this list needs to be checked with {@link String#contains}.
+     */
+    public static final String[] DAMAGEABLE = { "HELMET", "CHESTPLATE", "LEGGINGS", "BOOTS", "SWORD", "AXE", "PICKAXE",
+                                                "SHOVEL", "HOE", "ELYTRA", "TRIDENT", "HORSE_ARMOR", "BARDING",
+                                                "SHEARS", "FLINT_AND_STEEL", "BOW", "FISHING_ROD", "CARROT_ON_A_STICK",
+                                                "CARROT_STICK" };
+
+    public static final XMaterial[] VALUES = XMaterial.values();
+    private static final HashMap<String, XMaterial> CACHED_SEARCH = new HashMap<>();
+    private static MinecraftVersion version;
+    private static Boolean isNewVersion;
+    private final byte data;
+    private final String[] legacy;
+
+    XMaterial(int data, String... legacy)
+    {
+        this.data = (byte) data;
+        this.legacy = legacy;
+    }
+
+    /**
+     * Checks if the version is 1.13 (Aquatic Update) or higher.
+     *
+     * @return true if 1.13 or higher.
+     */
+    public static boolean isNewVersion()
+    {
+        if (isNewVersion != null)
+            return isNewVersion;
+        return isNewVersion = isVersionOrHigher(MinecraftVersion.VERSION_1_13);
+    }
+
+    public static boolean isOneEight()
+    {
+        return getVersion() == MinecraftVersion.VERSION_1_8;
+    }
+
+    /**
+     * Uses newly added materials to minecraft to detect the server version.
+     *
+     * @return the current server version.
+     */
+    public static MinecraftVersion getVersion()
+    {
+        if (version != null)
+            return version;
+        return version = valueOfVersion(Bukkit.getVersion());
+    }
+
+    /**
+     * When using newer versions of Minecraft {@link #isNewVersion()} this helps to
+     * find the old material name with its data using a cached search for
+     * optimization.
+     *
+     * @see #matchXMaterial(String, byte)
+     */
+    private static XMaterial requestOldXMaterial(String name, byte data)
+    {
+        XMaterial cached = CACHED_SEARCH.get(name + "," + data);
+
+        if (cached != null)
+            return cached;
+        Optional<XMaterial> search = data == -1 ?
+            Arrays.stream(XMaterial.VALUES).filter(mat -> mat.matchAnyLegacy(name)).findFirst() :
+            Arrays.stream(XMaterial.VALUES).filter(mat -> mat.matchAnyLegacy(name) && mat.data == data).findFirst();
+
+        if (search.isPresent())
+        {
+            XMaterial found = search.get();
+            CACHED_SEARCH.put(found.legacy[0] + "," + found.getData(), found);
+            return found;
+        }
+        return null;
+    }
+
+    /**
+     * Checks if XMaterial enum contains a material with this name.
+     *
+     * @param name name of the material
+     * @return true if XMaterial enum has this material.
+     */
+    public static boolean contains(String name)
+    {
+        String formatted = format(name);
+        return Arrays.stream(XMaterial.VALUES).anyMatch(mat -> mat.name().equals(formatted));
+    }
+
+    /**
+     * Checks if the given material matches any of the legacy names.
+     *
+     * @param name the material name.
+     * @return true if it's a legacy name.
+     */
+    public static boolean containsLegacy(String name)
+    {
+        String formatted = format(name);
+        return Arrays.stream(Arrays.stream(XMaterial.VALUES).map(m -> m.legacy).toArray(String[]::new))
+            .anyMatch(mat -> parseLegacyVersionMaterialName(mat).equals(formatted));
+    }
+
+    /**
+     * @see #matchXMaterial(String, byte)
+     */
+    public static XMaterial matchXMaterial(Material material)
+    {
+        return matchXMaterial(material.name());
+    }
+
+    /**
+     * @see #matchXMaterial(String, byte)
+     */
+    public static XMaterial matchXMaterial(String name)
+    {
+        // -1 Determines whether the item's data is unknown and only the name is given.
+        // Checking if the item is damageable won't do anything as the data is not going
+        // to be checked in requestOldMaterial anyway.
+        return matchXMaterial(name, (byte) -1);
+    }
+
+    /**
+     * Parses the material name and data argument as a {@link Material}.
+     *
+     * @param name name of the material
+     * @param data data of the material
+     */
+    public static Material parseMaterial(String name, byte data)
+    {
+        return matchXMaterial(name, data).parseMaterial();
+    }
+
+    /**
+     * @param item the ItemStack to match its material and data.
+     * @see #matchXMaterial(String, byte)
+     */
+    @SuppressWarnings("deprecation")
+    public static XMaterial matchXMaterial(ItemStack item)
+    {
+        return isDamageable(item.getType().name()) ? matchXMaterial(item.getType().name(), (byte) 0) :
+            matchXMaterial(item.getType().name(), (byte) item.getDurability());
+    }
+
+    /**
+     * Matches the argument string and its data with a XMaterial.
+     *
+     * @param name the name of the material
+     * @param data the data byte of the material
+     * @return a XMaterial from the enum (with the same legacy name and data if in
+     *         older versions.)
+     */
+    public static XMaterial matchXMaterial(String name, byte data)
+    {
+        Validate.notEmpty(name, "Material name cannot be null or empty");
+        name = format(name);
+
+        if ((contains(name) && data <= 0))
+            return valueOf(name);
+        return requestOldXMaterial(name, data);
+    }
+
+    /**
+     * Gets the XMaterial based on the Material's ID and data. You should avoid
+     * using this for performance reasons.
+     *
+     * @param id   the ID (Magic value) of the material.
+     * @param data the data of the material.
+     * @return some XMaterial, or null.
+     */
+    public static XMaterial matchXMaterial(int id, byte data)
+    {
+        // Looping through Material.values() will take longer.
+        return Arrays.stream(XMaterial.VALUES).filter(mat -> mat.getId() == id && mat.data == data).findFirst()
+            .orElse(null);
+    }
+
+    /**
+     * Attempts to build the string like an enum name.
+     *
+     * @param name the material name to modify.
+     * @return a Material enum name.
+     */
+    private static String format(String name)
+    {
+        return name.toUpperCase().replace("MINECRAFT:", "").replace('-', '_').replaceAll("\\s+", "_").replaceAll("\\W",
+                                                                                                                 "");
+    }
+
+    /**
+     * Parses the material name if the legacy name has a version attached to it.
+     *
+     * @param name the material name to parse.
+     * @return the material name with the version removed.
+     */
+    private static String parseLegacyVersionMaterialName(String name)
+    {
+        if (!name.contains("/"))
+            return name;
+        return name.substring(0, name.indexOf('/'));
+    }
+
+    /**
+     * Checks if the version argument is the same or higher than the current server
+     * version.
+     *
+     * @param version the version to be checked.
+     * @return true of the version is equal or higher than the current version.
+     */
+    public static boolean isVersionOrHigher(MinecraftVersion version)
+    {
+        MinecraftVersion current = getVersion();
+
+        if (version == current)
+            return true;
+        if (version == MinecraftVersion.UNKNOWN)
+            return false;
+        if (current == MinecraftVersion.UNKNOWN)
+            return true;
+
+        int ver = Integer.parseInt(version.name().replace("VERSION_", "").replace("_", ""));
+        int currentVer = Integer.parseInt(current.name().replace("VERSION_", "").replace("_", ""));
+
+        return currentVer >= ver;
+    }
+
+    /**
+     * Converts the material's name to a string with the first letter uppercase.
+     *
+     * @return a converted string.
+     */
+    public static String toWord(Material material)
+    {
+        return material.name().charAt(0) + material.name().substring(1).toLowerCase();
+    }
+
+    /**
+     * Compares two major versions. The current server version and the given
+     * version.
+     *
+     * @param version the version to check.
+     * @return true if is the same as the current version or higher.
+     */
+    public static boolean isVersionOrHigher(String version)
+    {
+        int currentVer = Integer.parseInt(getExactMajorVersion(Bukkit.getVersion()).replace(".", ""));
+        int versionNumber = Integer.parseInt(version.replace(".", ""));
+
+        return currentVer >= versionNumber;
+    }
+
+    /**
+     * Gets the exact major version (..., 1.9, 1.10, ..., 1.14)
+     *
+     * @param version Supports {@link Bukkit#getVersion()},
+     *                {@link Bukkit#getBukkitVersion()} and normal formats such as
+     *                "1.14"
+     * @return the exact major version.
+     */
+    public static String getExactMajorVersion(String version)
+    {
+        // getBukkitVersion()
+        if (version.contains("SNAPSHOT") || version.contains("-R"))
+            version = version.substring(0, version.indexOf("-"));
+        // getVersion()
+        if (version.contains("git"))
+            version = version.substring(version.indexOf("MC:") + 4).replace(")", "");
+        if (version.split(Pattern.quote(".")).length > 2)
+            version = version.substring(0, version.lastIndexOf("."));
+        return version;
+    }
+
+    /**
+     * Parses the string arugment to a version. Supports
+     * {@link Bukkit#getVersion()}, {@link Bukkit#getBukkitVersion()} and normal
+     * formats such as "1.14"
+     *
+     * @param version the server version.
+     * @return the Minecraft version represented by the string.
+     */
+    private static MinecraftVersion valueOfVersion(String version)
+    {
+        version = getExactMajorVersion(version);
+        if (version.equals("1.10") || version.equals("1.11") || version.equals("1.12"))
+            return MinecraftVersion.VERSION_1_9;
+        version = version.replace(".", "_");
+        if (!version.startsWith("VERSION_"))
+            version = "VERSION_" + version;
+        String check = version;
+        return Arrays.stream(MinecraftVersion.VALUES).anyMatch(v -> v.name().equals(check)) ?
+            MinecraftVersion.valueOf(version) : MinecraftVersion.UNKNOWN;
+    }
+
+    /**
+     * Checks if the material can be damaged from {@link #DAMAGEABLE}.
+     *
+     * @param name the name of the material.
+     * @return true of the material can be damaged.
+     */
+    public static boolean isDamageable(String name)
+    {
+        return Arrays.stream(DAMAGEABLE).anyMatch(name::contains);
+    }
+
+    /**
+     * Gets the ID (Magic value) of the material. If an
+     * {@link IllegalArgumentException} was thrown from this method, you should
+     * definitely report it.
+     *
+     * @return the ID of the material. -1 if it's a new block.
+     */
+    @SuppressWarnings("deprecation")
+    public int getId()
+    {
+        return isNew() ? -1 : this.parseMaterial().getId();
+    }
+
+    /**
+     * Checks if the given string matches any of this material's legacy material
+     * names.
+     *
+     * @param name the name to check
+     * @return true if it's one of the legacy names.
+     */
+    public boolean matchAnyLegacy(String name)
+    {
+        String formatted = format(name);
+        return Arrays.asList(legacy).contains(formatted);
+    }
+
+    /**
+     * Converts the material's name to a string with the first letter uppercase.
+     *
+     * @return a converted string.
+     */
+    public String toWord()
+    {
+        return name().charAt(0) + name().substring(1).toLowerCase();
+    }
+
+    /**
+     * @return true if the item can be damaged.
+     * @see #isDamageable(String)
+     */
+    public boolean isDamageable()
+    {
+        return isDamageable(name());
+    }
+
+    /**
+     * Get the {@link ItemStack} data of this material in older versions. Which can
+     * be accessed with {@link ItemStack#getData()} then MaterialData#getData() or
+     * {@link ItemStack#getDurability()} if not damageable.
+     *
+     * @return data of this material.
+     */
+    public int getData()
+    {
+        return data;
+    }
+
+    /**
+     * Get a list of materials names that was previously used by older versions.
+     *
+     * @return a list of string of legacy material names.
+     */
+    public String[] getLegacy()
+    {
+        return legacy;
+    }
+
+    /**
+     * Parses the XMaterial as an {@link ItemStack}.
+     *
+     * @return an ItemStack with the same material (and data if in older versions.)
+     */
+    public ItemStack parseItem()
+    {
+        return parseItem(false);
+    }
+
+    /**
+     * Parses the XMaterial as an {@link ItemStack}.
+     *
+     * @param suggest if true {@link #parseMaterial(boolean)}
+     * @return an ItemStack with the same material (and data if in older versions.)
+     */
+    @SuppressWarnings("deprecation")
+    public ItemStack parseItem(boolean suggest)
+    {
+        Material material = this.parseMaterial(suggest);
+        return isNewVersion() ? new ItemStack(material) : new ItemStack(material, 1, data);
+    }
+
+    /**
+     * Parses the XMaterial as a {@link Material}.
+     *
+     * @return the Material related to this XMaterial based on the server version.
+     */
+    public Material parseMaterial()
+    {
+        return parseMaterial(false);
+    }
+
+    /**
+     * Parses the XMaterial as a {@link Material}.
+     *
+     * @param suggest Use a suggested material if the material is added in the new
+     *                version.
+     * @return the Material related to this XMaterial based on the server version.
+     * @see #matchXMaterial(String, byte)
+     */
+    public Material parseMaterial(boolean suggest)
+    {
+        Material newMat = Material.getMaterial(name());
+
+        // If the name is not null it's probably the new version.
+        // So you can still use this name even if it's a duplicated name.
+        // Since duplicated names only apply to older versions.
+        if (newMat != null && (isNewVersion()))
+            return newMat;
+        return requestOldMaterial(suggest);
+    }
+
+    /**
+     * Parses from old material names and can accept suggestions.
+     *
+     * @param suggest Accept suggestions for newly added blocks
+     * @return A parsed Material suitable for this minecraft version.
+     */
+    private Material requestOldMaterial(boolean suggest)
+    {
+        Material oldMat;
+        boolean isNew = getVersionIfNew() != MinecraftVersion.UNKNOWN;
+        for (int i = legacy.length - 1; i >= 0; i--)
+        {
+            String legacyName = legacy[i];
+            // Slash means it's just another name for the material in another version.
+            if (legacyName.contains("/"))
+            {
+                oldMat = Material.getMaterial(parseLegacyVersionMaterialName(legacyName));
+
+                if (oldMat != null)
+                    return oldMat;
+                else
+                    continue;
+            }
+            if (isNew)
+            {
+                if (suggest)
+                {
+                    oldMat = Material.getMaterial(legacyName);
+                    if (oldMat != null)
+                        return oldMat;
+                }
+                else
+                    return null;
+                // According to the suggestion format list, all the other names continuing
+                // from here are considered as a "suggestion" if there's no slash anymore.
+            }
+            oldMat = Material.getMaterial(legacyName);
+            if (oldMat != null)
+                return oldMat;
+        }
+        return null;
+    }
+
+    /**
+     * Checks if an item is similar to the material and its data (if in older
+     * versions.)
+     *
+     * @param item item to check.
+     * @return true if the material is the same as the item's material (and data if
+     *         in older versions.)
+     */
+    @SuppressWarnings("deprecation")
+    public boolean isSimilar(ItemStack item)
+    {
+        Objects.requireNonNull(item, "ItemStack cannot be null");
+        Objects.requireNonNull(item.getType(), "ItemStack's material cannot be null");
+        return (isNewVersion() || this.isDamageable()) ? item.getType() == this.parseMaterial() :
+            item.getType() == this.parseMaterial() && item.getDurability() == data;
+    }
+
+    /**
+     * Get the suggested material names that can be used instead of this material.
+     *
+     * @return a list of suggested material names.
+     */
+    public String[] getSuggestions()
+    {
+        if (!legacy[0].contains("."))
+            return new String[0];
+        return Arrays.stream(legacy).filter(mat -> !mat.contains(".")).toArray(String[]::new);
+    }
+
+    /**
+     * Checks if this material is supported in the current version. It'll check both
+     * the newest matetrial name and for legacy names.
+     *
+     * @return true if the material exists in {@link Material} list.
+     */
+    public boolean isSupported()
+    {
+        return Arrays.stream(Material.values())
+            .anyMatch(mat -> mat.name().equals(name()) || matchAnyLegacy(mat.name()));
+    }
+
+    /**
+     * Gets the added version if the material is newly added after the 1.13 Aquatic
+     * Update and higher.
+     *
+     * @return the version which the material was added in.
+     *         {@link MinecraftVersion#UNKNOWN} if not new.
+     * @see #isNew()
+     */
+    public MinecraftVersion getVersionIfNew()
+    {
+        return isNew() ? valueOfVersion(legacy[0]) : MinecraftVersion.UNKNOWN;
+    }
+
+    /**
+     * Checks if the material is newly added after the 1.13 Aquatic Update.
+     *
+     * @return true if it was newly added.
+     */
+    public boolean isNew()
+    {
+        return legacy[0].contains(".");
+    }
+
+    /**
+     * Gets the suggested material instead of returning null for unsupported
+     * versions. This is somehow similar to what ProtcolSupport and ViaVersion are
+     * doing to new materials. Don't use this if you want to parse to a
+     * {@link Material}
+     *
+     * @return The suggested material that is similar.
+     * @see #parseMaterial()
+     */
+    public XMaterial suggestOldMaterialIfNew()
+    {
+        if (getVersionIfNew() == MinecraftVersion.UNKNOWN || legacy.length == 1)
+            return null;
+
+        // We need a loop because: Newest -> Oldest
+        for (int i = legacy.length - 1; i >= 0; i--)
+        {
+            String legacyName = legacy[i];
+
+            if (legacyName.contains("/"))
+                continue;
+            XMaterial mat = matchXMaterial(parseLegacyVersionMaterialName(legacyName), data);
+            if (mat != null && this != mat)
+                return mat;
+        }
+        return null;
+    }
+
+    /**
+     * Only major versions related to material changes.
+     */
+    public enum MinecraftVersion
+    {
+        /**
+         * Bountiful Update
+         */
+        VERSION_1_8,
+        /**
+         * Combat Update (Pitiful Update?)
+         */
+        VERSION_1_9,
+        /**
+         * Aquatic Update
+         */
+        VERSION_1_13,
+        /**
+         * Village Pillage Update
+         */
+        VERSION_1_14,
+        /**
+         * 1.7 or below. Using {@link #getVersionIfNew()} it means 1.12 or below.
+         */
+        UNKNOWN;
+
+        public static final MinecraftVersion[] VALUES = MinecraftVersion.values();
+    }
+}
\ No newline at end of file