diff --git a/Spigot-Server-Patches/0165-Move-setBlock-tile-tile-transition-workaround-into-T.patch b/Spigot-Server-Patches/0165-Move-setBlock-tile-tile-transition-workaround-into-T.patch
new file mode 100644
index 0000000000..8514f7e374
--- /dev/null
+++ b/Spigot-Server-Patches/0165-Move-setBlock-tile-tile-transition-workaround-into-T.patch
@@ -0,0 +1,147 @@
+From f957e361a8f39e1145bc6d53e21dc74c74a43577 Mon Sep 17 00:00:00 2001
+From: Zach Brown <zach.brown@destroystokyo.com>
+Date: Sat, 25 Jun 2016 23:55:56 -0500
+Subject: [PATCH] Move setBlock tile->tile transition workaround into TE
+ removal code and out of setblock
+
+Works around an issue in which running it in setBlock for all block changes could cause sign (and other?) data corruption.
+Also tells CB's TE fixer to ignore removals, as it would end up in a state in which it'd set the block, then
+call TE removal, which would get the TE to remove, then making CB's fixer run and get confused as to the current state of
+the block, but we don't care because that's the whole reason we're removing it.
+
+diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java
+index a5f2fc0..ef525ea 100644
+--- a/src/main/java/net/minecraft/server/BlockChest.java
++++ b/src/main/java/net/minecraft/server/BlockChest.java
+@@ -288,7 +288,7 @@ public class BlockChest extends BlockTileEntity {
+     }
+ 
+     public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+-        TileEntity tileentity = world.getTileEntity(blockposition);
++        TileEntity tileentity = world.getTileEntity(blockposition, true); // Paper - This is being removed, don't fix
+ 
+         if (tileentity instanceof IInventory) {
+             InventoryUtils.dropInventory(world, blockposition, (IInventory) tileentity);
+diff --git a/src/main/java/net/minecraft/server/BlockDispenser.java b/src/main/java/net/minecraft/server/BlockDispenser.java
+index 024ce36..c423663 100644
+--- a/src/main/java/net/minecraft/server/BlockDispenser.java
++++ b/src/main/java/net/minecraft/server/BlockDispenser.java
+@@ -144,7 +144,7 @@ public class BlockDispenser extends BlockTileEntity {
+     }
+ 
+     public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+-        TileEntity tileentity = world.getTileEntity(blockposition);
++        TileEntity tileentity = world.getTileEntity(blockposition, true); // Paper - This is being removed, don't fix
+ 
+         if (tileentity instanceof TileEntityDispenser) {
+             InventoryUtils.dropInventory(world, blockposition, (TileEntityDispenser) tileentity);
+diff --git a/src/main/java/net/minecraft/server/BlockFurnace.java b/src/main/java/net/minecraft/server/BlockFurnace.java
+index 25f7b4b..898be91 100644
+--- a/src/main/java/net/minecraft/server/BlockFurnace.java
++++ b/src/main/java/net/minecraft/server/BlockFurnace.java
+@@ -109,7 +109,7 @@ public class BlockFurnace extends BlockTileEntity {
+ 
+     public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+         if (!BlockFurnace.c) {
+-            TileEntity tileentity = world.getTileEntity(blockposition);
++            TileEntity tileentity = world.getTileEntity(blockposition, true); // Paper - This is being removed, don't fix
+ 
+             if (tileentity instanceof TileEntityFurnace) {
+                 InventoryUtils.dropInventory(world, blockposition, (TileEntityFurnace) tileentity);
+diff --git a/src/main/java/net/minecraft/server/BlockSkull.java b/src/main/java/net/minecraft/server/BlockSkull.java
+index 404793a..0d4d29b 100644
+--- a/src/main/java/net/minecraft/server/BlockSkull.java
++++ b/src/main/java/net/minecraft/server/BlockSkull.java
+@@ -122,7 +122,7 @@ public class BlockSkull extends BlockTileEntity {
+             // if (!((Boolean) iblockdata.get(BlockSkull.NODROP)).booleanValue()) {
+             if (false) {
+                 // CraftBukkit end
+-                TileEntity tileentity = world.getTileEntity(blockposition);
++                TileEntity tileentity = world.getTileEntity(blockposition, true); // Paper - This is being removed, don't fix
+ 
+                 if (tileentity instanceof TileEntitySkull) {
+                     TileEntitySkull tileentityskull = (TileEntitySkull) tileentity;
+diff --git a/src/main/java/net/minecraft/server/BlockTileEntity.java b/src/main/java/net/minecraft/server/BlockTileEntity.java
+index dfddafb..25c21b4 100644
+--- a/src/main/java/net/minecraft/server/BlockTileEntity.java
++++ b/src/main/java/net/minecraft/server/BlockTileEntity.java
+@@ -26,6 +26,7 @@ public abstract class BlockTileEntity extends Block implements ITileEntity {
+     public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+         super.remove(world, blockposition, iblockdata);
+         world.s(blockposition);
++        world.setTypeAndData(blockposition, Blocks.AIR.getBlockData(), 0); // Paper - SPIGOT-611 workaround moved from setBlock
+     }
+ 
+     public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, int i, int j) {
+diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
+index f7d9a7c..383eef2 100644
+--- a/src/main/java/net/minecraft/server/World.java
++++ b/src/main/java/net/minecraft/server/World.java
+@@ -2071,8 +2071,14 @@ public abstract class World implements IBlockAccess {
+     }
+ 
+     public Map<BlockPosition, TileEntity> capturedTileEntities = Maps.newHashMap();
++    // Paper start - Add additional param so we can ignore fixing on removals
+     @Nullable
+     public TileEntity getTileEntity(BlockPosition blockposition) {
++        return getTileEntity(blockposition, false);
++    }
++
++    public TileEntity getTileEntity(BlockPosition blockposition, boolean isRemoving) {
++        // Paper end
+         if (blockposition.isInvalidYLocation()) { // Paper
+             return null;
+         } else {
+@@ -2149,7 +2155,7 @@ public abstract class World implements IBlockAccess {
+     }
+ 
+     public void s(BlockPosition blockposition) {
+-        TileEntity tileentity = this.getTileEntity(blockposition);
++        TileEntity tileentity = this.getTileEntity(blockposition, true); // Paper - This is being removed, don't fix
+ 
+         if (tileentity != null && this.M) {
+             tileentity.y();
+diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
+index 3377f97..269ae39 100644
+--- a/src/main/java/net/minecraft/server/WorldServer.java
++++ b/src/main/java/net/minecraft/server/WorldServer.java
+@@ -123,8 +123,16 @@ public class WorldServer extends World implements IAsyncTaskHandler {
+ 
+     // CraftBukkit start
+     @Override
++    // Paper start - Add additional param so we can ignore fixing on removals
+     public TileEntity getTileEntity(BlockPosition pos) {
+-        TileEntity result = super.getTileEntity(pos);
++        return getTileEntity(pos, false);
++    }
++
++    @Override
++    public TileEntity getTileEntity(BlockPosition pos, boolean isRemoving) {
++        TileEntity result = super.getTileEntity(pos, isRemoving);
++        if (isRemoving) return result;
++        // Paper end
+         Block type = getType(pos).getBlock();
+ 
+         if (type == Blocks.CHEST || type == Blocks.TRAPPED_CHEST) { // Spigot
+diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+index ed7e76f..a31475a 100644
+--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
++++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+@@ -136,10 +136,14 @@ public class CraftBlock implements Block {
+         IBlockData blockData = getNMSBlock(type).fromLegacyData(data);
+         BlockPosition position = new BlockPosition(x, y, z);
+ 
++        // Paper start - Moved to TileEntity removal
++        /*
+         // SPIGOT-611: need to do this to prevent glitchiness. Easier to handle this here (like /setblock) than to fix weirdness in tile entity cleanup
+         if (type != 0) {
+             chunk.getHandle().getWorld().setTypeAndData(position, Blocks.AIR.getBlockData(), 0);
+         }
++        */
++        // Paper end
+ 
+         if (applyPhysics) {
+             return chunk.getHandle().getWorld().setTypeAndData(position, blockData, 3);
+-- 
+2.9.0.windows.1
+
diff --git a/scripts/importmcdev.sh b/scripts/importmcdev.sh
index 6e72cf4bc7..6420cf021d 100755
--- a/scripts/importmcdev.sh
+++ b/scripts/importmcdev.sh
@@ -44,6 +44,7 @@ import BlockFluids
 import BlockFurnace
 import BlockIceFrost
 import BlockPosition
+import BlockTileEntity
 import ChunkCache
 import ChunkProviderFlat
 import ChunkProviderGenerate