diff --git a/Spigot-Server-Patches/0003-mc-dev-imports.patch b/Spigot-Server-Patches/0003-mc-dev-imports.patch
index 1490a9a44b..37303d8615 100644
--- a/Spigot-Server-Patches/0003-mc-dev-imports.patch
+++ b/Spigot-Server-Patches/0003-mc-dev-imports.patch
@@ -1,4 +1,4 @@
-From 064eacc5931529fab242e2faed8e34f57eb6933f Mon Sep 17 00:00:00 2001
+From b0a88bf483ac0df3413f5ff4337833bd750265f3 Mon Sep 17 00:00:00 2001
 From: Zach Brown <zach.brown@destroystokyo.com>
 Date: Mon, 29 Feb 2016 21:09:10 -0600
 Subject: [PATCH] mc-dev imports
@@ -3609,6 +3609,81 @@ index 0000000..2f4265a
 +        return this.b.getType(blockposition.down()).b();
 +    }
 +}
+diff --git a/src/main/java/net/minecraft/server/NavigationListener.java b/src/main/java/net/minecraft/server/NavigationListener.java
+new file mode 100644
+index 0000000..f82ea80
+--- /dev/null
++++ b/src/main/java/net/minecraft/server/NavigationListener.java
+@@ -0,0 +1,69 @@
++package net.minecraft.server;
++
++import java.util.WeakHashMap;
++
++public class NavigationListener implements IWorldAccess {
++
++    private static final Object a = new Object();
++    private final WeakHashMap<NavigationAbstract, Object> b = new WeakHashMap();
++
++    public NavigationListener() {}
++
++    public void a(NavigationAbstract navigationabstract) {
++        this.b.put(navigationabstract, NavigationListener.a);
++    }
++
++    public void a(World world, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) {
++        if (this.a(world, blockposition, iblockdata, iblockdata1)) {
++            NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.b.keySet().toArray(new NavigationAbstract[0]);
++            NavigationAbstract[] anavigationabstract1 = anavigationabstract;
++            int j = anavigationabstract.length;
++
++            for (int k = 0; k < j; ++k) {
++                NavigationAbstract navigationabstract = anavigationabstract1[k];
++
++                if (navigationabstract != null && !navigationabstract.i()) {
++                    PathEntity pathentity = navigationabstract.k();
++
++                    if (pathentity != null && !pathentity.b() && pathentity.d() != 0) {
++                        PathPoint pathpoint = navigationabstract.c.c();
++                        double d0 = blockposition.distanceSquared(((double) pathpoint.a + navigationabstract.a.locX) / 2.0D, ((double) pathpoint.b + navigationabstract.a.locY) / 2.0D, ((double) pathpoint.c + navigationabstract.a.locZ) / 2.0D);
++                        int l = (pathentity.d() - pathentity.e()) * (pathentity.d() - pathentity.e());
++
++                        if (d0 < (double) l) {
++                            navigationabstract.j();
++                        }
++                    }
++                }
++            }
++
++        }
++    }
++
++    protected boolean a(World world, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {
++        AxisAlignedBB axisalignedbb = iblockdata.d(world, blockposition);
++        AxisAlignedBB axisalignedbb1 = iblockdata1.d(world, blockposition);
++
++        return axisalignedbb != axisalignedbb1 && (axisalignedbb == null || !axisalignedbb.equals(axisalignedbb1));
++    }
++
++    public void a(BlockPosition blockposition) {}
++
++    public void a(int i, int j, int k, int l, int i1, int j1) {}
++
++    public void a(EntityHuman entityhuman, SoundEffect soundeffect, SoundCategory soundcategory, double d0, double d1, double d2, float f, float f1) {}
++
++    public void a(int i, boolean flag, double d0, double d1, double d2, double d3, double d4, double d5, int... aint) {}
++
++    public void a(Entity entity) {}
++
++    public void b(Entity entity) {}
++
++    public void a(SoundEffect soundeffect, BlockPosition blockposition) {}
++
++    public void a(int i, BlockPosition blockposition, int j) {}
++
++    public void a(EntityHuman entityhuman, int i, BlockPosition blockposition, int j) {}
++
++    public void b(int i, BlockPosition blockposition, int j) {}
++}
 diff --git a/src/main/java/net/minecraft/server/PathfinderGoalFloat.java b/src/main/java/net/minecraft/server/PathfinderGoalFloat.java
 new file mode 100644
 index 0000000..1a20dbf
diff --git a/Spigot-Server-Patches/0079-Optimize-NavigationListener-Iteration.patch b/Spigot-Server-Patches/0079-Optimize-NavigationListener-Iteration.patch
new file mode 100644
index 0000000000..0968baaff1
--- /dev/null
+++ b/Spigot-Server-Patches/0079-Optimize-NavigationListener-Iteration.patch
@@ -0,0 +1,100 @@
+From 9c96f51c8068de370baeb9fa4aee91c82d273e42 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Mon, 7 Mar 2016 22:43:26 -0500
+Subject: [PATCH] Optimize NavigationListener Iteration
+
+I don't know what the person who wrote that code was smoking, but I
+don't think it was good.
+
+Gets rid of the WeakHashMap that mojang was abusing purely to be lazy
+on clean up, and handles registering and deregistering navigation
+upon world add/remove operations.
+
+diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java
+index 7d794b9..ca4cb26 100644
+--- a/src/main/java/net/minecraft/server/NavigationAbstract.java
++++ b/src/main/java/net/minecraft/server/NavigationAbstract.java
+@@ -32,7 +32,7 @@ public abstract class NavigationAbstract {
+         this.b = world;
+         this.g = entityinsentient.getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
+         this.s = this.a();
+-        this.b.C().a(this);
++        //this.b.C().a(this); // Paper
+     }
+ 
+     protected abstract Pathfinder a();
+diff --git a/src/main/java/net/minecraft/server/NavigationListener.java b/src/main/java/net/minecraft/server/NavigationListener.java
+index f82ea80..ef446fc 100644
+--- a/src/main/java/net/minecraft/server/NavigationListener.java
++++ b/src/main/java/net/minecraft/server/NavigationListener.java
+@@ -1,26 +1,41 @@
+ package net.minecraft.server;
+ 
++import java.util.ArrayList; // Paper
++import java.util.List; // Paper
+ import java.util.WeakHashMap;
+ 
+ public class NavigationListener implements IWorldAccess {
+ 
+     private static final Object a = new Object();
+-    private final WeakHashMap<NavigationAbstract, Object> b = new WeakHashMap();
++    private final List<NavigationAbstract> navigators = new ArrayList<>(); // Paper
+ 
+     public NavigationListener() {}
+ 
++
+     public void a(NavigationAbstract navigationabstract) {
+-        this.b.put(navigationabstract, NavigationListener.a);
++        this.add(navigationabstract); // Paper
+     }
+ 
++    // Paper start
++    public void add(NavigationAbstract navigationabstract) {
++        this.navigators.add(navigationabstract);
++    }
++    public void remove(NavigationAbstract navigationabstract) {
++        this.navigators.remove(navigationabstract);
++    }
++    // Paper end
++
+     public void a(World world, BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1, int i) {
+         if (this.a(world, blockposition, iblockdata, iblockdata1)) {
+-            NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.b.keySet().toArray(new NavigationAbstract[0]);
+-            NavigationAbstract[] anavigationabstract1 = anavigationabstract;
+-            int j = anavigationabstract.length;
++            // Paper start
++            //NavigationAbstract[] anavigationabstract = (NavigationAbstract[]) this.navigators.keySet().toArray(new NavigationAbstract[0]);
++            //NavigationAbstract[] anavigationabstract1 = anavigationabstract;
++            int j = this.navigators.size();
++
+ 
+             for (int k = 0; k < j; ++k) {
+-                NavigationAbstract navigationabstract = anavigationabstract1[k];
++                NavigationAbstract navigationabstract = this.navigators.get(k);
++                // Paper end
+ 
+                 if (navigationabstract != null && !navigationabstract.i()) {
+                     PathEntity pathentity = navigationabstract.k();
+diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
+index cae2873..5ae2f14 100644
+--- a/src/main/java/net/minecraft/server/World.java
++++ b/src/main/java/net/minecraft/server/World.java
+@@ -1024,6 +1024,7 @@ public abstract class World implements IBlockAccess {
+             this.getChunkAt(i, j).a(entity);
+             this.entityList.add(entity);
+             this.b(entity);
++            if (entity instanceof EntityInsentient) { this.getNavListener().add(((EntityInsentient) entity).navigation); } // Paper
+             return true;
+         }
+     }
+@@ -1105,6 +1106,7 @@ public abstract class World implements IBlockAccess {
+         }
+         // CraftBukkit end
+         } // Spigot
++        if (entity instanceof EntityInsentient) { this.getNavListener().remove(((EntityInsentient) entity).navigation); } // Paper
+         this.c(entity);
+     }
+ 
+-- 
+2.7.2
+