--- ../src-base/minecraft/net/minecraft/network/play/server/S26PacketMapChunkBulk.java
+++ ../src-work/minecraft/net/minecraft/network/play/server/S26PacketMapChunkBulk.java
@@ -24,10 +24,18 @@
     private byte[][] field_149260_f;
     private int field_149261_g;
     private boolean field_149267_h;
-    private static byte[] field_149268_i = new byte[0];
-    private static final String __OBFID = "CL_00001306";
-    private int maxLen = 0;
-    private Semaphore deflateGate;
+    private byte[] field_149268_i = new byte[0]; // CraftBukkit - remove static
+    // CraftBukkit start
+    static final ThreadLocal<Deflater> localDeflater = new ThreadLocal<Deflater>()
+    {
+        @Override
+        protected Deflater initialValue()
+        {
+            // Don't use higher compression level, slows things down too much
+            return new Deflater(6);
+        }
+    };
+    // CraftBukkit end
 
     public S26PacketMapChunkBulk() {}
 
@@ -46,6 +54,15 @@
         {
             Chunk chunk = (Chunk)p_i45197_1_.get(k);
             S21PacketChunkData.Extracted extracted = S21PacketChunkData.func_149269_a(chunk, true, 65535);
+
+            if (field_149268_i.length < j + extracted.field_150282_a.length)
+            {
+                byte[] abyte = new byte[j + extracted.field_150282_a.length];
+                System.arraycopy(field_149268_i, 0, abyte, 0, field_149268_i.length);
+                field_149268_i = abyte;
+            }
+
+            System.arraycopy(extracted.field_150282_a, 0, field_149268_i, j, extracted.field_150282_a.length);
             j += extracted.field_150282_a.length;
             this.field_149266_a[k] = chunk.xPosition;
             this.field_149264_b[k] = chunk.zPosition;
@@ -53,34 +70,36 @@
             this.field_149262_d[k] = extracted.field_150281_c;
             this.field_149260_f[k] = extracted.field_150282_a;
         }
-        this.deflateGate = new Semaphore(1);
-        maxLen = j;
-    }
-
-    private void deflate()
-    {
-        byte[] data = new byte[maxLen];
-        int offset = 0;
-        for (int x = 0; x < field_149260_f.length; x++)
-        {
-            System.arraycopy(field_149260_f[x], 0, data, offset, field_149260_f[x].length);
-            offset += field_149260_f[x].length;
-        }
+        /* CraftBukkit start - Moved to compress()
         Deflater deflater = new Deflater(-1);
 
-        try
-        {
-            deflater.setInput(data, 0, data.length);
+        try {
+            deflater.setInput(buildBuffer, 0, j);
             deflater.finish();
-            byte[] deflated = new byte[data.length];
-            this.field_149261_g = deflater.deflate(deflated);
-            this.field_149263_e = deflated;
+            this.buffer = new byte[j];
+            this.size = deflater.deflate(this.buffer);
+        } finally {
+            deflater.end();
         }
-        finally
+        */
+    }
+
+    // Add compression method
+    public void compress()
+    {
+        if (this.field_149263_e != null)
         {
-            deflater.end();
+            return;
         }
+
+        Deflater deflater = localDeflater.get();
+        deflater.reset();
+        deflater.setInput(this.field_149268_i);
+        deflater.finish();
+        this.field_149263_e = new byte[this.field_149268_i.length + 100];
+        this.field_149261_g = deflater.deflate(this.field_149263_e);
     }
+    // CraftBukkit end
 
     public static int func_149258_c()
     {
@@ -155,16 +174,7 @@
 
     public void writePacketData(PacketBuffer p_148840_1_) throws IOException
     {
-        if (this.field_149263_e == null)
-        {
-            deflateGate.acquireUninterruptibly();
-            if (this.field_149263_e == null)
-            {
-                deflate();
-            }
-            deflateGate.release();
-        }
-
+        compress(); // CraftBukkit
         p_148840_1_.writeShort(this.field_149266_a.length);
         p_148840_1_.writeInt(this.field_149261_g);
         p_148840_1_.writeBoolean(this.field_149267_h);