diff --git a/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch b/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch
deleted file mode 100644
index 3d4e250c6..000000000
--- a/Spigot-Server-Patches/0031-Configurable-async-light-updates.patch
+++ /dev/null
@@ -1,242 +0,0 @@
-From 3139fa5792642d1ac35a315ca8a40acf0c057bf7 Mon Sep 17 00:00:00 2001
-From: Byteflux <byte@byteflux.net>
-Date: Wed, 2 Mar 2016 00:52:31 -0600
-Subject: [PATCH] Configurable async light updates
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index facb98c..9991a4a 100644
---- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-@@ -166,4 +166,9 @@ public class PaperWorldConfig {
- 
-     }
- 
-+    public boolean useAsyncLighting;
-+    private void useAsyncLighting() {
-+        useAsyncLighting = false; //getBoolean( "use-async-lighting", false );
-+        log("World async lighting: " + useAsyncLighting);
-+    }
- }
-diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index cde4124..5df38be 100644
---- a/src/main/java/net/minecraft/server/Chunk.java
-+++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -11,6 +11,8 @@ import java.util.Map;
- import java.util.Random;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ConcurrentLinkedQueue;
-+import java.util.concurrent.atomic.AtomicInteger; // Paper
-+
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- 
-@@ -44,6 +46,10 @@ public class Chunk {
-     private int w;
-     private ConcurrentLinkedQueue<BlockPosition> x;
-     protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
-+    // Paper start - Asynchronous light updates
-+    public AtomicInteger pendingLightUpdates = new AtomicInteger();
-+    public long lightUpdateTime;
-+    // Paper end
- 
-     // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
-     private int neighbors = 0x1 << 12;
-@@ -278,7 +284,7 @@ public class Chunk {
-     private void a(int i, int j, int k, int l) {
-         if (l > k && this.world.areChunksLoaded(new BlockPosition(i, 0, j), 16)) {
-             for (int i1 = k; i1 < l; ++i1) {
--                this.world.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
-+                this.world.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
-             }
- 
-             this.r = true;
-@@ -991,7 +997,7 @@ public class Chunk {
- 
-     public void b(boolean flag) {
-         if (this.l && !this.world.worldProvider.m() && !flag) {
--            this.h(this.world.isClientSide);
-+            this.recheckGaps(this.world.isClientSide); // Paper - Asynchronous lighting updates
-         }
- 
-         this.q = true;
-@@ -1012,6 +1018,23 @@ public class Chunk {
- 
-     }
- 
-+    /**
-+     * Paper- Recheck gaps asynchronously
-+     */
-+    public void recheckGaps(final boolean isClientSide) {
-+        if (!world.paperConfig.useAsyncLighting) {
-+            this.h(this.world.isClientSide);
-+            return;
-+        }
-+
-+        world.lightingExecutor.submit(new Runnable() {
-+            @Override
-+            public void run() {
-+                Chunk.this.h(isClientSide);
-+            }
-+        });
-+    }
-+
-     public boolean isReady() {
-         // Spigot Start
-         /*
-diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 83857a6..49288c9 100644
---- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
-+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-@@ -46,6 +46,12 @@ public class ChunkProviderServer implements IChunkProvider {
-     }
- 
-     public void queueUnload(int i, int j) {
-+        // Paper start - Asynchronous lighting updates
-+        Chunk chunk = chunks.get(LongHash.toLong(i, j));
-+        if (chunk != null && chunk.world.paperConfig.useAsyncLighting && (chunk.pendingLightUpdates.get() > 0 || chunk.world.getTime() - chunk.lightUpdateTime < 20)) {
-+            return;
-+        }
-+        // Paper end
-         if (this.world.worldProvider.c(i, j)) {
-             // CraftBukkit start
-             this.unloadQueue.add(i, j);
-diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index c5ce0c3..fae23ae 100644
---- a/src/main/java/net/minecraft/server/World.java
-+++ b/src/main/java/net/minecraft/server/World.java
-@@ -29,6 +29,12 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
- import org.bukkit.generator.ChunkGenerator;
- // CraftBukkit end
- 
-+// Paper start
-+import java.util.concurrent.ExecutorService;
-+import java.util.concurrent.Executors;
-+import com.google.common.util.concurrent.ThreadFactoryBuilder;
-+// Paper end
-+
- public abstract class World implements IBlockAccess {
- 
-     private int a = 63;
-@@ -134,6 +140,7 @@ public abstract class World implements IBlockAccess {
-     private org.spigotmc.TickLimiter entityLimiter;
-     private org.spigotmc.TickLimiter tileLimiter;
-     private int tileTickPosition;
-+    public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper - Lighting Thread").build()); // Paper - Asynchronous lighting updates
- 
-     public CraftWorld getWorld() {
-         return this.world;
-@@ -476,7 +483,7 @@ public abstract class World implements IBlockAccess {
- 
-         if (!this.worldProvider.m()) {
-             for (i1 = k; i1 <= l; ++i1) {
--                this.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
-+                this.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); // Paper - Asynchronous lighting updates
-             }
-         }
- 
-@@ -2245,10 +2252,10 @@ public abstract class World implements IBlockAccess {
-         boolean flag = false;
- 
-         if (!this.worldProvider.m()) {
--            flag |= this.c(EnumSkyBlock.SKY, blockposition);
-+            flag |= this.updateLight(EnumSkyBlock.SKY, blockposition); // Paper - Asynchronous lighting updates
-         }
- 
--        flag |= this.c(EnumSkyBlock.BLOCK, blockposition);
-+        flag |= this.updateLight(EnumSkyBlock.BLOCK, blockposition); // Paper - Asynchronous lighting updates
-         return flag;
-     }
- 
-@@ -2298,10 +2305,15 @@ public abstract class World implements IBlockAccess {
-         }
-     }
- 
-+    // Paper start - Asynchronous lighting updates
-     public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) {
-+        return this.c(enumskyblock, blockposition, null, null);
-+    }
-+
-+    public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition, Chunk chunk, List<Chunk> neighbors) { // Paper
-         // CraftBukkit start - Use neighbor cache instead of looking up
--        Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
--        if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) {
-+        //Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
-+        if (chunk == null /*|| !chunk.areNeighborsLoaded(1)*/ /*!this.areChunksLoaded(blockposition, 17, false)*/) {
-             // CraftBukkit end
-             return false;
-         } else {
-@@ -2372,6 +2384,17 @@ public abstract class World implements IBlockAccess {
-                 i = 0;
-             }
- 
-+            // Paper start - Asynchronous light updates
-+            if (chunk.world.paperConfig.useAsyncLighting) {
-+                chunk.pendingLightUpdates.decrementAndGet();
-+                if (neighbors != null) {
-+                    for (Chunk neighbor : neighbors) {
-+                        neighbor.pendingLightUpdates.decrementAndGet();
-+                    }
-+                }
-+            }
-+            // Paper end
-+
-             this.methodProfiler.b();
-             this.methodProfiler.a("checkedPosition < toCheckCount");
- 
-@@ -2426,6 +2449,52 @@ public abstract class World implements IBlockAccess {
-         }
-     }
- 
-+    /**
-+     * Paper - Asynchronous lighting updates
-+     */
-+    public boolean updateLight(final EnumSkyBlock enumskyblock, final BlockPosition position) {
-+        int x = position.getX();
-+        int z = position.getZ();
-+        final Chunk chunk = this.getChunkIfLoaded(x >> 4, z >> 4);
-+        if (chunk == null || !chunk.areNeighborsLoaded(1)) {
-+            return false;
-+        }
-+
-+        if (!chunk.world.paperConfig.useAsyncLighting) {
-+            return this.c(enumskyblock, position, chunk, null);
-+        }
-+
-+        chunk.pendingLightUpdates.incrementAndGet();
-+        chunk.lightUpdateTime = chunk.world.getTime();
-+
-+        final List<Chunk> neighbors = new ArrayList<Chunk>();
-+
-+        for (int cx = (x >> 4) - 1; cx <= (x >> 4) + 1; ++cx) {
-+            for (int cz = (z >> 4) - 1; cz <= (z >> 4) + 1; ++cz) {
-+                if (cx != x >> 4 && cz != z >> 4) {
-+                    Chunk neighbor = this.getChunkIfLoaded(cx, cz);
-+                    if (neighbor != null) {
-+                        neighbor.pendingLightUpdates.incrementAndGet();
-+                        neighbor.lightUpdateTime = chunk.world.getTime();
-+                        neighbors.add(neighbor);
-+                    }
-+                }
-+            }
-+        }
-+
-+        if (!Bukkit.isPrimaryThread()) {
-+            return this.c(enumskyblock, position, chunk, neighbors);
-+        }
-+
-+        lightingExecutor.submit(new Runnable() {
-+            @Override
-+            public void run() {
-+                World.this.c(enumskyblock, position, chunk, neighbors);
-+            }
-+        });
-+        return true;
-+    }
-+
-     public boolean a(boolean flag) {
-         return false;
-     }
--- 
-2.7.1.windows.2
-
diff --git a/Spigot-Server-Patches/0031-Lighting-Queue.patch b/Spigot-Server-Patches/0031-Lighting-Queue.patch
new file mode 100644
index 000000000..125642905
--- /dev/null
+++ b/Spigot-Server-Patches/0031-Lighting-Queue.patch
@@ -0,0 +1,233 @@
+From 73b3ea1a73387e5a5a24366959c1c35caf7387e9 Mon Sep 17 00:00:00 2001
+From: Byteflux <byte@byteflux.net>
+Date: Wed, 2 Mar 2016 00:52:31 -0600
+Subject: [PATCH] Lighting Queue
+
+
+diff --git a/src/main/java/co/aikar/timings/SpigotTimings.java b/src/main/java/co/aikar/timings/SpigotTimings.java
+index 3f4271c..5fdf051 100644
+--- a/src/main/java/co/aikar/timings/SpigotTimings.java
++++ b/src/main/java/co/aikar/timings/SpigotTimings.java
+@@ -17,6 +17,7 @@ public final class SpigotTimings {
+     public static final Timing timeUpdateTimer = Timings.ofSafe("Time Update");
+     public static final Timing serverCommandTimer = Timings.ofSafe("Server Command");
+     public static final Timing worldSaveTimer = Timings.ofSafe("World Save");
++    public static final Timing lightingQueueTimer = Timings.ofSafe("Lighting Queue");
+ 
+     public static final Timing tickEntityTimer = Timings.ofSafe("## tickEntity");
+     public static final Timing tickTileEntityTimer = Timings.ofSafe("## tickTileEntity");
+diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+index facb98c..e0e9a65 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+@@ -166,4 +166,9 @@ public class PaperWorldConfig {
+ 
+     }
+ 
++    public boolean queueLightUpdates;
++    private void queueLightUpdates() {
++        queueLightUpdates = getBoolean("queue-light-updates", false);
++        log("Lighting Queue enabled: " + queueLightUpdates);
++    }
+ }
+diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
+index cde4124..9020b1b 100644
+--- a/src/main/java/net/minecraft/server/Chunk.java
++++ b/src/main/java/net/minecraft/server/Chunk.java
+@@ -44,6 +44,7 @@ public class Chunk {
+     private int w;
+     private ConcurrentLinkedQueue<BlockPosition> x;
+     protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
++    public int lightUpdates; // Paper - Number of queued light updates for this chunk
+ 
+     // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
+     private int neighbors = 0x1 << 12;
+@@ -226,6 +227,22 @@ public class Chunk {
+     private void h(boolean flag) {
+         this.world.methodProfiler.a("recheckGaps");
+         if (this.world.areChunksLoaded(new BlockPosition(this.locX * 16 + 8, 0, this.locZ * 16 + 8), 16)) {
++            // Paper start - Queue light update
++            if (!world.paperConfig.queueLightUpdates) {
++                recheckGaps(flag);
++            } else {
++                ++lightUpdates;
++                world.getServer().getServer().lightingQueue.add(() -> {
++                    recheckGaps(flag);
++                    --lightUpdates;
++                });
++            }
++        }
++    }
++
++    private void recheckGaps(boolean flag) {
++        if (true) {
++            // Paper end
+             for (int i = 0; i < 16; ++i) {
+                 for (int j = 0; j < 16; ++j) {
+                     if (this.h[i + j * 16]) {
+@@ -476,7 +493,7 @@ public class Chunk {
+             } else {
+                 if (flag) {
+                     this.initLighting();
+-                } else {
++                } else if (!world.paperConfig.queueLightUpdates) { // Paper
+                     int j1 = iblockdata.c();
+                     int k1 = iblockdata1.c();
+ 
+@@ -491,6 +508,28 @@ public class Chunk {
+                     if (j1 != k1 && (j1 < k1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) {
+                         this.d(i, k);
+                     }
++                    // Paper start - Queue light update
++                } else {
++                    int j1 = iblockdata.c();
++                    int k1 = iblockdata1.c();
++
++                    ++lightUpdates;
++                    world.getServer().getServer().lightingQueue.add(() -> {
++                        if (j1 > 0) {
++                            if (j >= i1) {
++                                this.c(i, j + 1, k);
++                            }
++                        } else if (j == i1 - 1) {
++                            this.c(i, j, k);
++                        }
++
++                        if (j1 != k1 && (j1 < k1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) {
++                            this.d(i, k);
++                        }
++
++                        --lightUpdates;
++                    });
++                    // Paper end
+                 }
+ 
+                 TileEntity tileentity;
+@@ -1314,4 +1353,29 @@ public class Chunk {
+ 
+         private EnumTileEntityState() {}
+     }
++
++    // Paper start
++    public boolean hasLightUpdates() {
++        if (world.paperConfig.queueLightUpdates) {
++            if (lightUpdates > 0) {
++                return true;
++            }
++
++            for (int x = locX - 2; x <= locX + 2; ++x) {
++                for (int z = locZ - 2; z <= locZ + 2; ++z) {
++                    if ((x == 0 && z == 0) || (x == locX && z == locZ)) {
++                        continue;
++                    }
++
++                    Chunk chunk = world.getChunkIfLoaded(x, z);
++                    if (chunk != null && chunk.lightUpdates > 0) {
++                        return true;
++                    }
++                }
++            }
++        }
++
++        return false;
++    }
++    // Paper end
+ }
+diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
+index 83857a6..4dd672a 100644
+--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
+@@ -284,6 +284,7 @@ public class ChunkProviderServer implements IChunkProvider {
+                 long chunkcoordinates = this.unloadQueue.popFirst();
+                 Chunk chunk = this.chunks.get(chunkcoordinates);
+                 if (chunk == null) continue;
++                if (chunk.hasLightUpdates()) continue; // Paper - Don't unload chunks with pending light updates.
+ 
+                 ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk);
+                 server.getPluginManager().callEvent(event);
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index 6ae06a5..aa337cc 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -47,6 +47,11 @@ import org.bukkit.craftbukkit.CraftServer;
+ // CraftBukkit end
+ import co.aikar.timings.SpigotTimings; // Paper
+ 
++// Paper start
++import java.util.LinkedList;
++import java.util.Queue;
++// Paper end
++
+ public abstract class MinecraftServer implements Runnable, ICommandListener, IAsyncTaskHandler, IMojangStatistics {
+ 
+     public static final Logger LOGGER = LogManager.getLogger();
+@@ -113,6 +118,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
+     public final Thread primaryThread;
+     public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
+     public int autosavePeriod;
++    public final Queue<Runnable> lightingQueue = new LinkedList<Runnable>(); // Paper - Queued light updates
+     // CraftBukkit end
+ 
+     public MinecraftServer(OptionSet options, Proxy proxy, DataConverterManager dataconvertermanager, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache) {
+@@ -759,6 +765,35 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
+ 
+         this.methodProfiler.b();
+         this.methodProfiler.b();
++
++        // Paper start - Flush light updates
++        if (!lightingQueue.isEmpty()) {
++            SpigotTimings.lightingQueueTimer.startTiming();
++
++            int updatesThisTick = 0;
++            long cachedTime = System.currentTimeMillis();
++            long startTime = cachedTime - (this.h[this.ticks % 100] / 1000000);
++            int maxTickTimeCap = MathHelper.floor((TICK_TIME / 1000000) * 0.8);
++            int maxTickTime = Math.max(0, (int) (maxTickTimeCap - (cachedTime - startTime)));
++            Runnable lightUpdate;
++
++            while (maxTickTime > 0 && (lightUpdate = lightingQueue.poll()) != null) {
++                lightUpdate.run();
++                if (++updatesThisTick % 10 == 0) {
++                    long currentTime = System.currentTimeMillis();
++                    if (currentTime - cachedTime > maxTickTime) {
++                        break;
++                    }
++
++                    cachedTime = currentTime;
++                    maxTickTime = Math.max(0, (int) (maxTickTimeCap - (currentTime - startTime)));
++                }
++            }
++
++            SpigotTimings.lightingQueueTimer.stopTiming();
++        }
++        // Paper end
++
+         org.spigotmc.WatchdogThread.tick(); // Spigot
+         co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
+     }
+diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
+index c5ce0c3..a1d8bc5 100644
+--- a/src/main/java/net/minecraft/server/World.java
++++ b/src/main/java/net/minecraft/server/World.java
+@@ -378,7 +378,17 @@ public abstract class World implements IBlockAccess {
+             } else {
+                 if (iblockdata.c() != iblockdata1.c() || iblockdata.d() != iblockdata1.d()) {
+                     this.methodProfiler.a("checkLight");
+-                    this.w(blockposition);
++                    // Paper start - Queue light update
++                    if (!paperConfig.queueLightUpdates) {
++                        this.w(blockposition);
++                    } else {
++                        ++chunk.lightUpdates;
++                        getMinecraftServer().lightingQueue.add(() -> {
++                            this.w(blockposition);
++                            --chunk.lightUpdates;
++                        });
++                    }
++                    // Paper end
+                     this.methodProfiler.b();
+                 }
+ 
+-- 
+2.7.1.windows.2
+
diff --git a/Spigot-Server-Patches/0033-Configurable-end-credits.patch b/Spigot-Server-Patches/0033-Configurable-end-credits.patch
index eec179101..cdedb4bb9 100644
--- a/Spigot-Server-Patches/0033-Configurable-end-credits.patch
+++ b/Spigot-Server-Patches/0033-Configurable-end-credits.patch
@@ -1,16 +1,16 @@
-From cbfc14ef58ca1f52834aaeb230f7f034efd0bf45 Mon Sep 17 00:00:00 2001
+From a0fe380f5153cbc63cf9c9243bc64b2d1542bfa0 Mon Sep 17 00:00:00 2001
 From: DoctorDark <doctordark11@gmail.com>
 Date: Wed, 16 Mar 2016 02:21:39 -0500
 Subject: [PATCH] Configurable end credits
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 9991a4a..1b88731 100644
+index e0e9a65..3a57c8e 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -171,4 +171,10 @@ public class PaperWorldConfig {
-         useAsyncLighting = false; //getBoolean( "use-async-lighting", false );
-         log("World async lighting: " + useAsyncLighting);
+         queueLightUpdates = getBoolean("queue-light-updates", false);
+         log("Lighting Queue enabled: " + queueLightUpdates);
      }
 +
 +    public boolean disableEndCredits;
diff --git a/Spigot-Server-Patches/0036-Optimize-explosions.patch b/Spigot-Server-Patches/0036-Optimize-explosions.patch
index 385805c1e..951b72ecc 100644
--- a/Spigot-Server-Patches/0036-Optimize-explosions.patch
+++ b/Spigot-Server-Patches/0036-Optimize-explosions.patch
@@ -1,4 +1,4 @@
-From 40287dea24fbe1f8d97a10d6580beb13dc7037c7 Mon Sep 17 00:00:00 2001
+From abf2b31e23d05c3fb8ec5b85f739356b48047979 Mon Sep 17 00:00:00 2001
 From: Byteflux <byte@byteflux.net>
 Date: Wed, 2 Mar 2016 11:59:48 -0600
 Subject: [PATCH] Optimize explosions
@@ -10,7 +10,7 @@ This patch adds a per-tick cache that is used for storing and retrieving
 an entity's exposure during an explosion.
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 7154d31..2be15d2 100644
+index 66deccb..09b9867 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -201,4 +201,10 @@ public class PaperWorldConfig {
@@ -124,10 +124,10 @@ index 8ce1b23..5bb2510 100644
 +    // Paper end
  }
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 6ae06a5..92b98a0 100644
+index aa337cc..a30b019 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -865,6 +865,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
+@@ -900,6 +900,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
                  worldserver.timings.tracker.stopTiming(); // Spigot
                  this.methodProfiler.b();
                  this.methodProfiler.b();
@@ -136,22 +136,22 @@ index 6ae06a5..92b98a0 100644
  
              // this.i[i][this.ticks % 100] = System.nanoTime() - j; // CraftBukkit
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index fae23ae..b6d8e1b 100644
+index a1d8bc5..3fe987f 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -32,6 +32,7 @@ import org.bukkit.generator.ChunkGenerator;
- // Paper start
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-+import java.util.HashMap;
- import com.google.common.util.concurrent.ThreadFactoryBuilder;
- // Paper end
+@@ -15,6 +15,7 @@ import java.util.concurrent.Callable;
  
-@@ -141,6 +142,7 @@ public abstract class World implements IBlockAccess {
+ // CraftBukkit start
+ import com.google.common.collect.Maps;
++import java.util.HashMap; // Paper
+ import java.util.Map;
+ import org.bukkit.Bukkit;
+ import org.bukkit.block.BlockState;
+@@ -134,6 +135,7 @@ public abstract class World implements IBlockAccess {
+     private org.spigotmc.TickLimiter entityLimiter;
      private org.spigotmc.TickLimiter tileLimiter;
      private int tileTickPosition;
-     public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper - Lighting Thread").build()); // Paper - Asynchronous lighting updates
-+    public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<Explosion.CacheKey, Float>(); // Paper - Optimize explosions
++    public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
  
      public CraftWorld getWorld() {
          return this.world;
diff --git a/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch b/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch
index 895b4b1fd..9fa7914d7 100644
--- a/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch
+++ b/Spigot-Server-Patches/0051-Disable-spigot-tick-limiters.patch
@@ -1,14 +1,14 @@
-From 6afc533c9e295094848e44abbfa76c9283454215 Mon Sep 17 00:00:00 2001
+From cf6fcfa594a8512abf3b7821edcebe478fc13df0 Mon Sep 17 00:00:00 2001
 From: Zach Brown <zach.brown@destroystokyo.com>
 Date: Wed, 2 Mar 2016 23:45:17 -0600
 Subject: [PATCH] Disable spigot tick limiters
 
 
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index b6d8e1b..66293f7 100644
+index 3fe987f..c93af22 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -1412,10 +1412,10 @@ public abstract class World implements IBlockAccess {
+@@ -1415,10 +1415,10 @@ public abstract class World implements IBlockAccess {
          // CraftBukkit start - Use field for loop variable
          co.aikar.timings.TimingHistory.entityTicks += this.entityList.size(); // Paper
          int entitiesThisCycle = 0;
@@ -23,7 +23,7 @@ index b6d8e1b..66293f7 100644
              tickPosition = (tickPosition < entityList.size()) ? tickPosition : 0;
              entity = (Entity) this.entityList.get(this.tickPosition);
              // CraftBukkit end
-@@ -1480,9 +1480,7 @@ public abstract class World implements IBlockAccess {
+@@ -1483,9 +1483,7 @@ public abstract class World implements IBlockAccess {
          // Spigot start
          // Iterator iterator = this.tileEntityListTick.iterator();
          int tilesThisCycle = 0;
diff --git a/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch b/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch
index e7f27e968..76abad2cc 100644
--- a/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch
+++ b/Spigot-Server-Patches/0061-Add-Location-support-to-tab-completers-vanilla-featu.patch
@@ -1,4 +1,4 @@
-From 94e78ae772b6c0b96a39f28b088331772b5157d3 Mon Sep 17 00:00:00 2001
+From f5d0f96c004c8bbae8fc9a036da32ffd36db3dad Mon Sep 17 00:00:00 2001
 From: DemonWav <demonwav@gmail.com>
 Date: Thu, 3 Mar 2016 01:44:39 -0600
 Subject: [PATCH] Add Location support to tab completers (vanilla feature
@@ -6,7 +6,7 @@ Subject: [PATCH] Add Location support to tab completers (vanilla feature
 
 
 diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
-index 8ec65af..fd9aa5c 100644
+index 1f97e59..ca11cd7 100644
 --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
 @@ -262,4 +262,9 @@ public class PaperWorldConfig {
@@ -20,10 +20,10 @@ index 8ec65af..fd9aa5c 100644
 +    }
  }
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 92b98a0..4c0b0ba 100644
+index a30b019..6aaba5e 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java
 +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -1151,7 +1151,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
+@@ -1186,7 +1186,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
              return arraylist;
          }
          */
@@ -151,5 +151,5 @@ index 100d84a..a40218c 100644
  
      public static CommandSender lastSender = null; // Nasty :(
 -- 
-2.7.3
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0064-Optimize-getBlockData.patch b/Spigot-Server-Patches/0064-Optimize-getBlockData.patch
index 2799dd6fe..cbe3d6bd4 100644
--- a/Spigot-Server-Patches/0064-Optimize-getBlockData.patch
+++ b/Spigot-Server-Patches/0064-Optimize-getBlockData.patch
@@ -1,4 +1,4 @@
-From 1605c01b00947016970a88f124e76ee1a93fa1ae Mon Sep 17 00:00:00 2001
+From 913ffd56eaf018ef08a5581bdb34cf4e98d9327e Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Thu, 3 Mar 2016 02:07:55 -0600
 Subject: [PATCH] Optimize getBlockData
@@ -6,10 +6,10 @@ Subject: [PATCH] Optimize getBlockData
 Hot method, so reduce # of instructions for the method.
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 5df38be..19788ed 100644
+index 9020b1b..f233c13 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -392,8 +392,15 @@ public class Chunk {
+@@ -403,8 +403,15 @@ public class Chunk {
          return this.a(i, j, k).c();
      }
  
@@ -27,5 +27,5 @@ index 5df38be..19788ed 100644
  
      public IBlockData a(final int i, final int j, final int k) {
 -- 
-2.7.2
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch b/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch
index 2f3bb4423..693ed846e 100644
--- a/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch
+++ b/Spigot-Server-Patches/0065-Avoid-hopper-searches-if-there-are-no-items.patch
@@ -1,4 +1,4 @@
-From f10417f375c81cec510a68204309474063d79aff Mon Sep 17 00:00:00 2001
+From 2a296ac64bd3bd678edd258287d058ed28e9c186 Mon Sep 17 00:00:00 2001
 From: CullanP <cullanpage@gmail.com>
 Date: Thu, 3 Mar 2016 02:13:38 -0600
 Subject: [PATCH] Avoid hopper searches if there are no items
@@ -14,21 +14,24 @@ And since minecart hoppers are used _very_ rarely near we can avoid alot of sear
 Combined, this adds up a lot.
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 19788ed..6d148d7 100644
+index f233c13..d8c0347 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -49,6 +49,10 @@ public class Chunk {
-     // Paper start - Asynchronous light updates
-     public AtomicInteger pendingLightUpdates = new AtomicInteger();
-     public long lightUpdateTime;
+@@ -46,6 +46,13 @@ public class Chunk {
+     protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
+     public int lightUpdates; // Paper - Number of queued light updates for this chunk
+ 
++    // Paper start
 +    // Track the number of minecarts and items
 +    // Keep this synced with entitySlices.add() and entitySlices.remove()
 +    private final int[] itemCounts = new int[16];
 +    private final int[] inventoryEntityCounts = new int[16];
-     // Paper end
- 
++    // Paper end
++
      // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
-@@ -620,6 +624,13 @@ public class Chunk {
+     private int neighbors = 0x1 << 12;
+ 
+@@ -653,6 +660,13 @@ public class Chunk {
          entity.ac = k;
          entity.ad = this.locZ;
          this.entitySlices[k].add(entity);
@@ -42,7 +45,7 @@ index 19788ed..6d148d7 100644
          // Spigot start - increment creature type count
          // Keep this synced up with World.a(Class)
          if (entity instanceof EntityInsentient) {
-@@ -652,6 +663,13 @@ public class Chunk {
+@@ -685,6 +699,13 @@ public class Chunk {
          }
  
          this.entitySlices[i].remove(entity);
@@ -56,7 +59,7 @@ index 19788ed..6d148d7 100644
          // Spigot start - decrement creature type count
          // Keep this synced up with World.a(Class)
          if (entity instanceof EntityInsentient) {
-@@ -841,6 +859,15 @@ public class Chunk {
+@@ -874,6 +895,15 @@ public class Chunk {
              if (!this.entitySlices[k].isEmpty()) {
                  Iterator iterator = this.entitySlices[k].iterator();
  
@@ -72,7 +75,7 @@ index 19788ed..6d148d7 100644
                  while (iterator.hasNext()) {
                      Entity entity1 = (Entity) iterator.next();
  
-@@ -873,7 +900,18 @@ public class Chunk {
+@@ -906,7 +936,18 @@ public class Chunk {
          i = MathHelper.clamp(i, 0, this.entitySlices.length - 1);
          j = MathHelper.clamp(j, 0, this.entitySlices.length - 1);
  
@@ -92,5 +95,5 @@ index 19788ed..6d148d7 100644
  
              while (iterator.hasNext()) {
 -- 
-2.7.2
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch b/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch
index d99487adb..7173f4e44 100644
--- a/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch
+++ b/Spigot-Server-Patches/0071-Change-implementation-of-tile-entity-removal-list.patch
@@ -1,23 +1,26 @@
-From 84b6a774a12374f05c0d1d02f2ca5e07f0fe40f3 Mon Sep 17 00:00:00 2001
+From 5d2b01e642cb5ef8b70cdf786376be1610e2e2a2 Mon Sep 17 00:00:00 2001
 From: Joseph Hirschfeld <joe@ibj.io>
 Date: Thu, 3 Mar 2016 02:39:54 -0600
 Subject: [PATCH] Change implementation of (tile)entity removal list
 
 
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index 21b0986..2919415 100644
+index c93af22..6cfd38c 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -33,6 +33,8 @@ import org.bukkit.generator.ChunkGenerator;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.HashMap;
+@@ -30,6 +30,11 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+ import org.bukkit.generator.ChunkGenerator;
+ // CraftBukkit end
+ 
++// Paper start
 +import java.util.Set;
 +import com.google.common.collect.Sets;
- import com.google.common.util.concurrent.ThreadFactoryBuilder;
- // Paper end
++// Paper end
++
+ public abstract class World implements IBlockAccess {
  
-@@ -66,11 +68,11 @@ public abstract class World implements IBlockAccess {
+     private int a = 63;
+@@ -60,11 +65,11 @@ public abstract class World implements IBlockAccess {
          }
      };
      // Spigot end
@@ -31,7 +34,7 @@ index 21b0986..2919415 100644
      public final List<EntityHuman> players = Lists.newArrayList();
      public final List<Entity> j = Lists.newArrayList();
      protected final IntHashMap<Entity> entitiesById = new IntHashMap();
-@@ -1384,19 +1386,20 @@ public abstract class World implements IBlockAccess {
+@@ -1387,19 +1392,20 @@ public abstract class World implements IBlockAccess {
  
          int j;
  
@@ -61,5 +64,5 @@ index 21b0986..2919415 100644
          this.f.clear();
          this.l();
 -- 
-2.7.2
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch b/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch
index 88d1f635b..1e24f5eaf 100644
--- a/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch
+++ b/Spigot-Server-Patches/0075-Add-exception-reporting-event.patch
@@ -1,4 +1,4 @@
-From 74ef9d7784479d8a035466d41dcb1c86996fc120 Mon Sep 17 00:00:00 2001
+From fabc3a2adbde966e8248772fadf3f9930b2b1101 Mon Sep 17 00:00:00 2001
 From: Joseph Hirschfeld <joe@ibj.io>
 Date: Thu, 3 Mar 2016 03:15:41 -0600
 Subject: [PATCH] Add exception reporting event
@@ -50,7 +50,7 @@ index 0000000..9339718
 +}
 \ No newline at end of file
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 6d148d7..b6d84d7 100644
+index d8c0347..d42a8d2 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
 @@ -1,5 +1,6 @@
@@ -60,7 +60,7 @@ index 6d148d7..b6d84d7 100644
  import com.google.common.base.Predicate;
  import com.google.common.collect.Maps;
  import com.google.common.collect.Queues;
-@@ -18,6 +19,7 @@ import org.apache.logging.log4j.Logger;
+@@ -16,6 +17,7 @@ import org.apache.logging.log4j.Logger;
  
  import com.google.common.collect.Lists; // CraftBukkit
  import org.bukkit.Bukkit; // CraftBukkit
@@ -68,7 +68,7 @@ index 6d148d7..b6d84d7 100644
  
  public class Chunk {
  
-@@ -753,10 +755,15 @@ public class Chunk {
+@@ -789,10 +791,15 @@ public class Chunk {
              this.tileEntities.remove(blockposition);
              // Paper end
          } else {
@@ -89,7 +89,7 @@ index 6d148d7..b6d84d7 100644
          }
      }
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 49288c9..9ef6246 100644
+index 4dd672a..450bf9b 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 @@ -4,6 +4,7 @@ import java.io.IOException;
@@ -100,7 +100,7 @@ index 49288c9..9ef6246 100644
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
-@@ -226,7 +227,11 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -220,7 +221,11 @@ public class ChunkProviderServer implements IChunkProvider {
  
              return chunk;
          } catch (Exception exception) {
@@ -113,7 +113,7 @@ index 49288c9..9ef6246 100644
              return null;
          }
      }
-@@ -235,7 +240,11 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -229,7 +234,11 @@ public class ChunkProviderServer implements IChunkProvider {
          try {
              this.chunkLoader.b(this.world, chunk);
          } catch (Exception exception) {
@@ -126,7 +126,7 @@ index 49288c9..9ef6246 100644
          }
  
      }
-@@ -245,9 +254,14 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -239,9 +248,14 @@ public class ChunkProviderServer implements IChunkProvider {
              chunk.setLastSaved(this.world.getTime());
              this.chunkLoader.a(this.world, chunk);
          } catch (IOException ioexception) {
@@ -292,7 +292,7 @@ index 320e52e..d40257f 100644
              }
  
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index ee36486..6fb0230 100644
+index 6cfd38c..614cabe 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
 @@ -1,5 +1,7 @@
@@ -303,7 +303,7 @@ index ee36486..6fb0230 100644
  import com.google.common.base.Function;
  import com.google.common.base.Objects;
  import com.google.common.base.Predicate;
-@@ -1441,8 +1443,10 @@ public abstract class World implements IBlockAccess {
+@@ -1447,8 +1449,10 @@ public abstract class World implements IBlockAccess {
                  } catch (Throwable throwable1) {
                      entity.tickTimer.stopTiming();
                      // Paper start - Prevent tile entity and entity crashes
@@ -315,7 +315,7 @@ index ee36486..6fb0230 100644
                      entity.dead = true;
                      continue;
                      // Paper end
-@@ -1506,8 +1510,10 @@ public abstract class World implements IBlockAccess {
+@@ -1512,8 +1516,10 @@ public abstract class World implements IBlockAccess {
                          this.methodProfiler.b();
                      } catch (Throwable throwable2) {
                          // Paper start - Prevent tile entity and entity crashes
diff --git a/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch b/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch
index 8bdad61a7..81840c890 100644
--- a/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch
+++ b/Spigot-Server-Patches/0092-Add-World-Util-Methods.patch
@@ -1,4 +1,4 @@
-From 712fbf766b9e252fa208226bce6b7941327fefbe Mon Sep 17 00:00:00 2001
+From 5eafc0a2293770a3558d1e30c46f72f8a20d4e78 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Fri, 18 Mar 2016 20:16:03 -0400
 Subject: [PATCH] Add World Util Methods
@@ -6,10 +6,10 @@ Subject: [PATCH] Add World Util Methods
 Methods that can be used for other patches to help improve logic.
 
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index b356aa6..a6c8e53 100644
+index 614cabe..2283536 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess {
+@@ -152,6 +152,12 @@ public abstract class World implements IBlockAccess {
          return (CraftServer) Bukkit.getServer();
      }
  
@@ -22,7 +22,7 @@ index b356aa6..a6c8e53 100644
      public Chunk getChunkIfLoaded(int x, int z) {
          return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z);
      }
-@@ -628,6 +634,41 @@ public abstract class World implements IBlockAccess {
+@@ -634,6 +640,41 @@ public abstract class World implements IBlockAccess {
          }
      }
  
@@ -64,7 +64,7 @@ index b356aa6..a6c8e53 100644
      public int getLightLevel(BlockPosition blockposition) {
          return this.c(blockposition, true);
      }
-@@ -742,6 +783,27 @@ public abstract class World implements IBlockAccess {
+@@ -748,6 +789,27 @@ public abstract class World implements IBlockAccess {
          return this.worldProvider.n()[this.getLightLevel(blockposition)];
      }
  
@@ -93,5 +93,5 @@ index b356aa6..a6c8e53 100644
          // CraftBukkit start - tree generation
          if (captureTreeGeneration) {
 -- 
-2.7.4
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch b/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch
index f5b939d3b..b77c465ec 100644
--- a/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch
+++ b/Spigot-Server-Patches/0100-Optimize-Chunk-Unload-Queue.patch
@@ -1,4 +1,4 @@
-From db83f7f21876709f4d9a58499435fb7ecad82d0b Mon Sep 17 00:00:00 2001
+From f3a9dd01aab3b666d2b5e76346c58afef11ed3b1 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Fri, 18 Mar 2016 17:57:25 -0400
 Subject: [PATCH] Optimize Chunk Unload Queue
@@ -23,10 +23,10 @@ it will skip it and move to next.
 Also optimize EAR to use these methods.
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index b6d84d7..7ba45c8 100644
+index d42a8d2..05417a7 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -55,6 +55,8 @@ public class Chunk {
+@@ -53,6 +53,8 @@ public class Chunk {
      // Keep this synced with entitySlices.add() and entitySlices.remove()
      private final int[] itemCounts = new int[16];
      private final int[] inventoryEntityCounts = new int[16];
@@ -36,7 +36,7 @@ index b6d84d7..7ba45c8 100644
  
      // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index 9ef6246..f9375eb 100644
+index 450bf9b..f5a2580 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 @@ -21,7 +21,7 @@ import org.bukkit.event.world.ChunkUnloadEvent;
@@ -48,7 +48,7 @@ index 9ef6246..f9375eb 100644
      public final ChunkGenerator chunkGenerator; // CraftBukkit - public
      private final IChunkLoader chunkLoader;
      public LongObjectHashMap<Chunk> chunks = new LongObjectHashMap<Chunk>(); // CraftBukkit
-@@ -83,14 +83,24 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -77,14 +77,24 @@ public class ChunkProviderServer implements IChunkProvider {
          return (chunk == null) ? getChunkAt(x, z) : chunk;
      }
  
@@ -76,7 +76,7 @@ index 9ef6246..f9375eb 100644
          return chunk;
      }
  
-@@ -118,6 +128,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -112,6 +122,7 @@ public class ChunkProviderServer implements IChunkProvider {
              // CraftBukkit end
          }
  
@@ -84,7 +84,7 @@ index 9ef6246..f9375eb 100644
          return chunk;
      }
  
-@@ -126,7 +137,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -120,7 +131,7 @@ public class ChunkProviderServer implements IChunkProvider {
      }
  
      public Chunk getChunkAt(int i, int j, Runnable runnable) {
@@ -93,7 +93,7 @@ index 9ef6246..f9375eb 100644
          Chunk chunk = chunks.get(LongHash.toLong(i, j));
          ChunkRegionLoader loader = null;
  
-@@ -150,12 +161,13 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -144,12 +155,13 @@ public class ChunkProviderServer implements IChunkProvider {
          if (runnable != null) {
              runnable.run();
          }
@@ -108,7 +108,7 @@ index 9ef6246..f9375eb 100644
          Chunk chunk = this.chunks.get(LongHash.toLong(i, j));
          boolean newChunk = false;
          // CraftBukkit end
-@@ -201,7 +213,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -195,7 +207,7 @@ public class ChunkProviderServer implements IChunkProvider {
                          continue;
                      }
  
@@ -117,7 +117,7 @@ index 9ef6246..f9375eb 100644
                      if (neighbor != null) {
                          neighbor.setNeighborLoaded(-x, -z);
                          chunk.setNeighborLoaded(x, z);
-@@ -212,6 +224,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -206,6 +218,7 @@ public class ChunkProviderServer implements IChunkProvider {
              chunk.loadNearby(this, this.chunkGenerator);
              world.timings.syncChunkLoadTimer.stopTiming(); // Spigot
          }
@@ -125,7 +125,7 @@ index 9ef6246..f9375eb 100644
  
          return chunk;
      }
-@@ -300,10 +313,17 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -294,10 +307,17 @@ public class ChunkProviderServer implements IChunkProvider {
          if (!this.world.savingDisabled) {
              // CraftBukkit start
              Server server = this.world.getServer();
@@ -144,10 +144,10 @@ index 9ef6246..f9375eb 100644
 +                    continue;
 +                }
 +                // Paper end
+                 if (chunk.hasLightUpdates()) continue; // Paper - Don't unload chunks with pending light updates.
  
                  ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk);
-                 server.getPluginManager().callEvent(event);
-@@ -325,7 +345,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -320,7 +340,7 @@ public class ChunkProviderServer implements IChunkProvider {
                                  continue;
                              }
  
@@ -156,7 +156,7 @@ index 9ef6246..f9375eb 100644
                              if (neighbor != null) {
                                  neighbor.setNeighborUnloaded(-x, -z);
                                  chunk.setNeighborUnloaded(x, z);
-@@ -367,4 +387,69 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -362,4 +382,69 @@ public class ChunkProviderServer implements IChunkProvider {
      public boolean e(int i, int j) {
          return this.chunks.containsKey(LongHash.toLong(i, j)); // CraftBukkit
      }
@@ -240,10 +240,10 @@ index 63e118d..721bcae 100644
                  i += server.getChunkAt( x, z ).entityCount.get( oClass );
              }
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index f261e01..22c87eb 100644
+index 2283536..406bdaa 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -163,9 +163,15 @@ public abstract class World implements IBlockAccess {
+@@ -159,9 +159,15 @@ public abstract class World implements IBlockAccess {
      // Paper end
  
      public Chunk getChunkIfLoaded(int x, int z) {
diff --git a/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch b/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch
index a3a8da9ad..cc119efb0 100644
--- a/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch
+++ b/Spigot-Server-Patches/0105-Optimize-Chunk-Access.patch
@@ -1,4 +1,4 @@
-From 1f1ba7ebcc4d5a51914decb47c0537ff3a5ae1da Mon Sep 17 00:00:00 2001
+From 03ee6c4a13460987076f859841235e5460bc2661 Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Thu, 27 Aug 2015 01:15:02 -0400
 Subject: [PATCH] Optimize Chunk Access
@@ -9,10 +9,10 @@ getChunkAt is called for the same chunk multiple times in a row, often from getT
 Optimize this look up by using a Last Access cache.
 
 diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
-index 7ba45c8..fd65117 100644
+index 05417a7..c4b3461 100644
 --- a/src/main/java/net/minecraft/server/Chunk.java
 +++ b/src/main/java/net/minecraft/server/Chunk.java
-@@ -32,6 +32,7 @@ public class Chunk {
+@@ -30,6 +30,7 @@ public class Chunk {
      private boolean i;
      public final World world;
      public final int[] heightMap;
@@ -20,7 +20,7 @@ index 7ba45c8..fd65117 100644
      public final int locX;
      public final int locZ;
      private boolean l;
-@@ -99,6 +100,7 @@ public class Chunk {
+@@ -97,6 +98,7 @@ public class Chunk {
          this.world = world;
          this.locX = i;
          this.locZ = j;
@@ -29,7 +29,7 @@ index 7ba45c8..fd65117 100644
  
          for (int k = 0; k < this.entitySlices.length; ++k) {
 diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
-index f9375eb..90348d5 100644
+index f5a2580..f31ffe2 100644
 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
 +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
 @@ -24,7 +24,18 @@ public class ChunkProviderServer implements IChunkProvider {
@@ -52,7 +52,7 @@ index f9375eb..90348d5 100644
      // private final LongHashMap<Chunk> chunks = new LongHashMap();
      // private final List<Chunk> chunkList = Lists.newArrayList();
      public final WorldServer world;
-@@ -59,6 +70,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -53,6 +64,7 @@ public class ChunkProviderServer implements IChunkProvider {
  
              Chunk c = chunks.get(LongHash.toLong(i, j));
              if (c != null) {
@@ -60,7 +60,7 @@ index f9375eb..90348d5 100644
                  c.mustSave = true;
              }
              // CraftBukkit end
-@@ -333,6 +345,7 @@ public class ChunkProviderServer implements IChunkProvider {
+@@ -328,6 +340,7 @@ public class ChunkProviderServer implements IChunkProvider {
                          chunk.removeEntities();
                          this.saveChunk(chunk);
                          this.saveChunkNOP(chunk);
@@ -69,10 +69,10 @@ index f9375eb..90348d5 100644
                      }
  
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index d8bd36c..d21076b 100644
+index 406bdaa..0419eb4 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -160,6 +160,12 @@ public abstract class World implements IBlockAccess {
+@@ -156,6 +156,12 @@ public abstract class World implements IBlockAccess {
      public Chunk getChunkIfLoaded(BlockPosition blockposition) {
          return this.chunkProvider.getLoadedChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4);
      }
@@ -110,5 +110,5 @@ index caa5e62..c69e070 100644
          // Update neighbor counts
          for (int xx = -2; xx < 3; xx++) {
 -- 
-2.7.4.windows.1
+2.7.1.windows.2
 
diff --git a/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch b/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch
index 8e026f843..91941b580 100644
--- a/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch
+++ b/Spigot-Server-Patches/0107-Optimize-isValidLocation-for-inlining.patch
@@ -1,4 +1,4 @@
-From 64e71e5b3e3539cf102becf3e3c95c10c3856db6 Mon Sep 17 00:00:00 2001
+From 8eb1640efd765ee190b892daaf1be6c45ba1488f Mon Sep 17 00:00:00 2001
 From: Aikar <aikar@aikar.co>
 Date: Tue, 22 Mar 2016 23:41:34 -0400
 Subject: [PATCH] Optimize isValidLocation for inlining
@@ -22,10 +22,10 @@ index f0908a2..d1688e1 100644
  
      public BaseBlockPosition(int i, int j, int k) {
 diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
-index dcce296..edfb4cd 100644
+index 0419eb4..90b4367 100644
 --- a/src/main/java/net/minecraft/server/World.java
 +++ b/src/main/java/net/minecraft/server/World.java
-@@ -288,8 +288,8 @@ public abstract class World implements IBlockAccess {
+@@ -284,8 +284,8 @@ public abstract class World implements IBlockAccess {
          return this.getType(blockposition1);
      }
  
@@ -36,7 +36,7 @@ index dcce296..edfb4cd 100644
      }
  
      public boolean isEmpty(BlockPosition blockposition) {
-@@ -301,7 +301,7 @@ public abstract class World implements IBlockAccess {
+@@ -297,7 +297,7 @@ public abstract class World implements IBlockAccess {
      }
  
      public boolean a(BlockPosition blockposition, boolean flag) {
@@ -45,7 +45,7 @@ index dcce296..edfb4cd 100644
      }
  
      public boolean areChunksLoaded(BlockPosition blockposition, int i) {
-@@ -381,7 +381,7 @@ public abstract class World implements IBlockAccess {
+@@ -377,7 +377,7 @@ public abstract class World implements IBlockAccess {
              return true;
          }
          // CraftBukkit end
@@ -54,7 +54,7 @@ index dcce296..edfb4cd 100644
              return false;
          } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
              return false;
-@@ -649,7 +649,7 @@ public abstract class World implements IBlockAccess {
+@@ -655,7 +655,7 @@ public abstract class World implements IBlockAccess {
      // Paper start - test if meets light level, return faster
      // logic copied from below
      public boolean isLightLevel(BlockPosition blockposition, int level) {
@@ -63,7 +63,7 @@ index dcce296..edfb4cd 100644
              if (this.getType(blockposition).f()) {
                  if (this.c(blockposition.up(), false) >= level) {
                      return true;
-@@ -762,7 +762,7 @@ public abstract class World implements IBlockAccess {
+@@ -768,7 +768,7 @@ public abstract class World implements IBlockAccess {
              blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ());
          }
  
@@ -72,7 +72,7 @@ index dcce296..edfb4cd 100644
              return enumskyblock.c;
          } else if (!this.isLoaded(blockposition)) {
              return enumskyblock.c;
-@@ -774,7 +774,7 @@ public abstract class World implements IBlockAccess {
+@@ -780,7 +780,7 @@ public abstract class World implements IBlockAccess {
      }
  
      public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) {
@@ -81,7 +81,7 @@ index dcce296..edfb4cd 100644
              if (this.isLoaded(blockposition)) {
                  Chunk chunk = this.getChunkAtWorldCoords(blockposition);
  
-@@ -810,7 +810,7 @@ public abstract class World implements IBlockAccess {
+@@ -816,7 +816,7 @@ public abstract class World implements IBlockAccess {
          // CraftBukkit end
          Chunk chunk = this.getChunkIfLoaded(blockposition);
          if (chunk != null) {
@@ -90,7 +90,7 @@ index dcce296..edfb4cd 100644
          }
          return null;
      }
-@@ -828,7 +828,7 @@ public abstract class World implements IBlockAccess {
+@@ -834,7 +834,7 @@ public abstract class World implements IBlockAccess {
              }
          }
          // CraftBukkit end
@@ -99,7 +99,7 @@ index dcce296..edfb4cd 100644
              return Blocks.AIR.getBlockData();
          } else {
              Chunk chunk = this.getChunkAtWorldCoords(blockposition);
-@@ -2044,7 +2044,7 @@ public abstract class World implements IBlockAccess {
+@@ -2050,7 +2050,7 @@ public abstract class World implements IBlockAccess {
      public Map<BlockPosition, TileEntity> capturedTileEntities = Maps.newHashMap();
  
      public TileEntity getTileEntity(BlockPosition blockposition) {
@@ -108,7 +108,7 @@ index dcce296..edfb4cd 100644
              return null;
          } else {
              // CraftBukkit start
-@@ -2147,7 +2147,7 @@ public abstract class World implements IBlockAccess {
+@@ -2153,7 +2153,7 @@ public abstract class World implements IBlockAccess {
      }
  
      public boolean d(BlockPosition blockposition, boolean flag) {