diff --git a/CraftBukkit-Patches/0020-Better-more-flexible-itemstack-merging.patch b/CraftBukkit-Patches/0020-Better-more-flexible-itemstack-merging.patch
new file mode 100644
index 0000000000..6921670391
--- /dev/null
+++ b/CraftBukkit-Patches/0020-Better-more-flexible-itemstack-merging.patch
@@ -0,0 +1,88 @@
+From e0396f9b7cbcb5f22183d97bd5d2e3858f27ce52 Mon Sep 17 00:00:00 2001
+From: md_5 <md_5@live.com.au>
+Date: Mon, 21 Jan 2013 14:31:25 +1100
+Subject: [PATCH] Better + more flexible itemstack merging
+
+---
+ src/main/java/net/minecraft/server/EntityItem.java | 13 ++++++-----
+ src/main/java/net/minecraft/server/World.java      | 26 ++--------------------
+ 2 files changed, 9 insertions(+), 30 deletions(-)
+
+diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
+index a7baa0f..5e3ac84 100644
+--- a/src/main/java/net/minecraft/server/EntityItem.java
++++ b/src/main/java/net/minecraft/server/EntityItem.java
+@@ -114,7 +114,8 @@ public class EntityItem extends Entity {
+     }
+ 
+     private void g() {
+-        Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(0.5D, 0.0D, 0.5D)).iterator();
++        double radius = world.getWorld().itemMergeRadius;
++        Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(radius, radius, radius)).iterator();
+ 
+         while (iterator.hasNext()) {
+             EntityItem entityitem = (EntityItem) iterator.next();
+@@ -143,11 +144,11 @@ public class EntityItem extends Entity {
+             } else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
+                 return false;
+             } else {
+-                itemstack1.count += itemstack.count;
+-                entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
+-                entityitem.age = Math.min(entityitem.age, this.age);
+-                entityitem.setItemStack(itemstack1);
+-                this.die();
++                itemstack.count += itemstack1.count;
++                this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
++                this.age = Math.min(entityitem.age, this.age);
++                this.setItemStack(itemstack);
++                entityitem.die();
+                 return true;
+             }
+         } else {
+diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
+index 3c6adb6..88b7f7a 100644
+--- a/src/main/java/net/minecraft/server/World.java
++++ b/src/main/java/net/minecraft/server/World.java
+@@ -927,30 +927,7 @@ public abstract class World implements IBlockAccess {
+         } else if (entity instanceof EntityItem) {
+             event = CraftEventFactory.callItemSpawnEvent((EntityItem) entity);
+             // Spigot start
+-            ItemStack item = ((EntityItem) entity).getItemStack();
+-            org.bukkit.craftbukkit.inventory.CraftItemStack craft = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item);
+-            int maxSize = item.getMaxStackSize();
+-            if (item.count < maxSize) {
+-                double radius = this.getWorld().itemMergeRadius;
+-                if (radius > 0) {
+-                    List<Entity> entities = this.getEntities(entity, entity.boundingBox.grow(radius, radius, radius));
+-                    for (Entity e : entities) {
+-                        if (e instanceof EntityItem) {
+-                            EntityItem loopItem = (EntityItem) e;
+-                            ItemStack loopStack = loopItem.getItemStack();
+-                            if (!loopItem.dead && craft.isSimilar(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(loopStack))) {
+-                                int toAdd = Math.min(loopStack.count, maxSize - item.count);
+-                                item.count += toAdd;
+-                                loopStack.count -= toAdd;
+-                                if (loopStack.count <= 0) {
+-                                    loopItem.die();
+-                                }
+-                            }
+-                        }
+-                    }
+-                }
+-            }
+-        } else if (entity instanceof EntityExperienceOrb) {
++            if (entity instanceof EntityExperienceOrb) {
+             EntityExperienceOrb xp = (EntityExperienceOrb) entity;
+             double radius = this.getWorld().expMergeRadius;
+             if (radius > 0) {
+@@ -965,6 +942,7 @@ public abstract class World implements IBlockAccess {
+                     }
+                 }
+             }
++            }
+             // Spigot end
+         } else if (entity.getBukkitEntity() instanceof org.bukkit.entity.Projectile) {
+             // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead
+-- 
+1.8.1-rc2
+