diff --git a/CraftBukkit-Patches/0002-mc-dev-imports.patch b/CraftBukkit-Patches/0002-mc-dev-imports.patch
index f2e2c84a3a..b573897855 100644
--- a/CraftBukkit-Patches/0002-mc-dev-imports.patch
+++ b/CraftBukkit-Patches/0002-mc-dev-imports.patch
@@ -1,4 +1,4 @@
-From 889d5efb0e10f4111b4ecda5b2e42e6ee82f641e Mon Sep 17 00:00:00 2001
+From 401298e7004254ee150ea7bcd6263eaf68cd6fc1 Mon Sep 17 00:00:00 2001
 From: md_5 <md_5@live.com.au>
 Date: Sun, 1 Dec 2013 15:10:48 +1100
 Subject: [PATCH] mc-dev imports
@@ -1526,343 +1526,6 @@ index 0000000..3eeed3e
 +        return this.data;
 +    }
 +}
-diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java
-new file mode 100644
-index 0000000..5b8842f
---- /dev/null
-+++ b/src/main/java/net/minecraft/server/NBTTagCompound.java
-@@ -0,0 +1,331 @@
-+package net.minecraft.server;
-+
-+import java.io.DataInput;
-+import java.io.DataOutput;
-+import java.io.IOException;
-+import java.util.HashMap;
-+import java.util.Iterator;
-+import java.util.Map;
-+import java.util.Set;
-+import java.util.concurrent.Callable;
-+
-+import org.apache.logging.log4j.LogManager;
-+import org.apache.logging.log4j.Logger;
-+
-+public class NBTTagCompound extends NBTBase {
-+
-+    private static final Logger b = LogManager.getLogger();
-+    private Map map = new HashMap();
-+
-+    public NBTTagCompound() {}
-+
-+    void write(DataOutput dataoutput) throws IOException
-+    {
-+        Iterator iterator = this.map.keySet().iterator();
-+
-+        while (iterator.hasNext()) {
-+            String s = (String) iterator.next();
-+            NBTBase nbtbase = (NBTBase) this.map.get(s);
-+
-+            a(s, nbtbase, dataoutput);
-+        }
-+
-+        dataoutput.writeByte(0);
-+    }
-+
-+    void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException
-+    {
-+        if (i > 512) {
-+            throw new RuntimeException("Tried to read NBT tag with too high complexity, depth > 512");
-+        } else {
-+            this.map.clear();
-+
-+            byte b0;
-+
-+            while ((b0 = a(datainput, nbtreadlimiter)) != 0) {
-+                String s = b(datainput, nbtreadlimiter);
-+
-+                nbtreadlimiter.a((long) (16 * s.length()));
-+                NBTBase nbtbase = a(b0, s, datainput, i + 1, nbtreadlimiter);
-+
-+                this.map.put(s, nbtbase);
-+            }
-+        }
-+    }
-+
-+    public Set c() {
-+        return this.map.keySet();
-+    }
-+
-+    public byte getTypeId() {
-+        return (byte) 10;
-+    }
-+
-+    public void set(String s, NBTBase nbtbase) {
-+        this.map.put(s, nbtbase);
-+    }
-+
-+    public void setByte(String s, byte b0) {
-+        this.map.put(s, new NBTTagByte(b0));
-+    }
-+
-+    public void setShort(String s, short short1) {
-+        this.map.put(s, new NBTTagShort(short1));
-+    }
-+
-+    public void setInt(String s, int i) {
-+        this.map.put(s, new NBTTagInt(i));
-+    }
-+
-+    public void setLong(String s, long i) {
-+        this.map.put(s, new NBTTagLong(i));
-+    }
-+
-+    public void setFloat(String s, float f) {
-+        this.map.put(s, new NBTTagFloat(f));
-+    }
-+
-+    public void setDouble(String s, double d0) {
-+        this.map.put(s, new NBTTagDouble(d0));
-+    }
-+
-+    public void setString(String s, String s1) {
-+        this.map.put(s, new NBTTagString(s1));
-+    }
-+
-+    public void setByteArray(String s, byte[] abyte) {
-+        this.map.put(s, new NBTTagByteArray(abyte));
-+    }
-+
-+    public void setIntArray(String s, int[] aint) {
-+        this.map.put(s, new NBTTagIntArray(aint));
-+    }
-+
-+    public void setBoolean(String s, boolean flag) {
-+        this.setByte(s, (byte) (flag ? 1 : 0));
-+    }
-+
-+    public NBTBase get(String s) {
-+        return (NBTBase) this.map.get(s);
-+    }
-+
-+    public byte b(String s) {
-+        NBTBase nbtbase = (NBTBase) this.map.get(s);
-+
-+        return nbtbase != null ? nbtbase.getTypeId() : 0;
-+    }
-+
-+    public boolean hasKey(String s) {
-+        return this.map.containsKey(s);
-+    }
-+
-+    public boolean hasKeyOfType(String s, int i) {
-+        byte b0 = this.b(s);
-+
-+        if (b0 == i) {
-+            return true;
-+        } else if (i != 99) {
-+            if (b0 > 0) {
-+                b.warn("NBT tag {} was of wrong type; expected {}, found {}", new Object[] { s, getTagName(i), getTagName(b0)});
-+            }
-+
-+            return false;
-+        } else {
-+            return b0 == 1 || b0 == 2 || b0 == 3 || b0 == 4 || b0 == 5 || b0 == 6;
-+        }
-+    }
-+
-+    public byte getByte(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0 : ((NBTNumber) this.map.get(s)).f();
-+        } catch (ClassCastException classcastexception) {
-+            return (byte) 0;
-+        }
-+    }
-+
-+    public short getShort(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0 : ((NBTNumber) this.map.get(s)).e();
-+        } catch (ClassCastException classcastexception) {
-+            return (short) 0;
-+        }
-+    }
-+
-+    public int getInt(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0 : ((NBTNumber) this.map.get(s)).d();
-+        } catch (ClassCastException classcastexception) {
-+            return 0;
-+        }
-+    }
-+
-+    public long getLong(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0L : ((NBTNumber) this.map.get(s)).c();
-+        } catch (ClassCastException classcastexception) {
-+            return 0L;
-+        }
-+    }
-+
-+    public float getFloat(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0.0F : ((NBTNumber) this.map.get(s)).h();
-+        } catch (ClassCastException classcastexception) {
-+            return 0.0F;
-+        }
-+    }
-+
-+    public double getDouble(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? 0.0D : ((NBTNumber) this.map.get(s)).g();
-+        } catch (ClassCastException classcastexception) {
-+            return 0.0D;
-+        }
-+    }
-+
-+    public String getString(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? "" : ((NBTBase) this.map.get(s)).a_();
-+        } catch (ClassCastException classcastexception) {
-+            return "";
-+        }
-+    }
-+
-+    public byte[] getByteArray(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? new byte[0] : ((NBTTagByteArray) this.map.get(s)).c();
-+        } catch (ClassCastException classcastexception) {
-+            throw new ReportedException(this.a(s, 7, classcastexception));
-+        }
-+    }
-+
-+    public int[] getIntArray(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? new int[0] : ((NBTTagIntArray) this.map.get(s)).c();
-+        } catch (ClassCastException classcastexception) {
-+            throw new ReportedException(this.a(s, 11, classcastexception));
-+        }
-+    }
-+
-+    public NBTTagCompound getCompound(String s) {
-+        try {
-+            return !this.map.containsKey(s) ? new NBTTagCompound() : (NBTTagCompound) this.map.get(s);
-+        } catch (ClassCastException classcastexception) {
-+            throw new ReportedException(this.a(s, 10, classcastexception));
-+        }
-+    }
-+
-+    public NBTTagList getList(String s, int i) {
-+        try {
-+            if (this.b(s) != 9) {
-+                return new NBTTagList();
-+            } else {
-+                NBTTagList nbttaglist = (NBTTagList) this.map.get(s);
-+
-+                return nbttaglist.size() > 0 && nbttaglist.d() != i ? new NBTTagList() : nbttaglist;
-+            }
-+        } catch (ClassCastException classcastexception) {
-+            throw new ReportedException(this.a(s, 9, classcastexception));
-+        }
-+    }
-+
-+    public boolean getBoolean(String s) {
-+        return this.getByte(s) != 0;
-+    }
-+
-+    public void remove(String s) {
-+        this.map.remove(s);
-+    }
-+
-+    public String toString() {
-+        String s = "{";
-+
-+        String s1;
-+
-+        for (Iterator iterator = this.map.keySet().iterator(); iterator.hasNext(); s = s + s1 + ':' + this.map.get(s1) + ',') {
-+            s1 = (String) iterator.next();
-+        }
-+
-+        return s + "}";
-+    }
-+
-+    public boolean isEmpty() {
-+        return this.map.isEmpty();
-+    }
-+
-+    private CrashReport a(String s, int i, ClassCastException classcastexception) {
-+        CrashReport crashreport = CrashReport.a(classcastexception, "Reading NBT data");
-+        CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Corrupt NBT tag", 1);
-+
-+        crashreportsystemdetails.a("Tag type found", (Callable) (new CrashReportCorruptNBTTag(this, s)));
-+        crashreportsystemdetails.a("Tag type expected", (Callable) (new CrashReportCorruptNBTTag2(this, i)));
-+        crashreportsystemdetails.a("Tag name", s);
-+        return crashreport;
-+    }
-+
-+    public NBTBase clone() {
-+        NBTTagCompound nbttagcompound = new NBTTagCompound();
-+        Iterator iterator = this.map.keySet().iterator();
-+
-+        while (iterator.hasNext()) {
-+            String s = (String) iterator.next();
-+
-+            nbttagcompound.set(s, ((NBTBase) this.map.get(s)).clone());
-+        }
-+
-+        return nbttagcompound;
-+    }
-+
-+    public boolean equals(Object object) {
-+        if (super.equals(object)) {
-+            NBTTagCompound nbttagcompound = (NBTTagCompound) object;
-+
-+            return this.map.entrySet().equals(nbttagcompound.map.entrySet());
-+        } else {
-+            return false;
-+        }
-+    }
-+
-+    public int hashCode() {
-+        return super.hashCode() ^ this.map.hashCode();
-+    }
-+
-+    private static void a(String s, NBTBase nbtbase, DataOutput dataoutput) throws IOException
-+    {
-+        dataoutput.writeByte(nbtbase.getTypeId());
-+        if (nbtbase.getTypeId() != 0) {
-+            dataoutput.writeUTF(s);
-+            nbtbase.write(dataoutput);
-+        }
-+    }
-+
-+    private static byte a(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException
-+    {
-+        return datainput.readByte();
-+    }
-+
-+    private static String b(DataInput datainput, NBTReadLimiter nbtreadlimiter) throws IOException
-+    {
-+        return datainput.readUTF();
-+    }
-+
-+    static NBTBase a(byte b0, String s, DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) {
-+        NBTBase nbtbase = NBTBase.createTag(b0);
-+
-+        try {
-+            nbtbase.load(datainput, i, nbtreadlimiter);
-+            return nbtbase;
-+        } catch (IOException ioexception) {
-+            CrashReport crashreport = CrashReport.a(ioexception, "Loading NBT data");
-+            CrashReportSystemDetails crashreportsystemdetails = crashreport.a("NBT Tag");
-+
-+            crashreportsystemdetails.a("Tag name", s);
-+            crashreportsystemdetails.a("Tag type", Byte.valueOf(b0));
-+            throw new ReportedException(crashreport);
-+        }
-+    }
-+
-+    static Map a(NBTTagCompound nbttagcompound) {
-+        return nbttagcompound.map;
-+    }
-+}
 diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java
 new file mode 100644
 index 0000000..c7cea7f
@@ -3548,5 +3211,5 @@ index 0000000..c0db754
 +    }
 +}
 -- 
-1.8.5.2.msysgit.0
+1.9.1
 
diff --git a/CraftBukkit-Patches/0137-Log-null-TileEntity-Owner.patch b/CraftBukkit-Patches/0137-Log-null-TileEntity-Owner.patch
new file mode 100644
index 0000000000..f56fc8a417
--- /dev/null
+++ b/CraftBukkit-Patches/0137-Log-null-TileEntity-Owner.patch
@@ -0,0 +1,29 @@
+From 9cac662254b15d2ab59efa9e99a4a988be30e4f6 Mon Sep 17 00:00:00 2001
+From: md_5 <git@md-5.net>
+Date: Sun, 20 Apr 2014 11:16:54 +1000
+Subject: [PATCH] Log null TileEntity Owner
+
+
+diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
+index 78e17d7..19d008c 100644
+--- a/src/main/java/net/minecraft/server/TileEntity.java
++++ b/src/main/java/net/minecraft/server/TileEntity.java
+@@ -177,7 +177,14 @@ public class TileEntity {
+ 
+     // CraftBukkit start - add method
+     public InventoryHolder getOwner() {
+-        org.bukkit.block.BlockState state = world.getWorld().getBlockAt(x, y, z).getState();
++        // Spigot start
++        org.bukkit.block.Block block = world.getWorld().getBlockAt(x, y, z);
++        if (block == null) {
++            org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "No block for owner at %s %d %d %d", new Object[]{world.getWorld(), x, y, z});
++            return null;
++        }
++        // Spigot end
++        org.bukkit.block.BlockState state = block.getState();
+         if (state instanceof InventoryHolder) return (InventoryHolder) state;
+         return null;
+     }
+-- 
+1.9.1
+
diff --git a/CraftBukkit-Patches/0138-Don-t-special-case-invalid-usernames-for-UUIDs.patch b/CraftBukkit-Patches/0138-Don-t-special-case-invalid-usernames-for-UUIDs.patch
new file mode 100644
index 0000000000..c6ca430f85
--- /dev/null
+++ b/CraftBukkit-Patches/0138-Don-t-special-case-invalid-usernames-for-UUIDs.patch
@@ -0,0 +1,34 @@
+From d3c20f6bc5078698723d6f34d68bd3865c7e674c Mon Sep 17 00:00:00 2001
+From: md_5 <git@md-5.net>
+Date: Sun, 20 Apr 2014 18:58:00 +1000
+Subject: [PATCH] Don't special case 'invalid' usernames for UUIDs.
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+index 7c265b5..a996677 100644
+--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
++++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+@@ -231,8 +231,6 @@ public final class CraftServer implements Server {
+     private boolean printSaveWarning;
+     private CraftIconCache icon;
+     private boolean overrideAllCommandBlockCommands = false;
+-    private final Pattern validUserPattern = Pattern.compile("^[a-zA-Z0-9_]{2,16}$");
+-    private final UUID invalidUserUUID = UUID.nameUUIDFromBytes("InvalidUsername".getBytes(Charsets.UTF_8));
+ 
+     private final class BooleanWrapper {
+         private boolean value = true;
+@@ -1321,11 +1319,6 @@ public final class CraftServer implements Server {
+         Validate.notNull(name, "Name cannot be null");
+         com.google.common.base.Preconditions.checkArgument( !org.apache.commons.lang.StringUtils.isBlank( name ), "Name cannot be blank" ); // Spigot
+ 
+-        // If the name given cannot ever be a valid username give a dummy return, for scoreboard plugins
+-        if (!validUserPattern.matcher(name).matches()) {
+-            return new CraftOfflinePlayer(this, new GameProfile(invalidUserUUID, name));
+-        }
+-
+         OfflinePlayer result = getPlayerExact(name);
+         if (result == null) {
+             // This is potentially blocking :(
+-- 
+1.9.1
+
diff --git a/CraftBukkit-Patches/0139-Convert-player-skulls-async.patch b/CraftBukkit-Patches/0139-Convert-player-skulls-async.patch
new file mode 100644
index 0000000000..593c98ad81
--- /dev/null
+++ b/CraftBukkit-Patches/0139-Convert-player-skulls-async.patch
@@ -0,0 +1,96 @@
+From fa5e5bc9da02923761b86b69e08eeabdb3581d20 Mon Sep 17 00:00:00 2001
+From: Thinkofdeath <thethinkofdeath@gmail.com>
+Date: Sun, 20 Apr 2014 13:18:55 +0100
+Subject: [PATCH] Convert player skulls async
+
+
+diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java
+index 748f00a..a239f04 100644
+--- a/src/main/java/net/minecraft/server/TileEntitySkull.java
++++ b/src/main/java/net/minecraft/server/TileEntitySkull.java
+@@ -6,11 +6,25 @@ import net.minecraft.util.com.google.common.collect.Iterables;
+ import net.minecraft.util.com.mojang.authlib.GameProfile;
+ import net.minecraft.util.com.mojang.authlib.properties.Property;
+ 
++// Spigot start
++import java.util.concurrent.Executor;
++import java.util.concurrent.Executors;
++import com.google.common.util.concurrent.ThreadFactoryBuilder;
++import net.minecraft.util.com.mojang.authlib.Agent;
++// Spigot end
++
+ public class TileEntitySkull extends TileEntity {
+ 
+     private int a;
+     private int i;
+     private GameProfile j = null;
++    // Spigot start
++    private static final Executor executor = Executors.newFixedThreadPool(3,
++            new ThreadFactoryBuilder()
++                    .setNameFormat("Head Conversion Thread - %1$d")
++                    .build()
++    );
++    // Spigot end
+ 
+     public TileEntitySkull() {}
+ 
+@@ -65,18 +79,45 @@ public class TileEntitySkull extends TileEntity {
+     private void d() {
+         if (this.j != null && !UtilColor.b(this.j.getName())) {
+             if (!this.j.isComplete() || !this.j.getProperties().containsKey("textures")) {
+-                GameProfile gameprofile = MinecraftServer.getServer().getUserCache().a(this.j.getName());
+-
+-                if (gameprofile != null) {
+-                    Property property = (Property) Iterables.getFirst(gameprofile.getProperties().get("textures"), null);
+-
+-                    if (property == null) {
+-                        gameprofile = MinecraftServer.getServer().av().fillProfileProperties(gameprofile, true);
++                // Spigot start - Handle async
++                final String name = this.j.getName();
++                executor.execute(new Runnable() {
++                    @Override
++                    public void run() {
++                        GameProfile[] profiles = new GameProfile[1];
++                        GameProfileLookup gameProfileLookup = new GameProfileLookup(profiles);
++
++                        MinecraftServer.getServer().getGameProfileRepository().findProfilesByNames(new String[] { name }, Agent.MINECRAFT, gameProfileLookup);
++                        if (!MinecraftServer.getServer().getOnlineMode() && profiles[0] == null) {
++                            UUID uuid = EntityHuman.a(new GameProfile(null, name));
++                            GameProfile profile = new GameProfile(uuid, name);
++
++                            gameProfileLookup.onProfileLookupSucceeded(profile);
++                        }
++
++                        GameProfile profile = profiles[0];
++                        if (profile != null) {
++                            Property property = Iterables.getFirst(profile.getProperties().get("textures"), null);
++
++                            if (property == null) {
++                                profile = MinecraftServer.getServer().av().fillProfileProperties(profile, true);
++                            }
++
++                            final GameProfile finalProfile = profile;
++                            MinecraftServer.getServer().processQueue.add(new Runnable() {
++                                @Override
++                                public void run() {
++                                    j = finalProfile;
++                                    update();
++                                    MinecraftServer.getServer().getPlayerList().sendPacketNearby(x, y, z,
++                                            world.spigotConfig.viewDistance * 16,
++                                            world.worldData.j()/*Dimension*/, getUpdatePacket());
++                                }
++                            });
++                        }
+                     }
+-
+-                    this.j = gameprofile;
+-                    this.update();
+-                }
++                });
++                // Spigot end
+             }
+         }
+     }
+-- 
+1.9.1
+
diff --git a/CraftBukkit-Patches/0140-Prevent-NoClassDefError-crash-and-notify-on-crash.patch b/CraftBukkit-Patches/0140-Prevent-NoClassDefError-crash-and-notify-on-crash.patch
new file mode 100644
index 0000000000..a044e532e1
--- /dev/null
+++ b/CraftBukkit-Patches/0140-Prevent-NoClassDefError-crash-and-notify-on-crash.patch
@@ -0,0 +1,50 @@
+From 7298686551958fd4fe66772a694ead9a01d956c5 Mon Sep 17 00:00:00 2001
+From: David <dmck2b@gmail.com>
+Date: Mon, 21 Apr 2014 12:43:08 +0100
+Subject: [PATCH] Prevent NoClassDefError crash and notify on crash
+
+
+diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
+index 52ed625..ff65035 100644
+--- a/src/main/java/net/minecraft/server/World.java
++++ b/src/main/java/net/minecraft/server/World.java
+@@ -108,6 +108,8 @@ public abstract class World implements IBlockAccess {
+     protected float growthOdds = 100;
+     protected float modifiedOdds = 100;
+     private final byte chunkTickRadius;
++    public static boolean haveWeSilencedAPhysicsCrash;
++    public static String blockLocation;
+ 
+     public static long chunkToKey(int x, int z)
+     {
+@@ -531,6 +533,9 @@ public abstract class World implements IBlockAccess {
+                 // CraftBukkit end
+ 
+                 block1.doPhysics(this, i, j, k, block);
++            } catch (StackOverflowError stackoverflowerror) { // Spigot Start
++                haveWeSilencedAPhysicsCrash = true;
++                blockLocation = i + ", " + j + ", " + k; // Spigot End
+             } catch (Throwable throwable) {
+                 CrashReport crashreport = CrashReport.a(throwable, "Exception while updating neighbours");
+                 CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being updated");
+diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
+index de08ad6..94a3d42 100644
+--- a/src/main/java/org/spigotmc/WatchdogThread.java
++++ b/src/main/java/org/spigotmc/WatchdogThread.java
+@@ -60,6 +60,13 @@ public class WatchdogThread extends Thread
+                 log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" );
+                 log.log( Level.SEVERE, "Spigot version: " + Bukkit.getServer().getVersion() );
+                 //
++                if(net.minecraft.server.World.haveWeSilencedAPhysicsCrash)
++                {
++                    log.log( Level.SEVERE, "------------------------------" );
++                    log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" );
++                    log.log( Level.SEVERE, "near " + net.minecraft.server.World.blockLocation);
++                }
++                //
+                 log.log( Level.SEVERE, "------------------------------" );
+                 log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
+                 dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE ), log );
+-- 
+1.9.1
+
diff --git a/CraftBukkit-Patches/0141-Stop-anvils-from-destroying-all-items-in-the-second-.patch b/CraftBukkit-Patches/0141-Stop-anvils-from-destroying-all-items-in-the-second-.patch
new file mode 100644
index 0000000000..83a2815144
--- /dev/null
+++ b/CraftBukkit-Patches/0141-Stop-anvils-from-destroying-all-items-in-the-second-.patch
@@ -0,0 +1,23 @@
+From 7847557ebc8cf54f1f66fbe027ecf2e0ab9a4c74 Mon Sep 17 00:00:00 2001
+From: David <dmck2b@gmail.com>
+Date: Wed, 23 Apr 2014 01:01:47 +0100
+Subject: [PATCH] Stop anvils from destroying all items in the second slot
+
+While this may allow multiple stacked items to be repaired at once, it's better than eating all of a user's items.
+
+diff --git a/src/main/java/net/minecraft/server/ContainerAnvilInventory.java b/src/main/java/net/minecraft/server/ContainerAnvilInventory.java
+index 1afa6e7..d975b44 100644
+--- a/src/main/java/net/minecraft/server/ContainerAnvilInventory.java
++++ b/src/main/java/net/minecraft/server/ContainerAnvilInventory.java
+@@ -43,7 +43,7 @@ public class ContainerAnvilInventory extends InventorySubcontainer { // CraftBuk
+     ContainerAnvilInventory(ContainerAnvil containeranvil, String s, boolean flag, int i) {
+         super(s, flag, i);
+         this.a = containeranvil;
+-        this.setMaxStackSize(1); // CraftBukkit
++        // Spigot - Removed this.setMaxStackSize(1); // CraftBukkit
+     }
+ 
+     // CraftBukkit start - override inherited maxStack from InventorySubcontainer
+-- 
+1.9.1
+