--- ../src-base/minecraft/net/minecraftforge/common/util/EnumHelper.java
+++ ../src-work/minecraft/net/minecraftforge/common/util/EnumHelper.java
@@ -21,7 +21,23 @@
 import net.minecraft.world.EnumSkyBlock;
 import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door;
 import net.minecraftforge.classloading.FMLForgePlugin;
+// Cauldron start
+import cpw.mods.fml.relauncher.ReflectionHelper;
+import net.minecraft.inventory.IInventory;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.tileentity.TileEntity;
 
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.bukkit.World;
+import org.bukkit.WorldType;
+import org.bukkit.block.Biome;
+import org.bukkit.craftbukkit.entity.CraftEntity;
+import org.bukkit.entity.EntityType;
+import org.bukkit.event.inventory.InventoryType;
+// Cauldron end
+
 public class EnumHelper
 {
     private static Object reflectionFactory      = null;
@@ -30,6 +46,7 @@
     private static Method newFieldAccessor       = null;
     private static Method fieldAccessorSet       = null;
     private static boolean isSetup               = false;
+    private static final Logger logger = LogManager.getLogger();
 
     //Some enums are decompiled with extra arguments, so lets check for that
     @SuppressWarnings("rawtypes")
@@ -51,6 +68,73 @@
         {EnumRarity.class, EnumChatFormatting.class, String.class}
     };
 
+    // Cauldron start
+    public static Biome addBukkitBiome(String name) 
+    {
+        return (Biome)addEnum(Biome.class, name, new Class[0], new Object[0]);
+    }
+
+    public static World.Environment addBukkitEnvironment(int id, String name)
+    {
+        if (!isSetup)
+        {
+            setup();
+        }
+
+        return (World.Environment)addEnum(World.Environment.class, name, new Class[] { Integer.TYPE }, new Object[] { Integer.valueOf(id) });
+    }
+
+    public static WorldType addBukkitWorldType(String name)
+    {
+        if (!isSetup)
+        {
+            setup();
+        }
+
+        WorldType worldType = addEnum(WorldType.class, name, new Class [] { String.class }, new Object[] { name });
+        Map<String, WorldType> BY_NAME = ReflectionHelper.getPrivateValue(WorldType.class, null, "BY_NAME");
+        BY_NAME.put(name.toUpperCase(), worldType);
+
+        return worldType;
+    }
+
+    public static EntityType addBukkitEntityType(String name, Class <? extends org.bukkit.entity.Entity> clazz, int typeId, boolean independent) {
+        String entityType = name.replace("-", "_").toUpperCase();
+        EntityType bukkitType = addEnum(EntityType.class, entityType, new Class[] { String.class, Class.class, Integer.TYPE, Boolean.TYPE }, new Object[] { name, clazz, typeId, independent });
+
+        Map<String, EntityType> NAME_MAP = ReflectionHelper.getPrivateValue(EntityType.class, null, "NAME_MAP");
+        Map<Short, EntityType> ID_MAP = ReflectionHelper.getPrivateValue(EntityType.class, null, "ID_MAP");
+
+        NAME_MAP.put(name.toLowerCase(), bukkitType);
+        ID_MAP.put((short)typeId, bukkitType);
+
+
+        return bukkitType;
+    }
+
+    public static InventoryType addInventoryType(TileEntity tileentity)
+    {
+        if (!IInventory.class.isAssignableFrom(tileentity.getClass())) return null;
+        String id = (String)TileEntity.classToNameMap.get(tileentity.getClass());
+
+        try
+        {
+            IInventory teInv = (IInventory)tileentity;
+            int size = teInv.getSizeInventory();
+            return addEnum(org.bukkit.event.inventory.InventoryType.class, id, new Class[]{Integer.TYPE, String.class}, new Object[]{size, id});
+        } 
+        catch (Throwable e) 
+        {
+            if (MinecraftServer.getServer().tileEntityConfig.enableTEInventoryWarning.getValue())
+            {
+                logger.log(Level.WARN, "Could not create inventory type " + tileentity.getClass().getName() + " Exception: " + e.toString());
+                logger.log(Level.WARN, "Could not determine default inventory size for type " + tileentity.getClass().getName() + " using size of 9");
+            }
+            return addEnum(org.bukkit.event.inventory.InventoryType.class, id, new Class[]{Integer.TYPE, String.class}, new Object[]{9, id});
+        }
+    }
+    // Cauldron end
+
     public static EnumAction addAction(String name)
     {
         return addEnum(EnumAction.class, name);
@@ -280,6 +364,86 @@
         }
     }
 
+    // Cauldron start
+    @SuppressWarnings("unchecked")
+    public static <T extends Enum<?>> T replaceEnum(Class<T> enumType, String enumName, int ordinal,  Class<?>[] paramTypes, Object[] paramValues)
+    {
+        if (!isSetup)
+        {
+            setup();
+        }
+
+        Field valuesField = null;
+        Field[] fields = enumType.getDeclaredFields();
+
+        for (Field field : fields)
+        {
+            String name = field.getName();
+            if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards
+            {
+                valuesField = field;
+                break;
+            }
+        }
+
+        int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/;
+        if (valuesField == null)
+        {
+            String valueType = String.format("[L%s;", enumType.getName().replace('.', '/'));
+
+            for (Field field : fields)
+            {
+                if ((field.getModifiers() & flags) == flags &&
+                     field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't..
+                {
+                    valuesField = field;
+                    break;
+                }
+            }
+        }
+
+        if (valuesField == null)
+        {
+            FMLLog.severe("Could not find $VALUES field for enum: %s", enumType.getName());
+            FMLLog.severe("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF);
+            FMLLog.severe("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0'));
+            FMLLog.severe("Fields:");
+            for (Field field : fields)
+            {
+                String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0');
+                FMLLog.severe("       %s %s: %s", mods, field.getName(), field.getType().getName());
+            }
+            return null;
+        }
+
+        valuesField.setAccessible(true);
+        try
+        {
+            Enum[] previousValues = (Enum[])(Enum[])valuesField.get(enumType);
+            Enum[] newValues = new Enum[previousValues.length];
+            Enum newValue = null;
+            for (Enum enumValue : previousValues)
+            {
+                if (enumValue.ordinal() == ordinal)
+                {
+                    newValue = makeEnum(enumType, enumName, ordinal, paramTypes, paramValues);
+                    newValues[enumValue.ordinal()] =  newValue;
+                }
+                else newValues[enumValue.ordinal()] = enumValue;
+            }
+            List values = new ArrayList(Arrays.asList(newValues));
+            setFailsafeFieldValue(valuesField, null, values.toArray((Enum[])(Enum[])Array.newInstance(enumType, 0)));
+            cleanEnumCache(enumType);
+            return (T) newValue;
+        } 
+        catch (Exception e) 
+        {
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+    // Cauldron end
+
     static
     {
         if (!isSetup)
